前言:JavaEE开发的三层架构:客户端->WEB层->业务逻辑层->持久层
客户端:PC、APP
WEB层:Servlet+JSP、Struts、SpringMVC
业务层:JavaBean、Spring
持久层:JDBC、DBUtils、 Hibernate、MyBatis
理论上Servlet+JSP,JavaBean和JDBC可以开发所有的系统,但是一般公司都不会使用这种方式开发,效率太慢,性能差。企业会使用SSH(Struts,Spring,Hibernate)和SSM(SpringMVC,Spring,MyBatis)去开发,今天为大家带来的是Dao层框架Hibernate的知识体系。
一共分为三部分介绍:
1、Hibernate的简单使用(本文介绍)
2、Hibernate的详细讲解(Hibernate知识体系总结二https://www.jianshu.com/p/c8149129fa1b)
3、Hibernate表的关联关系(Hibernate知识体系总结三)
4、Hibernate案例(Hibernate知识体系总结三)
一、简介:
Hibernate是一个开源的ORM(Oobject Relational Mapping对象关系映射)框架,关系型数据库和对象之间的桥梁。在JDBC的基础上进行了封装,可以使用面向对象的思想进行操作数据库。
对象<——>O/R映射<——>关系型数据库
二、特点:
1、简化了数据访问层的重复代码,减少了内存消耗,加快了运行效率
2、减少了DAO层的编码工作
3、映射灵活性好,支持一对一,一对多,多对多各种复杂关系
4、可扩展性强,由于开源,可以自行编码扩展
三、使用:
1、创建Java项目,笔者是用的是Intelli IDEA进行开发的,相关的配置见另一篇文章https://www.jianshu.com/p/3efaf423f8c1
2、下载Hibernate,链接如下:https://sourceforge.net/projects/hibernate/files/hibernate-orm/
这边下载的是hibernate-release-5.4.8.Final.zipimage.png
documentation:API文档
libs:jar包,required目录下面为必须jar
project:hibernate相关的源代码
3、准备数据库和表,这边创建的是一张学生成绩表
create database hibernate_summary;
create table grades(
id bigint(32) not null comment 'id(主键)',
s_id int(10) not null comment '学号',
s_name varchar(32) not null comment '学生姓名',
s_source varchar(10) not null comment '学生分数',
s_class varchar(32) not null comment '学生班级',
primary key (id)
)engine=innodb default charset=utf8;
数据表.png
4、创建实体类和对应的映射文件, 创建成绩类Grades,并在同包名下新建Grades.hbm.xml映射文件(一般命名为xxx.hbm.xml),在该文件中定义了实体类与表的映射关系image.png
/**
* Hibernate持久化类编写规则:
* 1、需要提供无参构造方法,底层使用反射生成类的实例
* 2、属性私有化,提供共有get/set方法
* 3、属性尽量使用包装类,包装类多一个null类型,这样就容易区分是否有存入数据
* 4、需要有唯一表示OID与表的主键对应
* 5、尽量不要使用final,导致延迟加载策略失效
*/
public class Grades {
private Long id;
private Integer s_id;
private String s_name;
private String s_source;
private String s_class;
public Integer getS_id() {
return s_id;
}
public void setS_id(Integer s_id) {
this.s_id = s_id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getS_name() {
return s_name;
}
public void setS_name(String s_name) {
this.s_name = s_name;
}
public String getS_source() {
return s_source;
}
public void setS_source(String s_source) {
this.s_source = s_source;
}
public String getS_class() {
return s_class;
}
public void setS_class(String s_class) {
this.s_class = s_class;
}
}
<?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.hibernate.domain">
<!--
class标签:建立类与表的映射关系
name:类型全路径
table:表名
-->
<class name="com.hibernate.domain.Grades" table="grades">
<!--
id标签:类中属性和表中主键的映射
name:类中属性 column:表中字段
注意:如果类中属性和表中字段名称一致,column可省略不写
-->
<id name="id" column="id">
<!--
自然主键:将具有业务含义的字段作为主键,比如身份证号码,存在且唯一
代理主键:不具有业务含义,通常为整数类型,一般取名id
generator:主键生成策略(7种)
identity:主键自增,由数据库维护,录入时不需要指定主键
sequence(了解):oracle中的主键策略
increment(了解):主键自增,由hibernate维护,每次都会查找最大id,然后+1,生产中不使用,存在线程安全问题
hilo(了解):hibernate维护,自增,高低位算法,开发中不使用
native:hilo+sequence+identity 自动三选一策略
uuid:生成随机数作为主键,主键类型必须是string类型
assigned:自然主键生成策略,hibernate不会管理主键值,由开发人员自己录入
-->
<generator class="native"/>
</id>
<!--
property标签:类中属性和表中字段ß的映射
-->
<property name="s_id"/>
<property name="s_name"/>
<property name="s_source"/>
<property name="s_class"/>
</class>
</hibernate-mapping>
5、创建Hibernate核心配置文件,在src下面创建hibernate.cfg.xml文件(默认名称),用于配置数据库链接,全局属性置以及加载映射文件,发布后会在项目的WEB-INF/classes目录下
<?xml version="1.0" encoding="UTF-8"?>
<!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.jdbc.Driver</property>
<!-- 数据库url -->
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_summary?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true</property>
<!-- 数据库连接用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 数据库连接密码 -->
<property name="hibernate.connection.password">root</property>
<!-- 数据库方言
不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
sql99标准: DDL 定义语言 库表的增删改查
DCL 控制语言 事务 权限
DML 操纵语言 增删改查
注意: MYSQL在选择方言时,请选择最短的方言.
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--是否打印sql语句-->
<property name="hibernate.show_sql">true</property>
<!--是否格式化sql语句-->
<property name="hibernate.format_sql">true</property>
<!--
## auto schema export 自动导出表结构. 自动建表
#hibernate.hbm2ddl.auto create 自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
#hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
#hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
#hibernate.hbm2ddl.auto validate 校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--
指定hibernate操作数据库时的隔离级别
## specify a JDBC isolation level
#hibernate.connection.isolation 1|2|4|8
0001 1 读未提交
0010 2 读已提交
0100 4 可重复读
1000 8 串行化
-->
<property name="hibernate.connection.isolation">4</property>
<!--指定session与当前线程绑定-->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 引入orm元数据
路径书写: 填写src下的路径
-->
<mapping resource="com/hibernate/domain/Grades.hbm.xml"/>
</session-factory>
</hibernate-configuration>
6、编写测试代码,并查看数据库
/**
* 通过Hibernate往数据库添加数据
*/
public class TestHibernate {
public static void main(String[] args) {
//准备数据
Grades grades = new Grades();
grades.setS_id(302003);
grades.setS_name("小周3");
grades.setS_class("三零二班");
grades.setS_source("99");
//1.加载hibernate.cfg.xml配置文件
Configuration configuration = new Configuration().configure();
//2.创建SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
//3.创建session对象
Session session = sessionFactory.openSession();
//4.开启事务
Transaction tx = session.beginTransaction();
//5.保存分数
session.save(grades);
//6.提交事务
tx.commit();
//7.关闭资源
session.close();
}
}
控制台打印的sql语句:
新添加的数据:

7、封装获取Session工具类HibernateUtil,并测试使用
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
//1.加载hibernate.cfg.xml配置文件
Configuration configuration = new Configuration().configure();
//2.创建SessionFactory,一个web项目只能有一个sessionFactory对象
sessionFactory = configuration.buildSessionFactory();
}
/**
* 直接创建一个新的Session实例,使用后需要手动调用close方法关闭
* @return
*/
public static Session openSession() {
Session session = sessionFactory.openSession();
return session;
}
/**
* 创建的session实例会绑定到当前县城,提交或回滚是会自动关闭ß
* @return
*/
public static Session getCurrentSession() {
Session session = sessionFactory.getCurrentSession();
return session;
}
}
/**
* 通过Hibernate往数据库添加数据
*/
public class TestHibernate {
private static GradesService gradesService = new GradesServiceImpl();
public static void main(String[] args) {
//准备数据
Grades grades = new Grades();
grades.setS_id(302004);
grades.setS_name("小周4");
grades.setS_class("三零二班");
grades.setS_source("99");
gradesService.addGrade(grades);
}
}
public class GradesServiceImpl implements GradesService {
private GradesDao gradesDao = new GradesDaoImpl();
@Override
public void addGrade(Grades grades) {
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
try {
gradesDao.addGrade(grades);
} catch (Exception e) {
transaction.rollback();
e.printStackTrace();
}
transaction.commit();
}
}
public class GradesDaoImpl implements GradesDao {
@Override
public void addGrade(Grades grades) {
Session currentSession = HibernateUtil.getCurrentSession();
currentSession.save(grades);
}
}

至此Hibernate的简单使用已告一段落,未完待续~
Hibernate知识体系总结(二):https://www.jianshu.com/p/c8149129fa1b


