zoukankan      html  css  js  c++  java
  • hibernate_02_hibernate的入门

    1.什么是Hibernate框架?

    Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping,在Java对象与关系数据库之间建立某种映射,以实现直接存取Java对象

    2.ORM概述

    在介绍Hibernate的时候,说了Hibernate是一种ORM的框架。那什么是ORM呢?ORM是一种思想

    • O代表的是Objcet
    • R代表的是Relative
    • M代表的是Mapping

    ORM->对象关系映射....ORM关注是对象与数据库中的列的关系

    3.编写对象和对象映射

    customer对象

    @Data
    public class Customer {
        private Long cust_id;
        private String cust_name;
        private String cust_source;
        private String cust_industry;
        private String cust_level;
        private String cust_phone;
        private String cust_mobile;
    }

     customrt对象映射文件Customer.hbm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    
        <!--设置主键-->
        <class name="com.work.entity.Customer" table="cst_customer">
            <id name="cust_id" type="java.lang.Long">
                <column name="cust_id" length="20"></column>
                <generator class="native"></generator>
            </id>
            <!-- 建立类中的普通-的属性和表的字段的对应 -->
            <property name="cust_name" type="java.lang.String">
                <column name="cust_name" length="32"></column>
            </property>
    
            <property name="cust_source" type="java.lang.String">
                <column name="cust_source" length="32"></column>
            </property>
    
            <property name="cust_industry" type="java.lang.String">
                <column name="cust_industry" length="255"></column>
            </property>
    
            <property name="cust_level" type="java.lang.String">
                <column name="cust_level" length="255"></column>
            </property>
    
            <property name="cust_phone" type="java.lang.String">
                <column name="cust_phone" length="255"></column>
            </property>
    
            <property name="cust_mobile" type="java.lang.String">
                <column name="cust_mobile" length="255"></column>
            </property>
        </class>
    </hibernate-mapping>

    4. 主键的生成策略

    1.increment :hibernate提供自动增长机制,适用于short、int、long类型的主键。在单线程中使用他会发送一条sql语句 select max(id) from 然后id+1为下一个主键的值
    2.identity :适用于short、int、long类型的主键。适用于mysql
    3.sequence :适用于short、int、long类型的主键。适用于orcal
    4.uuid :适用于字符串主键。使用hibernate中的随机方式生成字符串主键
    5.native :本地策略 自动切换identity和sequence
    6.assigned :hibernate放弃外键的管理,程序员需要自己手动编写主键
    7.foreign : 外部的一对一关联映射
    hibernate的配置文件hibernate.cfg.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <!-- 连接数据库的基本参数 -->
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql:///ssh?serverTimeZone=UTC</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password">12345</property>
            <!-- 配置Hibernate的方言 可以使用mysql语句-->
            <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
            
            <!-- 可选配置================ -->
            <!-- 打印SQL -->
            <property name="hibernate.show_sql">true</property>
            <!-- 格式化SQL -->
            <property name="hibernate.format_sql">true</property>
            <!-- 自动创建表 -->
            <property name="hibernate.hbm2ddl.auto">update</property>
            <!--设置事务的隔离级别-->
            <property name="hibernate.connection.isolation">4</property>
            <!--配置当前线程绑定的session-->
            <property name="hibernate.current_session_context_class">thread</property>
    
            <mapping resource="com/work/entity/Customer.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>

    5.使用hibernateUtils完成CURD

    public class HibernateTest2 {
    
        @Test
        public void save() {
            Session session = HibernateUtils.openSession();
            Transaction transaction = session.beginTransaction();
    
            Customer customer = new Customer();
            customer.setCust_name("hdh");
            //返回保存记录的id
            Serializable id = session.save(customer);
            System.out.println(id);
    
            transaction.commit();
            session.close();
        }
    
        @Test
        /**
         * get和load的区别
         * load事延迟加载在使用的是时候才会发送sql语句 ;查询一个找不到的对象时抛异常
         * get是立即加载;查询一个找不到的对象时返回null
         */
        public void select() {
    
            Session session = HibernateUtils.openSession();
            //get方法查询
            Customer customer = session.get(Customer.class, 1L);
            System.out.println(customer);
    
            //load方法查询
            Customer load = session.load(customer.getClass(), 1L);
            // System.out.println(load);
    
            session.close();
        }
    
        @Test
        public void update() {
    
            Session session = HibernateUtils.openSession();
            Transaction transaction = session.beginTransaction();
    
            //创建对象在修改
            Customer customer = new Customer();
            customer.setCust_id(1L);
            customer.setCust_name("xj");
            session.update(customer);
    
            //查询后在修改
            Customer customer1 = session.get(Customer.class, 2L);
            customer1.setCust_name("xj");
            session.update(customer1);
    
            transaction.commit();
            session.close();
        }
    
        @Test
        public void delete() {
    
            Session session = HibernateUtils.openSession();
            Transaction transaction = session.beginTransaction();
    
            //创建对象在修改
            Customer customer = new Customer();
            customer.setCust_id(3L);
            session.delete(customer);
    
            //查询后在修改(可以级联删除 使用这个)
            Customer customer1 = session.get(Customer.class, 4L);
            session.delete(customer1);
            transaction.commit();
            session.close();
        }
    
        @Test
        public void saveOrupdate() {
            Session session = HibernateUtils.openSession();
            Transaction transaction = session.beginTransaction();
            //saveorupdate 保存或更新操作 取决于是否有主键(id)
    
            Customer customer = session.get(Customer.class, 1L);
            customer.setCust_level("vip");
            session.saveOrUpdate(customer);
    
            transaction.commit();
            session.close();
        }
     
    }
    hibernateUtils.java
    **
     * Hibernate的工具类
     *
     */
    public class HibernateUtils {
    
        //configuation:配置对象 加载核心配置 加载映射文件
        public static final Configuration cfg;
        //sessionFactory:内部维护连接池和二级缓存,线程安全的
        public static final SessionFactory sf;
        
        static{
            cfg = new Configuration().configure();
            sf = cfg.buildSessionFactory();
        }
        //session内部维护了一级缓存,是连接对象    线程不安全的
        public static Session openSession(){
            return sf.openSession();
        }
    
        public static Session getCurrentSession(){
            return sf.getCurrentSession();
        }
    }

    6.hibernate的持久化的三种状态之间的切换

    瞬时状态对象:没有唯一标识的id,没有被session管理
    持久化状态对象:有唯一标识的id,被session管理
    游离状态对象:有唯一标识的id,没有被session管理 
    public class HibernateTest3 {
        @Test
        public void demo1() {
            
    
            Session session = HibernateUtils.openSession();
            Transaction transaction = session.beginTransaction();
    
            Customer customer = new Customer(); //瞬时状态对象:没有唯一标识的id,没有被session管理
            customer.setCust_name("hdh"); //持久化状态对象:有唯一标识的id,被session管理
            //返回保存记录的id
            Serializable id = session.save(customer);
            System.out.println(id);
            transaction.commit();
            session.close();
    
            System.out.println(customer.getCust_id()); //游离状态对象:有唯一标识的id,没有被session管理
        }
    
        /**
         * 三种状态之间的转换
         * 瞬时状态
         *      获得瞬时状态:Customer customer =new Costomer()
         *      状态转换:瞬时->持久
         *                save(Object obj ) saveOrUpdate(Object obj)
         *                瞬时->游离
         *                customer.setCust_id(1L)
         *
         * 持久化状态
         *      获得持久化状态:get() load() find() iterate()
         *                      session.get(Customer.class,1L)
         *      状态转换:持久->瞬时
         *                delete()
         *                持久->游离
         *                sesssion.close(),clear(),evict(Object obj)
         *
         * 游离化状态
         *      获得持久化状态:Customer customer = new Customer();
         *      状态转换:游离->瞬时
         *                customer.setCust_id(null)
         *                游离->持久
         *                update() saveOrUpdate()
         */
    
    }

    7.hibernatenate的一级缓存和一级缓存的快照

    hibernate持久化状态的数据会自动持久化到数据库

    1、通过session查询出的customer对象为持久态对象,同时该持久态对象会放到session一级缓存和快照区(副本)中
    2、当修改了customer也即持久态对象中属性的值,一级缓存中的内容也会随着修改,但一级缓存对应的快照区内容不会修改,
    3、最后提交事务时,比较它们的内容,如果不相同,把一级缓存内容更新到数据库,如果相同,不会更新到数据库。

    hibernate的一级缓存:称为Session级别的缓存,一级缓存的生命周期与Session一致,且一级缓存是hibernate自带的不可卸载的
    /**
     * hibernate的一级缓存:称为Session级别的缓存,一级缓存的生命周期与Session一致,且一级缓存是hibernate自带的不可卸载的
     *
     */
    public class HibernateTest4 {
    
        @Test
        public void test() {
    
            Session session = HibernateUtils.openSession();
            Transaction transaction = session.beginTransaction();
    
            //只会发送一次查询语句
            Customer customer1 = session.get(Customer.class, 1L);
            System.out.println(customer1);
            Customer customer2 = session.get(Customer.class, 1L);
            System.out.println(customer2);
    
            transaction.commit();
            session.close();
        }
    
        @Test
        /**
         * 持久化状态的数据会自动更新
         * 利用了一级缓存的快照区
         * 当事务提交的时候,hibernate会比较缓存区和快照区如果不一致会更新缓存,发送update语句
         */
        public void test1() {
    
            Session session = HibernateUtils.openSession();
            Transaction transaction = session.beginTransaction();
    
            Customer customer1 = session.get(Customer.class, 1L);
            customer1.setCust_name("lq");
    
            transaction.commit();
            session.close();
        }
    
    }

    8.hibernate主配置文件中指定session与当前线程绑定

    **
     * 测试当前线程绑定的Session,需要在配置文件种开启CurrentSession
     * <!--配置当前线程绑定的session-->
     * <property name="hibernate.current_session_context_class">thread</property>
     */
    public class HibernateTest5 {
    
        @Test
        public void test() {
            Session session = HibernateUtils.getCurrentSession();
            Transaction transaction = session.beginTransaction();
    
            Customer customer = new Customer();
            customer.setCust_id(1L);
            customer.setCust_name("lq");
            session.save(customer);
            //不需要关闭session
            transaction.commit();
    
        }
    
    
    }

    9.事务

      原子性(Atomicity)操作这些指令时,要么全部执行成功,要么全部不执行。只要其中一个指令执行失败,所有的指令都执行失败,数据进行回滚,回到执行指令前的数据状态。

      一致性(Consistency)事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。

      隔离性(Isolation)隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

      持久性(Durability)当事务正确完成后,它对于数据的改变是永久性的。

    如果不考虑隔离性,引发安全性问题

    读问题:

    脏读一个事务读到另一个事务未提交的数据,不可重复读一个事务读到另一个事务已经提交的 update数据,导致在一个事务多次查询结果不一致。

    虚读一个事务读到另一个事务已经提交的 insert数据,导致在前一个事务多次查询结果不一致,·

    不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异,不可被信任。

    设置事务的隔离级别:

    1>Read uncommitted:以上读问题都会发生

    2>Read committed:解决脏读,但是不可重复读和虚读有可能发生

    3>Repeatable read解决脏读和不可重复读,但是虛读有可能发生

    4>Serializable解决所有读问题



     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    读《31天学会CRM项目开发》记录4
    乡愁
    C#
    C#
    Redhat 离线安装 Docker (Community from binaries)
    使用FRP做内网穿透
    Windows上的Linux容器
    通过Powershell修改文件默认打开方式
    Office2019 VOL版本 自定义安装组件
    使用 Docker 生成 Let’s Encrypt 证书
  • 原文地址:https://www.cnblogs.com/asndxj/p/12055072.html
Copyright © 2011-2022 走看看