Hibernate
加入maven依赖
| |
| <dependency> |
| <groupId>javassist</groupId> |
| <artifactId>javassist</artifactId> |
| <version>3.12.0.GA</version> |
| </dependency> |
| <dependency> |
| <groupId>org.hibernate</groupId> |
| <artifactId>hibernate-core</artifactId> |
| <version>3.6.7.Final</version> |
| </dependency> |
| 使用javassist是因为 |
安装IDEA插件
JPA Buddy

配置数据库
创建文件 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/xsd/hibernate-configuration-3.0.dtd"> |
| |
| <hibernate-configuration> |
| <session-factory> |
| <property name="connection.driver_class">com.mysql.jdbc.Driver</property> |
| <property name="connection.url">jdbc:mysql:///db1?serverTimezone=GMT%2B8&useUnico</property> |
| <property name="connection.username">root</property> |
| <property name="connection.password">password</property> |
| </session-factory> |
| </hibernate-configuration> |
配置方言等其他配置
| |
| <property name="dialect">org.hibernate.dialect.MySQLDialect</property> |
| |
| <property name="show_sql">true</property> |
| |
| <property name="format_sql">true</property> |
| |
| <property name="hibernate.hbm2ddl.auto">update</property> |
配置一个实体类的CRUD
创建实体类A
| @Data |
| public class A implements Serializable { |
| private Integer id; |
| private String value; |
| |
| |
| |
| public Integer getId() { |
| return id; |
| } |
| |
| public void setId(Integer id) { |
| this.id = id; |
| } |
| |
| public String getValue() { |
| return value; |
| } |
| |
| public void setValue(String value) { |
| this.value = value; |
| } |
| } |
| |
同级包下,配置mapping
SensorData.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.jmu.design.domain.SensorData" table="sensor_data"> |
| <id name="id"> |
| <generator class="native"/> |
| </id> |
| <property name="type" column="type"/> |
| <property name="updateTime" column="update_time"/> |
| <property name="value" column="value"/> |
| </class> |
| </hibernate-mapping> |
在hibernate配置文件中添加映射关系
| |
| <mapping resource="com/jmu/design/domain/SensorData.hbm.xml"/> |

编写测试代码
| @Test |
| public void init(){ |
| |
| Configuration configuration = new Configuration().configure("hibernate.cfg.xml"); |
| |
| SessionFactory sessionFactory = configuration.buildSessionFactory(); |
| |
| |
| Session session = sessionFactory.openSession(); |
| |
| |
| Transaction transaction = session.beginTransaction(); |
| SensorData sensorData = new SensorData(); |
| sensorData.setType("type1"); |
| sensorData.setValue(123); |
| session.save(sensorData); |
| session.close(); |
| } |
然后出现未找到配置文件,maven中配置将配置文件自动构建打包

