Hibernate01-基础


Hibernate01-基础

1.Hibernate入门程序

  1. 引入依赖。

    
        org.hibernate
        hibernate-core
    

    
        mysql
        mysql-connector-java
    

    
        org.slf4j
        slf4j-api
    

    
        junit
        junit
    

    
        org.hibernate
        hibernate-c3p0
        5.6.4.Final
    

  1. hibernate.cfg.xml配置文件。
<?xml version="1.0" encoding="UTF-8"?>



    

        
        
        com.mysql.cj.jdbc.Driver
        jdbc:mysql://127.0.0.1:3306/ke?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=true&allowMultiQueries=true
        root
        123456

        
        
        org.hibernate.dialect.MySQL8Dialect
        
        true
        
        true

        update

        
        10
        20
        
        2
        
        2000
        
        2000
        
        10

        
        
        100
        30

        
        
    

  1. 实体类和数据库表映射的配置文件。
<?xml version="1.0" encoding="UTF-8"?>


    
    
        
        
            
            
        

        
        

        
    

  1. 实体类。
@Data
public class User {

    private int id;
    private String name;
    private int age;
}
  1. 插入数据的Hello World。
public class Test01 {

    private Session session;
    private Transaction transaction;
    private SessionFactory sessionFactory;

    @Test
    public void testHelloWorld() {
        User user = new User();
        user.setName("tom");
        user.setAge(10);

        session.save(user);
    }

    @Before
    public void before() {
        // 1 加载Hibernate的核心配置文件
        Configuration configuration = new Configuration().configure();

        // 2 创建SessionFactory对象,类似于JDBC中的连接池
        sessionFactory = configuration.buildSessionFactory();

        // 3 通过SessionFactory获取到Session对象,类似于JDBC中的Connection
        session = sessionFactory.openSession();

        // 4 开启事务
        transaction = session.beginTransaction();
    }

    @After
    public void after() {
        // 5 关闭事务
        transaction.commit();

        // 6 释放资源
        session.close();
        sessionFactory.close();
    }
}

2.hibernate核心配置文件hibernate.cfg.xml

  1. hibernate.hbm2ddl.auto配置。

update

3.实体类和数据库表映射文件Xxx.hbm.xml

  1. 配置包名。


4.hibernate核心类

  1. Configuration的作用是启动hibernate程序,加载hibernate.cfg.xml配置文件,通常情况下Configuration对象只有一个实例,即Configuration是单例的。

  2. SessionFactory接口的作用加载连接数据库,扩展参数,映射信息,通过这些映

    射信息创建Session对象,通常情况下SessionFactory也是单例的。

  3. Session接口提供CRUD方法来操作对象,从而操作数据库。Session是线程不安全的对象,在项目中可以创建多个Session对象,每个线程就创建一个Session对象。

  4. Transaction接口用于执行事务操作 。

  5. Query接口用于执行HQL查询。

  6. Criteria接口用于执行基于对象的查询(QBC查询)。

5.Session核心方法

  1. save(Object obj) ,保存对象。
  2. update(Object obj),更新对象。
  3. saveOrUpdate(Object obj),添加或修改对象。
  4. delete(Object obj),删除对象。
  5. get(Class clz,Serialize id),获取对象。
  6. load(Class clz,Serialize id),获取对象。和get获取对象的区别,load()延时加载,在对象使用时才从数据库查询数据。

6.hibernate主键策略

  1. identity,利用数据库的自增长,如Mysql的auto_increment。
  2. sequence,利用数据库序列生成的能力,例如Oracle的sequence。
  3. native,本地策略,由hibernate自动根据不同的数据选择最优策略。如Mysql选择identity;Oracle选择sequence。
  4. uuid,生成32位16进制的字符串,id需要是String类型。
  5. increment,生成数据库表递进的数值类型。会查询当前表中最大的id,select max(id) from tb_student,会有并发问题。
  6. assigned,由开发者在插入时填充主键。

7.对象关系映射-一对多

  1. 实例类。如果实体类使用@Data注解,会有循环加载的问题。
@Getter
@Setter
@ToString
public class Customer {

    private int id;
    private String name;

    @ToString.Exclude
    private Set orders = new HashSet<>();
}

@Getter
@Setter
@ToString
public class Order {

    private int id;
    private String orderName;

    @ToString.Exclude
    private Customer customer;
}
  1. Xxx.hbm.xml映射文件。

    
        
            
        

        

        
            
            
        
    



    
        
            
        

        

        
    

  1. insert插入操作。
@Test
public void testManyToOneInsert() {
    Customer customer = new Customer();
    customer.setName("alice");

    Order order01 = new Order();
    order01.setOrderName("A002");

    Order order02 = new Order();
    order02.setOrderName("A002");

    order01.setCustomer(customer);
    order02.setCustomer(customer);

    session.save(customer);
    session.save(order01);
    session.save(order02);
}
  1. select查询操作。
