前言 : 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.Demo , 使用Hibernate框架完成对数据表t_user的CRUD操作
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);
}
}
}