| <build> |
| <resources> |
| <resource> |
| <directory>src/main/resources</directory> |
| </resource> |
| <resource> |
| <directory>src/main/java</directory> |
| <includes> |
| <include>**/*.xml</include> |
| </includes> |
| <filtering>false</filtering> |
| </resource> |
| </resources> |
| </build> |
然后还需要添加一个依赖,否则3.x版本会出现异常
| <dependency> |
| <groupId>javassist</groupId> |
| <artifactId>javassist</artifactId> |
| <version>3.12.0.GA</version> |
| </dependency> |
CRUD测试
| @Test |
| public void init(){ |
| |
| Configuration configuration = new Configuration().configure("hibernate.cfg.xml"); |
| |
| SessionFactory sessionFactory = configuration.buildSessionFactory(); |
| |
| |
| Session session = sessionFactory.openSession(); |
| |
| |
| Transaction transaction = session.beginTransaction(); |
| |
| A a = new A(); |
| a.setValue("123"); |
| session.save(a); |
| |
| |
| session.delete(a); |
| |
| |
| List from_a = session.createQuery("from A").list(); |
| for (Object o : from_a) { |
| System.out.println(o); |
| } |
| |
| |
| A a1 = (A) session.get(A.class, 2); |
| System.out.println(a1.toString()); |
| a1.setValue(String.valueOf(111111)); |
| session.update(a1); |
| transaction.commit(); |
| session.close(); |
| } |
Get和load的区别
get请求是立即加载的过程,先查询缓存,缓存没有查询数据库
load是懒加载机制的,只有它被使用的时候,才会去查询数据库
清理缓存
数据库的更新方式
一般使用update

封装Hibernate的工具类
| import org.hibernate.Session; |
| import org.hibernate.SessionFactory; |
| import org.hibernate.cfg.Configuration; |
| import org.springframework.data.redis.core.index.PathBasedRedisIndexDefinition; |
| |
| public class HibernateUtil { |
| private static Configuration configuration; |
| private static SessionFactory sessionFactory; |
| private static ThreadLocal<Session> session = new ThreadLocal<>(); |
| |
| static { |
| configuration = new Configuration().configure("hibernate.cfg.xml"); |
| sessionFactory = configuration.buildSessionFactory(); |
| } |
| |
| public static Session getSession(){ |
| Session session = HibernateUtil.session.get(); |
| if (session==null || !session.isOpen()) { |
| if(sessionFactory == null){ |
| buildSessionFactory(); |
| } |
| |
| session = sessionFactory==null?null:sessionFactory.openSession(); |
| |
| HibernateUtil.session.set(session); |
| } |
| return session; |
| } |
| |
| |
| private static void buildSessionFactory() { |
| sessionFactory = configuration.buildSessionFactory(); |
| } |
| |
| public static void closeSession() { |
| Session session = HibernateUtil.session.get(); |
| HibernateUtil.session.set(null); |
| if(session!=null && session.isOpen()){ |
| session.close(); |
| } |
| } |
| } |
| |
Hibernate对象的生命周期
对象状态及生命周期
| Hibernate中对象有三种状态:瞬时状态(Transient)、持久状态(Persistent)、游离状态(Detached)。 |
| |
| 瞬时状态:刚刚使用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。Session中没有,数据库中没有。 |
| 持久化状态:已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。Session中有,数据库中有。 |
| 游离状态:已经被持久化,但不处于Session的缓存中。处于游离状态的Java对象被称为游离对象。Session中没有,数据库中有。(session中的缓存,一级缓存) |

单向多对一
HIbernate映射

自动生成表

也可以将xml配置文件中的update的构建表的方式注解打开
| |
| <property name="hibernate.hbm2ddl.auto">update</property> |
配置实体类对象
设有一个student表,以及一个grade表

Student.java
| import lombok.Data; |
| |
| import java.io.Serializable; |
| |
| @Data |
| public class Student implements Serializable { |
| private Integer id; |
| private String name; |
| private Integer age; |
| private Grade grade; |
| } |
| |
Student.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 package="com.jmu.design.domain"> |
| <class name="com.jmu.design.domain.Student" table="student"> |
| <id name="id"> |
| <generator class="native"/> |
| </id> |
| <property name= "name"/> |
| <property name="age"/> |
| |
| |
| |
| |
| |
| |
| |
| <many-to-one name="grade" class="Grade" not-null="true" column="grade_id"/> |
| </class> |
| </hibernate-mapping> |
Grade.java
| import lombok.Data; |
| |
| import java.io.Serializable; |
| |
| @Data |
| public class Grade implements Serializable { |
| private Integer id; |
| private String name; |
| } |
| |
Grade.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 package="com.jmu.design.domain"> |
| <class name="com.jmu.design.domain.Grade" table="grade"> |
| <id name="id"> |
| <generator class="native"/> |
| </id> |
| <property name= "name"/> |
| </class> |
| </hibernate-mapping> |
要记得mapping的映射也得加上
| <mapping resource="com/jmu/design/domain/Student.hbm.xml"/> |
| <mapping resource="com/jmu/design/domain/Grade.hbm.xml"/> |
测试文件
| public void manyToOneTest(){ |
| Session session = null; |
| Transaction tx = null; |
| |
| try{ |
| session = HibernateUtil.getSession(); |
| tx = session.beginTransaction(); |
| |
| |
| Grade grade1 = new Grade(); |
| grade1.setName("基础"); |
| Grade grade2 = new Grade(); |
| grade2.setName("高级"); |
| |
| session.save(grade1); |
| session.save(grade2); |
| |
| Student student1 = new Student(); |
| student1.setName("张三"); |
| student1.setAge(10); |
| student1.setGrade(grade1); |
| |
| Student student2 = new Student(); |
| student2.setName("李四"); |
| student2.setAge(20); |
| student2.setGrade(grade2); |
| |
| Student student3 = new Student(); |
| student3.setName("王五"); |
| student3.setAge(30); |
| student3.setGrade(grade1); |
| |
| session.save(student1); |
| session.save(student2); |
| session.save(student3); |
| |
| |
| tx.commit(); |
| }catch (Exception e){ |
| e.printStackTrace(); |
| tx.rollback(); |
| }finally { |
| HibernateUtil.closeSession(); |
| } |
| } |
单向一对多
配置实体类
Student.java
| import lombok.Data; |
| |
| import java.io.Serializable; |
| |
| @Data |
| public class Student implements Serializable { |
| private Integer id; |
| private String name; |
| private Integer age; |
| |
| } |
| |
Grade.java
| import lombok.Data; |
| |
| import java.io.Serializable; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| @Data |
| public class Grade implements Serializable { |
| private Integer id; |
| private String name; |
| private Set<Student> students = new HashSet<>(); |
| |
| } |
Student.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 package="com.jmu.design.domain"> |
| <class name="com.jmu.design.domain.Grade" table="grade"> |
| <id name="id"> |
| <generator class="native"/> |
| </id> |
| <property name= "name"/> |
| |
| <set name="students"> |
| <key column="grade_id" not-null="true"/> |
| <one-to-many class="Student"/> |
| </set> |
| </class> |
| </hibernate-mapping> |
Student.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 package="com.jmu.design.domain"> |
| <class name="com.jmu.design.domain.Student" table="student"> |
| <id name="id"> |
| <generator class="native"/> |
| </id> |
| <property name= "name"/> |
| <property name="age"/> |
| |
| |
| |
| |
| |
| |
| |
| |
| </class> |
| </hibernate-mapping> |
测试代码
插入的话和上面的一样
将student加入到grade的students集合中,就会自动映射到关系
查询:
| @Test |
| public void oneToMany(){ |
| Session session = null; |
| Transaction tx = null; |
| |
| try{ |
| session = HibernateUtil.getSession(); |
| tx = session.beginTransaction(); |
| |
| |
| |
| Grade grade = (Grade) session.get(Grade.class, 3); |
| System.out.println(grade.toString()); |
| |
| tx.commit(); |
| }catch (Exception e){ |
| e.printStackTrace(); |
| tx.rollback(); |
| }finally { |
| HibernateUtil.closeSession(); |
| } |
| } |
一对多在存储时,会先插入grade,然后插入student,之后发现这个student在grade的集合中,他们两个有关系,才会用update语句来更改student表中的grade_id,因此效率上来说是不如多对一的
双向多对一
就是把之前注释掉的配置文件和对应的实体类的字段打开
然后存的时候,用单向一对多或者单向多对一的方式都行
双向关系的时候记得把not-null删了
建议使用多对一,不用使用update语句,效率高
级联操作
在双向一对多的学习中,我们发现每次保存对象时,学生对象和年纪对象都需要我们持久化至session,既然它们两者有关联关系,可不可以只持久化其中一端,另一端就会自动的被持久化呢,这个属性就是Hibernate的cascade。 cascade是多对一、一对多、一对一、多对多各种关系之间的一种级联操作行为。

一般使用save-update,其他选项一般较少使用,级联插入
在存储的时候只需要存一方就行

维护关系
加上 inverse="true"由对方来维护关系,此时一端不再维护,当使用一对多来插入时,不会再更改grade_id字段

强制让多方来维护关系,因为多对一的插入较为高效
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY