Hibernate01-基础
Hibernate01-基础
1.Hibernate入门程序
- 引入依赖。
org.hibernate
hibernate-core
mysql
mysql-connector-java
org.slf4j
slf4j-api
junit
junit
org.hibernate
hibernate-c3p0
5.6.4.Final
- 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
- 实体类和数据库表映射的配置文件。
<?xml version="1.0" encoding="UTF-8"?>
- 实体类。
@Data
public class User {
private int id;
private String name;
private int age;
}
- 插入数据的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
- hibernate.hbm2ddl.auto配置。
update
3.实体类和数据库表映射文件Xxx.hbm.xml
- 配置包名。
4.hibernate核心类
-
Configuration的作用是启动hibernate程序,加载hibernate.cfg.xml配置文件,通常情况下Configuration对象只有一个实例,即Configuration是单例的。
-
SessionFactory接口的作用加载连接数据库,扩展参数,映射信息,通过这些映
射信息创建Session对象,通常情况下SessionFactory也是单例的。
-
Session接口提供CRUD方法来操作对象,从而操作数据库。Session是线程不安全的对象,在项目中可以创建多个Session对象,每个线程就创建一个Session对象。
-
Transaction接口用于执行事务操作 。
-
Query接口用于执行HQL查询。
-
Criteria接口用于执行基于对象的查询(QBC查询)。
5.Session核心方法
- save(Object obj) ,保存对象。
- update(Object obj),更新对象。
- saveOrUpdate(Object obj),添加或修改对象。
- delete(Object obj),删除对象。
- get(Class clz,Serialize id),获取对象。
- load(Class clz,Serialize id),获取对象。和get获取对象的区别,load()延时加载,在对象使用时才从数据库查询数据。
6.hibernate主键策略
- identity,利用数据库的自增长,如Mysql的auto_increment。
- sequence,利用数据库序列生成的能力,例如Oracle的sequence。
- native,本地策略,由hibernate自动根据不同的数据选择最优策略。如Mysql选择identity;Oracle选择sequence。
- uuid,生成32位16进制的字符串,id需要是String类型。
- increment,生成数据库表递进的数值类型。会查询当前表中最大的id,select max(id) from tb_student,会有并发问题。
- assigned,由开发者在插入时填充主键。
7.对象关系映射-一对多
- 实例类。如果实体类使用@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;
}
- Xxx.hbm.xml映射文件。
- 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);
}
- select查询操作。
@Test
public void testManyToOneGet() {
Customer customer = session.get(Customer.class, 1);
System.out.println(customer);
// 延时加载,使用时进行数据库的查询。
System.out.println(customer.getOrders());
}
-
delete删除操作。
- 没有在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); }- 在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); }- 在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配置详解
- cascade,级联操作。级联保存,save-update;级联删除,delete;级联保存与删除:,all。
- inverse, 是否把关联关系的维护权反转。默认inverse=false。如果设置inverse=true,即当前方放弃关联关系的维护。通常在一对多的关联配置中,多方无法放弃关系维护权,建议放弃1方的维护权,在1方加上inverse=true配置。
9.对象关系映射-多对多
- 实体类。
@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<>();
}
- xml配置文件。
- 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);
}
- select操作。
@Test
public void manyToManySelect() {
Person person = session.get(Person.class, 1);
System.out.println(person.getRoles());
}
- 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.对象关系映射-一对一
-
一对一的两种实现方式。
- 外键关联映射,给外键添加唯一约束,用于一对一的映射,会有一个单独的列最为外键进行唯一映射。
- 主键关联映射。使用id列映射另一个表的id列。
-
外键关联映射。
- 实体类。
@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; }- xml映射关系。
操作。- 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); } -
主键关联映射,只需要修改Card的xml配置文件。