@Test
public void testManyToOneGet() {
    Customer customer = session.get(Customer.class, 1);
    System.out.println(customer);

    // 延时加载,使用时进行数据库的查询。
    System.out.println(customer.getOrders());
}
  1. delete删除操作。

    1. 没有在Customer.hbm.xml中配置cascade="delete"。
    @Test
    public void testManyToOneDelete() {
        Customer customer = session.get(Customer.class, 7);
    
        // 1 没有在Customer.hbm.xml中配置cascade="delete",不会进行级联删除,
        // 删除有映射关系的数据,会进行两步操作。
        // 1) 将tb_order对应的customer_id设置为null。
        // 2) 删除tb_customer中对应的customer_id数据,不会删除tb_order对应的数据。
        session.delete(customer);
    }
    
    1. 在Customer.hbm.xml中配置cascade="delete"。
    @Test
    public void testManyToOneDelete() {
        Customer customer = session.get(Customer.class, 7);
    
        // 2 在Customer.hbm.xml的Set中配置cascade="delete"。
        // 1) 先查询到tb_custom关联的tb_order数据。
        // 2) 将tb_order的customer_id设置为null。
        // 3) 将tb_order对应的customer_id这条数据删除。
        // 4) 将删除tb_customer中的数据。
        session.delete(customer);
    }
    
    1. 在Customer.hbm.xml中配置cascade="delete" inverse="true"。
    @Test
    public void testManyToOneDelete() {
        Customer customer = session.get(Customer.class, 7);
    
        // 3 在Customer.hbm.xml的Set中配置cascade="delete" inverse="true",Customer放弃
        // 维护关系。
        // 1) 先查询到tb_custom关联的tb_order数据。
        // 2) 将tb_order对应的customer_id这条数据删除。
        // 3) 将删除tb_customer中的数据。
        session.delete(customer);
    }
    

8.cascade和inverse配置详解

  1. cascade,级联操作。级联保存,save-update;级联删除,delete;级联保存与删除:,all。
  2. inverse, 是否把关联关系的维护权反转。默认inverse=false。如果设置inverse=true,即当前方放弃关联关系的维护。通常在一对多的关联配置中,多方无法放弃关系维护权,建议放弃1方的维护权,在1方加上inverse=true配置。

9.对象关系映射-多对多

  1. 实体类。
@Getter
@Setter
@ToString
public class Person {

    private int id;
    private String name;

    private Set roles = new HashSet<>();
}

@Getter
@Setter
@ToString
public class Role {

    private int id;
    private String name;

    // 多对多映射在一方,排除toString()方法,防止循环查询。
    @ToString.Exclude
    private Set persons = new HashSet<>();
}
  1. xml配置文件。

    
        
            
        

        

        
        
            
            
            
            
        
    



    
        
            
        

        

        
        
            
            
            
            
        
    

  1. insert操作。
/**
     * 如果tb_person和tb_role都维护关联关系,就会在tb_person_role中添加重复的记录,两种解决方法。
     * 1) 代码中进行一方关系的维护,即只有一方使用Set.add()维护关系。
     * 2) 在tb_role中使用inverse="true",放弃关联关系的维护。
*/
@Test
public void manyToManySave() {
    Person p1 = new Person();
    p1.setName("tom");

    Person p2 = new Person();
    p2.setName("alice");

    Role role1 = new Role();
    role1.setName("超级管理员");

    Role role2 = new Role();
    role2.setName("管理员");

    // Person和Role都维护关联关系。
    p1.getRoles().add(role1);
    p1.getRoles().add(role2);
    p2.getRoles().add(role1);

    // 代码中Role放弃关联关系的维护。
    //role1.getPersons().add(p1);
    //role1.getPersons().add(p2);
    //role2.getPersons().add(p1);

    session.save(p1);
    session.save(p2);
    session.save(role1);
    session.save(role2);
}
  1. select操作。
@Test
public void manyToManySelect() {
    Person person = session.get(Person.class, 1);

    System.out.println(person.getRoles());
}
  1. delete操作。
@Test
public void manyToManyDelete() {
    Person person = new Person();
    person.setId(1);

    // tb_person中配置cascade="all",级联删除,会进行两步操作。
    // 1) 删除中间表tb_person_role的记录。
    // 2) 删除tb_person中的数据,不会删除tb_role中的数据。
    session.delete(person);
}

10.对象关系映射-一对一

  1. 一对一的两种实现方式。

    1. 外键关联映射,给外键添加唯一约束,用于一对一的映射,会有一个单独的列最为外键进行唯一映射。
    2. 主键关联映射。使用id列映射另一个表的id列。
  2. 外键关联映射。

    1. 实体类。
    @Getter
    @Setter
    @ToString
    public class Student {
    
        private int id;
        private String name;
    
        private Card card;
    }
    
    @Getter
    @Setter
    public class Card {
    
        private int id;
        private String cardNo;
    
        @ToString.Exclude
        private Student student;
    }
    
    1. xml映射关系。
    
        
            
                
            
    
            
    
            
        
    
    
    
        
            
                
            
    
            
    
            
            
        
    操作。
    
    1. insert操作。
    @Test
    public void oneToOneSave() {
        Student student = new Student();
        student.setName("alice");
    
        Card card = new Card();
        card.setCardNo("0002");
    
        card.setStudent(student);
    
        session.save(student);
        session.save(card);
    }
    
  3. 主键关联映射,只需要修改Card的xml配置文件。