更多Hibernate在框架开发
1.关于Hibernate
Hibernate是一个开放源代码ORM(对象关系映射)框架。该框架是当今主流的Java持久层框架之一。它对JDBC进行了轻量级的对象封装,使得Java开发人员可以使用面向对象的编程思想来操作数据库。
说的通俗点,传统的JDBC需要在数据库中创建数据库,创建表,使用Java代码中的Connection对象连接数据库,编写SQL语句实现增删改查,虽然有DBUtils工具帮我们处理事务,各种代码简化,但表字段非常多的时候,给参数赋值非常繁琐。而Hibernate利用实体类与表字段建立的配置文件帮我们自动创建表,并且在进行增删改查的时候不需要写SQL语句了,与SpringMVC等框架结合后,真正实现了一行代码搞定一个功能。所以这个框架大大简化了编码的复杂度,已经成为了一个共同协作的持久层框架之一。
2.一个单表小项目入门Hibernate
2.1 项目介绍
用户管理系统:
- MySQL数据库8.0版本: 项目数据库
user01
,用户单表tb_user
、用户表字段userid(int型,自增长)、username、userage
- 持久层操作: 对单表 添加用户、修改用户属性、删除用户、根据id查询用户。
- 额外技术: c3p0数据库连接池
2.2 项目编写之前的配置
Hibernate官网ORM模型Releases栏中下载Hibernate资源包(本文:
hibernate-release-5.0.12.Final
)。
导入jar包:
- 必须jar包:hibernate-release-5.0.12.Final/lib/required/文件夹下的所有jar包是hibernate的必须jar包
- 数据库jar包:
mysql-connector-java-8.0.11.jar
- 日志相关jar包 :
log4j-1.2.16.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.7.2.jar
在数据库中创建数据库user
mysql> create databases user;
2.3 编写实体类
实体类(也叫持久化类)就是JavaBean,编写的实体类属性最好与数据库表字段一样,实体类编写是有规范的:
- 提供无参数构造方法
- 属性私有化,提供get和set方法
- 尽量使用包装类的类型。int-Integer,char-Character,其余首字母大写。
- 属性中要有唯一标识与数据库中表的主键对应
- 尽量不用final修饰
public class User import Serializable; {
private Integer userid ;
private String username ;
private Integer userage ;
// setter和getter方法
}
2.4 编写映射配置文件
作用是让实体类属性与表字段名称建立联系。映射配置文件的名字和位置不是固定的,但建议以实体类名.hbm.xml
命名,并且放在实体类所在包下。
User.hbm.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!--引入dtd的XML约束-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.kmust.entity">
<!--
class:
name:用户实体类
table: 用户表名称
catalog:数据库名(可省略)
id: 主键设置
name : 实体类中与主键相对应的属性
column: 表主键名称
generator: 主键增长方式
class :主键增长方式
property: 其余属性设置
name: 实体类属性
column: 表中字段名,(省略表示字段名与实体类属性名一致)
-->
<!-- 第一部分:建立类和表的映射关系 -->
<class name="User" table="tb_user">
<!-- 第二部分:建立实体类属性与主键的映射关系 -->
<id name="userid" column="userid">
<generator class="native"/>
</id>
<!-- 第三部分:建立实体类其余属性与表字段的映射关系 -->
<property name="username" />
<property name="userage" />
</class>
</hibernate-mapping>
XML约束 : 在hibernate-core-5.2.17.Final.jar包下的org.hibernate下的hibernate-mapping-3.0.dtd里面有这段dtd的XML约束代码。
主键生成策略:(最常用两种)
native
: 设置主键(int)的生成策略为 自动增长,能够根据所用数据库自动判断增长方式(mysql是identity ,oracle是sequence)。uuid
: 设置主键(String)的生成策略为 采用128位的UUID算法生成的唯一标识。
如果实体类属性与表字段名称一致,则可以省略column
属性。
<hibernate-mapping>
标签中如果没有package属性,则实体类应该写完整的cn.kmust.entity.User
2.5 编写核心配置文件
作用是配置连接数据库的参数以及其他运行参数。核心配置文件的名字和位置也不是必须固定的,但最好以hibernate.cfg.xml
命名,并且放在src下,如果位置不是放在src下,则必须在代码中加载其路径。
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入dtd的XML约束 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 第一部分:配置连接数据库的基本参数 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///user01?useSSL=false</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--配置方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 第二部分:配置Hibernate的一些可选属性参数 -->
<!-- 显示sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化显示sql语句 -->
<property name="hibernate.format_sql">true</property>
<!--在SessionFactory创建时自动更新表结构,没有创建,不一样就修改 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 第三部分:加载映射配置 -->
<mapping resource="cn/kmust/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
XML约束 : 在hibernate-core-5.2.17.Final.jar/org/hibernate/hibernate-configuration-3.0.dtd里面有这段dtd的XML约束代码。
第一部分:数据库信息
- Platforms 下的各种数据库。
第二部分 :可选的配置
- Miscellaneous Settings(其他设置)下的各种配置。
- Plugin ConnectionProvider下的各种连接池。
- ……………………………..
提示 :
(1) 第一部分和第二部分的所有配置参数可在hibernate-release-5.2.17.Final/project/etc/hibernate.properites文 件下查看
(2)hibernate.properites文件中各参数配置可以网络搜索查看其具体用途,这儿不做累述。
第三部分 :程序运行只会加载核心配置文件,所以需要在核心配置文件中加载映射配置文件。
2.6 配置c3p0数据库连接池
导入c3p0数据库连接池相关的jar包(hibernate-release-5.0.17.Final/lib/optional/c3p0/)
在核心配置文件中的第二部分加入c3p0的配置
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
2.7 编写HibernateUtils工具类
以下涉及的对象可以在附录1中进行查看
在创建SessionFactory对象过程中就已经在更新表了,每次创建每次更新表,这导致资源消耗,所以,一般情况下,一个项目(一个数据库)只有一个SessionFactory实例,也就是SessionFactory实例第一次创建后,就不再关闭,让其为整个项目一直服务下去,所以,一般考虑抽取一个HibernateUtils工具类,把SessionFactory实例的创建放在静态代码块中,防止多次创建,降低了资源消耗。并且该类用静态方法返回Session对象,方便直接类名调用。
(1)静态代码块:静态代码块在类第一次加载时自动执行,并且只执行这一次,以后除非是创建该类对象,否则再次加载时也不会执行,常常用作初始化操作。
(2)静态方法: 静态方法在类加载的时候就已经加载,所以不需要用类的实例进行调用,而是可以用类名直接调用
所以应该注意的是:在一个项目中,SessionFactory在类加载时创建后就不能关闭了,如果一旦关闭,则再也不能开启。
public class HibernateUtils {
private static final SessionFactory sessionFactory ;
static {
try {
Configuration cfg = new Configuration().configure() ;
sessionFactory = cfg.buildSessionFactory();
} catch (ExceptionInInitializerError e) {
throw new ExceptionInInitializerError("初始化SessionFactory失败!") ;
}
}
/**
* 获取一个新的Session对象
* @return
*/
public static Session openSession() {
return sessionFactory.openSession();
}
}
2.8 编写Dao+测试(添加、删除、修改)
以下涉及的对象请查看附录1
以下给出测试框架,包含了事务的操作。其中,SessionFactory对象不能关闭,但是Session对象必须关闭。
public void add() {
//类名直接调用静态方法获取Session对象
Session session = HibernateUtils.openSession();
Transaction tx = null ;
try {
tx = session.beginTransaction();
//增删改查 操作
tx.commit();
} catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}finally {
session.close();
}
}
单表部分增删改查测试:
//增
session.saveOrUpdate(user);
//根据id查询
User user = session.get(User.class,1) ;
//修改年龄
User user = session.get(User.class,1) ;
user.setUserage(17);
session.saveOrUpdate(user);
//删除
User user = session.get(User.class,3) ;
session.delete(user);
3 注意MySQL版本与JDBC参数
重点提示(1):
在核心映射配置文件中,一些参数可能并不是hibernate.properites文件中给出的参数。尤其是第一部分的数据库参数,这与数据库的版本有很大关联。关于mysql最新版本8.x的JDBC连接请参考官网MySQL Connector/J 8.0 Developer Guide
例如:本人使用的是mysql8.0版本,这个版本要求 驱动参数里面加 了一个cj
,并且有SSL认证(url参数后多了一个userSSL的字段),5.7版本后,方言参数变为org.hibernate.dialect.MySQL5InnoDBDialect
。
如果写错了这些参数可能会导致一些列的问题,比如连接不上数据库,方言参数写错会导致虽然有Sql语句输出,但数据库中并没有建表成功等等问题。
重点提示(2) :
mysql的驱动jar也有版本的问题,请根据mysql版本下载相应的驱动。MySQL官网驱动下载地址
4 参考
附录1:Hibernate API重点对象
Hibernate5.0.12版本API参考(https://docs.jboss.org/hibernate/stable/orm/javadocs/)
Configuration对象 (org.hibernate.cfg.Configuration)是hibernate启动后的第一个对象,用来启动、加载、管理配置文件,并且创建SessionFactory对象实例。
SessionFactory接口(org.hibernate.SessionFactory)是用来初始化hibernate和创建Session对象。
Session接口(org.hibernate.Session)是负责执行创建Transaction对象和执行CRUD操作,是非线程安全的,多个线程并发操作一个Session实例时,会导致数据存取混乱。
- void saveOrUpdate(java.lang.Object object) : 添加、修改
- T get(java.lang.Class entityType, java.io.Serializable id) : 根据id查询记录对象
- void delete(java.lang.Object object) : 删除记录对象
Transaction接口(org.hibernate.Transaction)用于事务管理,通过session对象开启。