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解决所有读问题



 

 

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/asndxj/p/12055072.html