前言 : Hibernate框架是一个持久层技术的一个解决方案,使用很简单的配置就可以完成许多之前需要很多JDBC代码才能完成的增删改查操作 , 在这种持久层框架中 , ORM思想非常重要
在eclipse中可以安装Jboss插件,在开发hibernate的时候,有智能提示
Hibernate版本: 5.2.10
1.ORM思想 简单来说就是对关系型数据库中的表的字段和Java实体类中属性的一一映射关系
O: Object(对象) 即Java应用中的实体类
R: Relational(关系) 关系型数据表
M: Mapping(映射) 数据库中的表和Java应用中实体类的映射
最终的项目结构如下:
例如在数据库中有一张表t_user , t_user表中有三个字段(列) id(bigint),name(varchar),age(int) , Java应用中有一个实体类与之映射类名为User,User类中有三个属性 id(Long),name(String),age(Integer),并且User类中对应三个字段的setter和getter方法
如下图所示,t_user表中的字段和User表中的属性是一一对应的关系
对象关系映射
2.1. 第一步 拷贝jar包
在下载下来的hibernate框架的包下,有一个子目录lib,在lib下有一个required,表示开发hibernate应用所必须的jar包,拷贝到项目中做build path
需要hibernate jar的加我Q1012050164.
2.2 配置hibernate的属性配置文件,在classpath的根路径下创建一个hibernate.cfg.xml文件,一般都取这个名字(开发嘛,尽量符合规范)
eclipse中在source folder类型的文件下的目录会被编译输出到classpath(字节码输出路径)的根路径
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!-- hibernate的主配置文件 --> <hibernate-configuration> <session-factory> <!-- 配置数据库的连接信息 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">admin</property> <property name="hibernate.connection.url">jdbc:mysql:///jdbcdemo</property> <!-- 配置数据库方言,告诉hibernate框架我使用的是什么数据库 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- hibernate在执行的时候,显示运行的SQL语句 --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.format_sql">true</property> <!-- update表示如果在实体类中添加了新的属性,则更新表结构 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 关联映射文件 --> <mapping resource="com/ren/domain/User.hbm.xml"/> </session-factory> </hibernate-configuration>2.3 编写实体类和映射文件
实体类:User类,使用lombok的@setter和@getter注解生成对应字段的setter方法和getter方法:
package com.ren.domain; import java.util.Date; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Setter @Getter @ToString public class User { private Long id; // 主键id private String name; // 姓名 private Integer age; // 年龄 private Date hiredate; // 入职日期 }数据库中的t_user表
实体类User对应的映射文件,用来确定实体类的属性和数据库中的表的列对应关系,一般就叫 实体类名.hbm.xml, 所以我取名为User.hbm.xml
属性 ---- 列 映射
<!-- package属性值表示实体类在哪个包中 --> <hibernate-mapping package="com.ren.domain"> <class table="user" name="User"> <!-- 主键映射,列名为id,属性名也为id --> <id column="id" name="id" type="long"> <!-- 使用数据库自身的主键自增长方式 --> <generator class="native"/> </id> <!-- 非主键映射,属性名和列名一一对应 name属性表示实体类属性的名称 column表示实体类属性对应的列名 type:属性类型对应的数据库中的字段类型 --> <property name="name" column="name" type="string"/> <property name="hiredate" column="hiredate" type="date"/> <property name="age" column="age" type="integer"/> </class> </hibernate-mapping>2.4.编写测试CRUD
2.4.1 . Hibernate中的核心类,Session对象(实际上很多ORM框架(例如mybatis)访问数据库的类都叫这个名字) 封装了数据的增删改查操作,操作非常简单
获取Session对象的方法
核心类 : Configuration:配置类,一个Configuration对象代表和一个数据库的连接, 加载读取hibernate.cfg.xml全局配置文件,创建Configuration对象 , 放在classpath的根路径下.(注释有误 , 是hibernate.cfg.xml)
// 测试创建Session对象 @Test void testGetSession() throws Exception { Configuration config = new Configuration(); // 不带参数默认从classpath的根路径下加载名为hbm.cfg.xml的配置文件 config.configure(); Session session = config.buildSessionFactory().openSession(); }Session对象中封装了CRUD的方法 , 使用session对象完成基础的CRUD操作,使用Junit5单元测试 增删改操作必须使用事务对象Transaction,查询操作可以不涉及到事务
查询操作可以不使用事务
package com.ren.test; import java.util.Date; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.criterion.Restrictions; import org.hibernate.query.NativeQuery; import org.hibernate.query.Query; import org.junit.jupiter.api.Test; import com.ren.domain.User; import com.ren.many2one.Employee; public class HibernateCRUDTest { // 测试创建Session对象 @Test void testGetSession() throws Exception { Configuration config = new Configuration(); // 不带参数默认从classpath的根路径下加载名为hbm.cfg.xml的配置文件 config.configure(); Session session = config.buildSessionFactory().openSession(); } // 测试保存一条信息 @Test void testSave() throws Exception { // 创建需要保存的对象 User u = new User(); u.setName("致命华彩"); u.setAge(12); u.setHiredate(new Date()); // 创建配置类对象 Configuration config = new Configuration(); config.configure(); // 如果不指明主配置文件的路径,默认从classpath根路径下寻找hibernate.cfg.xml // 创建SessionFactory对象 SessionFactory factory = config.buildSessionFactory(); // 得到session对象 Session session = factory.openSession(); // 开启事务,对数据库进行增删改都要有事务 Transaction tx = session.getTransaction(); // 开启事务 tx.begin(); // 执行保存操作 session.save(u); // 提交事务 tx.commit(); // 关闭资源 session.close(); factory.close(); } // 更新一条用户信息 @Test void testUpdate() throws Exception { Configuration config = new Configuration(); config.configure(); SessionFactory factory = config.buildSessionFactory(); // 创建Session对象 Session session = factory.openSession(); Transaction tx = session.getTransaction(); tx.begin(); User user = session.get(User.class, 1L); System.out.println(user); user.setName("乐芙兰"); session.update(user); tx.commit(); } // 删除一条用户信息 @Test void testDelete() throws Exception { Configuration config = new Configuration(); config.configure(); SessionFactory factory = config.buildSessionFactory(); // 创建session对象 Session session = factory.openSession(); // 查询id为1的用户信息,主键查询 User user = session.get(User.class, 1L); Transaction tx = session.getTransaction(); tx.begin(); session.delete(user); tx.commit(); session.close(); factory.close(); } // 查询所有的用户信息,使用HQL(面向对象的查询语言)查询 @Test void testGetAll() throws Exception { Configuration config = new Configuration(); config.configure(); SessionFactory factory = config.buildSessionFactory(); Session session = factory.openSession(); // 面向对象的查询语言 Query<User> query = session.createQuery("FROM User", User.class); List<User> us = query.list(); for (User user : us) { System.out.println(user); } } // 查询年龄大于11岁的用户信息,条件查询类似于设置占位符条件,在HQL中还可以插入查询条件 @Test void testQueryByConditions() throws Exception { Configuration config = new Configuration(); config.configure(); Session session = config.buildSessionFactory().openSession(); // 占位符参数从0开始,HQL查询,第二个参数表示将最终查询的结果集封装成什么类型的对象 Query<User> query = session.createQuery("FROM User WHERE age > ?", User.class); query.setParameter(0, 13); List<User> us = query.list(); for (User u : us) { System.out.println(u); } } // QBC 使用criteria查询 ,QBC是完全的面向对象的查询语言,但是用的比较少基本不用,拼接查询条件太复杂 // Restrictions 是拼接查询条件的类 @SuppressWarnings("deprecation") @Test void testCriteria() throws Exception { Configuration config = new Configuration(); config.configure(); Session session = config.buildSessionFactory().openSession(); Criteria criteria = session.createCriteria(User.class); // id必须等于2 相当于SQL语句是 select * from User where id = 2 // 如果不添加查询条件,默认查询所有的用户信息 criteria.add(Restrictions.eq("id", 2L)); List<User> list = criteria.list(); for (User user : list) { System.out.println(user); } } // 有时候,查询很复杂的时候,HQL不能满足我们的需求,还可以使用本地SQL查询,但是本地SQL查询也过期了,因为可移植性太差 @SuppressWarnings("deprecation") @Test void testLocaleSql() throws Exception { Configuration config = new Configuration(); config.configure(); Session session = config.buildSessionFactory().openSession(); NativeQuery entity = session.createSQLQuery("SELECT * FROM User").addEntity(User.class); List list = entity.list(); for (Object object : list) { System.out.println(object); } } }