在之前经常用到操作数据库的框架是Mybatis或者Mybatis-plus。
Hibernate在項目中用过,但没有深入的了解过,所以这次趁着假期把这个框架了解一下。
目录
- 概念
- Hibernate和Mybatis的区别
- Hibernate使用
- 依赖引入
- Hibernate配置文件
- XML配置文件详解
- properties文件详解
- 实体类
- 映射文件
- 测试
- HibernateApi
- Configuration
- SessionFactory
- Session 会话
- session api
- Transaction 事务
- Query对象
- Criteria 对象
概念
Hibernate就是一个持久层的ORM框架
什么是ORM框架?
利用描述对象和数据库表之间映射的元数据,自动把Java应用程序中的对象,持久化到关系型数据库的表中。通过操作Java对象,就可以完成对数据库表的操作。
Hibernate和Mybatis的区别
Hibrenate | Mybatis | |
---|---|---|
开发难度 | 复杂 | 简单 |
实体映射 | 采用数据库与entity映射 | 采用SQL与entity映射 |
sql优化 | 自动生成sql,存在有些语句较为繁琐,会多消耗一些性能 | 手动编写sql,可以避免不需要的查询,提高系统性能 |
缓存机制 | 二级缓存配置在SessionFactory生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置是哪种缓存 | 二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现 |
Hibernate使用
基于mysql8.0.12的使用
依赖引入
映入hibernate和MySQL驱动
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.10.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
同时需要设置对应的资源地址,用于读取配置文件
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
Hibernate配置文件
实现Hibernate基础配置,是Hibernate能够友好的与DB进行交互基础。(开发时放置src/main/resource目录下)
配置文件有两件形式:
- properties文件,如hibernate.properties
- XML文件,如hibernate.cfg.xml
个人建议使用XML,因为properties中不能配置关联的映射文件,在后续的实现中会带来一些没必要的编码
XML配置文件详解
<?xml version="1.0" encoding="GBK"?>
<!-- 指定Hibernate配置文件的DTD信息 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- hibernate- configuration是连接配置文件的根元素 -->
<hibernate-configuration>
<session-factory>
<!-- 指定连接数据库所用的驱动 -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<!-- 指定连接数据库的url,hibernate连接的数据库名 -->
<property name="connection.url">jdbc:mysql://local/数据库名?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8</property>
<!-- 指定连接数据库的用户名 -->
<property name="connection.username">root</property>
<!-- 指定连接数据库的密码 -->
<property name="connection.password">123456</property>
<!-- 指定连接池里最大连接数 -->
<property name="hibernate.c3p0.max_size">20</property>
<!-- 指定连接池里最小连接数 -->
<property name="hibernate.c3p0.min_size">1</property>
<!-- 指定连接池里连接的超时时长 -->
<property name="hibernate.c3p0.timeout">5000</property>
<!-- 指定连接池里最大缓存多少个Statement对象 -->
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">true</property>
<!-- 配置数据库方言,让hibernate框架识别不同数据库的自己特有的语句 -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 根据需要自动创建数据表
create:启动时删数据库中的表,而后建立,退出时不删除数据表数据库;
create-drop:启动时删数据库中的表,而后建立,退出时自动删除全部表;
update:自动修改,若是表结构与实体类不一致,那么就修改表使它们一致,数据会保留;
validate:自动校验,若是表结构与实体类不一致,那么不作任何操做,报错 -->
<property name="hbm2ddl.auto">update</property>
<!-- 显示Hibernate持久化操作所生成的SQL -->
<property name="show_sql">true</property>
<!-- 将SQL脚本进行格式化后再输出 -->
<property name="hibernate.format_sql">true</property>
<!-- 罗列所有的映射文件 -->
<mapping resource="映射文件路径/dept.hbm.xml"/>
</session-factory>
</hibernate-configuration>
properties文件详解
## MySQL
#方言
hibernate.dialect org.hibernate.dialect.MySQL5Dialect
#驱动
hibernate.connection.driver_class com.mysql.cj.jdbc.Driver
#数据库地址
hibernate.connection.url jdbc:mysql://localhost/数据库名
#用户名
hibernate.connection.username root
#密码
hibernate.connection.password 123456
#是否在控制台输出sql语句
hibernate.show_sql true/false
#设置当创建sessionfactory时,是否根据映射文件自动建立数据库表。 create-drop:表示关闭sessionFactory时,将drop刚建的数据库表。该属性可以是update/create-drop/create
hibernate.hbm2ddl.auto update
###########################
### C3P0 Connection Pool C3P0连接池###
###########################
#连接池最大链接数
hibernate.c3p0.max_size 2
#连接池最小连接数
hibernate.c3p0.min_size 2
#连接池连接的超时时长
hibernate.c3p0.timeout 5000
#缓存statements 的数量
hibernate.c3p0.max_statements 100
hibernate.c3p0.idle_test_period 3000
hibernate.c3p0.acquire_increment 2
hibernate.c3p0.validate true
############
### JNDI (java naming directory interface)Java命名目录接口###
###当无需hibernate自己管理数据源而是直接访问容器管理数据源 使用JNDI
############
#指定数据源JNDI名字
hibernate.connection.datasource dddd
#文件系统下
hibernate.jndi.class com.sun.jndi.fscontext.RefFSContextFactory
hibernate.jndi.url file:/
#网络
#指定JND InitialContextFactory 的实现类,该属性也是可选的。如果JNDI与Hibernate持久化访问的代码处于同一个应用,无需指定该属性
hibernate.jndi.class com.ibm.websphere.naming.WsnInitialContextFactory
#指定JNDI提供者的URL,该属性可选 如果JNDI与Hibernate持久化访问的代码处于同一个应用,无需指定该属性
hibernate.jndi.url iiop://localhost:900/
#指定链接数据库用户名
hibernate.connection.username root
#指定密码
hibernate.connection.password 1111
#指定方言
hibernate.dialect org.hibernate.dialect.MySQLDialect
#######################
### Transaction API 事务属性说明###
#######################
#指定是否在事务结束后自动关闭session
hibernate.transaction.auto_close_session true
#指定session是否在事务完成后自动将数据刷新到底层数据库
hibernate.transaction.flush_before_completion true/false
## 指定hibernate所有的事务工厂的类型,该属性必须是TransactionFactory的直接或间接子类
hibernate.transaction.factory_class org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.factory_class org.hibernate.transaction.JDBCTransactionFactory
## 该属性值是一个JNDI名,hibernate将使用JTATTransactionFactory从应用服务器中取出JTAYserTransaction
jta.UserTransaction jta/usertransaction
jta.UserTransaction javax.transaction.UserTransaction
jta.UserTransaction UserTransaction
## 该属性值为一个transactionManagerLookup类名,当使用JVM级别的缓存时,或在JTA环境中使用hilo生成器策略时,需要该类
hibernate.transaction.manager_lookup_class org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.transaction.manager_lookup_class org.hibernate.transaction.WeblogicTransactionManagerLookup
hibernate.transaction.manager_lookup_class org.hibernate.transaction.WebSphereTransactionManagerLookup
hibernate.transaction.manager_lookup_class org.hibernate.transaction.OrionTransactionManagerLookup
hibernate.transaction.manager_lookup_class org.hibernate.transaction.ResinTransactionManagerLookup
实体类
public class Dept implements Serializable {
private Integer id;
private String deptno;
private String dname;
private String loc;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptno() {
return deptno;
}
public void setDeptno(String deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
映射文件
实现POJO与DB表格的映射配置(为了维护方便一般将其放置和相对应的POJO同一目录下,取名为POJOName.hbm.xml)
虽然一个映射文件中可以配置多个POJO与数据库表的映射关系但是还是建议一个映射文件中只配置一个POJO与数据库表的映射关系
<?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.tung.entity.Dept" table="dept">
<id name="id" column="id">
<!-- <generator>:指定主键由什么生成,推荐使用uuid,assigned指用户手工填入。设定标识符生成器
适应代理主键的有:
increment:有Hibernat自动以递增的方式生成标识符,每次增量1;
identity:由底层数据库生成标识符,前提条件是底层数据库支持自动增长字段类型。(DB2,MYSQL)
uuid:用128位的UUID算法生成字符串类型标识符。
适应自然主键:
assigned:由java程序负责生成标识符,为了能让java应用程序设置OID,不能把setId()方法设置成private类型。
让应用程序在save()之前为对象分配一个标识符。相当于不指定<generator.../>元素时所采用的默认策略。
应当尽量避免自然主键
-->
<generator class="increment"/>
</id>
<property name="deptno" column="deptno"/>
<property name="dname" column="dname"/>
<property name="loc" column="loc"/>
</class>
</hibernate-mapping>
测试
向数据库里添加一个dept对象数据
@Test
public void testAdd(){
//加载hibernate核心配置文件
Configuration cfg = new Configuration();
cfg.configure();
//创建SessionFactory对象
SessionFactory sessionFactory = cfg.buildSessionFactory();
//创建session对象
Session session = sessionFactory.openSession();
//开启事务
Transaction tx = session.beginTransaction();
//具体crud操作
Dept dept = new Dept();
dept.setDeptno("154");
dept.setDname("测试部门");
dept.setLoc("测试地址");
//调用session的方法实现添加
session.save(dept);
//提交事务
tx.commit();
//关闭资源
session.close();
sessionFactory.close();
}
因为表不存在,hibernate自动创建表,之后插入数据
HibernateApi
Configuration
用于读取配置文件和orm映射文件
初始化 | 描述 |
---|---|
new Configuration().configure() | 加载src/main/resource下的hibernate.cfg.xml |
new Configuration() | 加载的src/main/resource下的hibernate.properties |
new Configuration().configure(String resourceFile) | 加载指定的名称的配置文件resourceFile |
SessionFactory
相当于java web连接池,用于管理所有session
Session 会话
负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。
Session对象是非线程安全的。
获取Session方法 | 描述 |
---|---|
openSession() | 创建一个新的Session,使用完成后要手动调用close来关闭 |
getCurrentSession() | 获取一个与线程绑定的Session,当我们提交或事务回滚后会自动关闭 |
session api
方法名 | 描述 |
---|---|
save | 保存 |
update | 更新 |
delete | 删除 |
get | 通过id查询,如果没有 null |
load | 通过id查询,如果没有抛异常(延迟加载,提高Hibernate的执行效率) |
createQuery(“hql”) | 获得Query对象 |
createCriteria(Class) | 获得Criteria对象 |
Transaction 事务
方法名 | 描述 |
---|---|
beginTransaction() | 开启事务 |
getTransaction() | 获得事务 |
commit() | 提交事务 |
rollback() | 回滚事务 |
Query对象
获得方法
createQuery();
方法名 | 描述 |
---|---|
list() | 查询所有 |
uniqueResult() | 获得一个结果。如果没有查询到返回null,如果查询多条抛异常 |
setFirstResult(int) | 分页,开始索引数startIndex |
setMaxResults(int) | 分页,每页显示个数 pageSize |
Criteria 对象
获得方法
createCriteria();
这个对象用的不多,因为它有局限性,所以稍作了解即可