Hibernate[一]
2019-10-17 / JAVA / 1011 次围观 / 0 次吐槽 /1、hibernate简介
1.1、项目中框架的体系结构
1.2、ORM框架
n 对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)
n 对象和表字段进行对应
n 是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
n Object:对象,java对象,此处特指JavaBean,Model
n Relational:关系,二维表,数据库中的表。
n Mapping:映射
1.3、什么是hibernate
n Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装
n DBUtils也是对JDBC的封装
n 它将POJO与数据库表建立映射关系,是一个全自动的orm框架
n POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans
n hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
n Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用
1.4、总结Hibernate
n Hibernate是一个数据持久化层的ORM框架,它的主要功能就是把对象映射到表中,操作API,只需要将一个对象存储到数据库,不需要写sql语句
n Hibernate提供了对关系型数据库增删改成操作
1.5、主流的ORM框架
n JPA Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系(只有接口规范)
n Hibernate 最流行ORM框架,通过对象-关系映射配置,可以完全脱离底层SQL
n MyBatis 本是apache的一个开源项目 iBatis,支持普通 SQL查询,存储过程和高级映射的优秀持久层框架
n Apache DBUtils 、Spring JDBCTemplate
1.6、Hibernate的优点
v Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
v Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作 session.save(User);
v Hibernate使用java的反射机制
v Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,有一对一到多对多的各种复杂关系映射
2、hibernate的简单使用
hibernate的使用步骤
A.下载hibernate 的jar包,并导入到项目中(http://hibernate.org/orm/)
B.创建数据库和表
C.配置核心配置文件hibernate.cfg.xml【这个文件有连接数据库的配置】
D.编写映射文件hibernate mapping(*.hbm.xml),【声明对象如何关联数据库表字段】
E.调用hibernate的api
导入jar包
v 这里我们使用3.6.0的版本开发,4.0开发是建议使用注解
v 所需要导入的jar包,如下图,然后再导入一个mysql数据库连接驱动
hibernate的核心配置文件
² 将hibernate.cfg.xml放入src中
<!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> <!-- 1、配置数据库连接的4个参数 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/DB</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property> <!-- 是否显示sql语句 --> <property name="show_sql">true</property> <!-- 是否格式化sql语句 --> <property name="format_sql">true</property> <!-- 是否自动提交事务 --> <property name="hibernate.connection.autocommit">true</property> <!-- 2、配置JavaBean与表的映射文件 --> <mapping resource="com/cheug/hibernate/domain/User.hbm.xml"/> </session-factory> </hibernate-configuration>
编写JavaBean和映射文件.hbm.xml
JavaBean与.hbm.xml文件包属的包和文件名要一致
User.java 提供get/set方法
<!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.cheug.hibernate.domain.User" table="t_user"> <!-- 1、主键,如果属性与表字段不一至,要指定column --> <id name="uid" column="id"> <!-- 主键生成策略 --> <generator class="native"></generator> </id> <!-- 2、用户字段 --> <property name="username"></property> <property name="password"></property> </class> </hibernate-mapping>
使用
public class Demo01 { @Test public void test1(){ //1.获取核心 配置文件对象,默认是加载src的hibernate.cfg.xm文件 Configuration cfg = new Configuration().configure(); //2.创建会话工厂 SessionFactory factory = cfg.buildSessionFactory(); //3.创建会话 Session session = factory.openSession(); //开启事务 Transaction trans = session.beginTransaction(); //保存 User user = new User(); user.setUsername("cheug"); user.setPassword("123"); session.save(user); //提交事务 trans.commit(); //4.关闭会话 session.close(); //5.关闭工厂,释放资源 factory.close(); } }
常见问题
v 下面未知的实体是指在hibernate.cfg.xml中没有配置映射文件
3、API详解
3.1、Configuration 配置对象
² Hibernate的核心配置文件的多种形式
u hibernate.cfg.xml 通常使用xml配置文件,可以配置内容更丰富。
hibernate.properties 用于配置key/value 形式的内容,key不能重复的。配置有很多的局限性。一般不用。【可以进入hibernate-distribution-3.6.10.Final\project\etc目录看内容】
² Configuration 对象
² Configuration对象就是用来加载配置文件
² new Configuration构造方法配置加载的是hibernate.properties
² configre()方法加载的是hibernate.cfg.xml
默认情况下,上面两种配置文件都需要放在src目录下
configure(String resource)这个方法可以指定配置文件路径
² 加载映射文件方式
n 一种是在hibernate.cfg.xml配置,另一种是代码设置
² 常见异常
n 重复了映射文件
注意:开发中:将hbm.xml映射 配置 在hibernate.cfg.xml
3.2、SessionFactory 工厂
² SessionFactory 相当于java web连接池,用于管理所有session
² 获得SessionFactory 方式:config.buildSessionFactory();
² sessionFactory 还用于缓存配置信息 (数据库配置信息、映射文件,预定义HQL语句 等)
² SessionFactory线程安全,多个线程同时访问时,不会出现线程并发访问问题。
3.3、Session 会话
session会话的获取
² sessionFactory提供了两个方法来获取session
1. factory.openSession() 获取一个全新的session
2. factory.getCurrentSession() 获取一个与当前线程绑定的session
a.要使用这个方法必须在hibernate.cfg.xml中配置
<property name="hibernate.current_session_context_class">thread</property>
b.hibernate支持,将创建的session绑定到本地线程中,底层使用ThreadLocal,在程序之间共享session。
c.如果提交或者回滚事务,底层将自动关闭session
3.4、Transaction事务
² 掌握Hibernate中怎么获取事务,开启、提交、回滚事务
try{
//开启
//session操作
//提交
} catch(e){
//回滚
}
扩展:不需要手动的管理事务,之后所有的事务管理都交予spring。
v 事务也可以在hibernate.cfg.xml配置文件中设置
<!-- 是否自动提交事务 -->
<property name="hibernate.connection.autocommit">true</property>
3.5、session的api(方法)
n save 保存
n get 通过id查询,如果没有 null
n load 通过id查询,如果没有抛异常
n update 更新
n delete 删除
@Test public void test4(){ Configuration cfg = new Configuration().configure(); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); //1.save保存,插入数据,需要提交事务 //User u1 = new User("abc","123"); //session.save(u1); //2.get查询,根据id查询,hibernate会根据类名查表,如果没查找,返回null值 User u2 = (User) session.get(User.class, 15); System.out.println(u2); //3.load查询,如果没有查到,会抛出ObjectNotFoundException异常 User u3 = (User) session.load(User.class, 22); System.out.println(u3); session.close(); sf.close(); }
3.6、get和load方法的区别
v get方法是直接加载数据库
v load的设计是懒加载,用到时才去查询数据库
v load方法返回的是对象的一个代理
v load执行原理图
3.7、Query 查询对象
HQL:Hibernate Query Language的缩写,就是Hibernate的查询语言
面向对象查询语言,最终底层要转成面向数据库查询语言
SQL:直接面向数据库查询语言
Query:用于查询的对象,可以设置查询条件和分页查询
3.8、Criteria
v QBC(query by criteria),hibernate提供纯面向对象查询语言,提供直接使用PO对象进行操作。
概念:
PO:persistent object ,用于与数据库交互数据。--dao层 (JavaBean + hbm )
BO:Business object 业务数据对象。--service层
VO:Value Object 值对象。--web层
3.9、SQLQuery
² SQLQuery:使用原生的SQL语句查询
² 并不是所有sql都能转成hql
3.10,工具类
public class HibernateUtils { private static SessionFactory sf; static{ //1.加载配置 Configuration cfg = new Configuration().configure(); //2.创建一个sessionFactory sf = cfg.buildSessionFactory(); //3.在虚拟机关闭时,释放SessionFactory Runtime.getRuntime().addShutdownHook(new Thread(){ @Override public void run() { sf.close(); System.out.println("释放资源"); } }); } public static Session openSession(){ return sf.openSession(); } public static Session getCurrentSession(){ return sf.getCurrentSession(); } }
4、配置文件详解
4.1 hibernate.cfg.xml
4.2、hbm.xml映射文件 解说
实体类entity(model)的编写规则
² 我们在使用Hibernate时,书写了一个User类,这个类我们称为JavaBean
² JavaBean可以简单的理解成提供私有属性,并提供私有属性的get/set方法
² POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans
² 我们也称为模型,在Hibernate中,又称这种类为实体,因为是与表关联的
编写规则:
Ø 提供一个无参数 public访问控制符的构造器
Ø 提供一个标识属性,映射数据表主键字段,提供id
Ø 所有属性提供public访问控制符的 set get 方法(javaBean)
Ø 标识属性应尽量使用基本数据类型的包装类型
不要用final修饰实体 (将无法生成代理对象进行优化)
持久化对象的唯一标识 OID
v Java按地址区分同一个类的不同对象.
v 关系数据库用主键区分同一条记录
v Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系结论: 对象的OID和数据库的表的主键对应。
v 为保证OID的唯一性,应该让Hibernate来为OID赋值
区分自然主键和代理主键
v 主键需要具备: 不为空/不能重复/不能改变
v 自然主键: 在业务中,某个属性符合主键的三个要求.那么该属性可以作为主键列.【登录名可以是自然主键】
v 代理主键: 在业务中,不存符合以上3个条件的属性,那么就增加一个没有意义的列.作为主键.
基本数据与包装类型
v 基本数据类型和包装类型对应hibernate的映射类型相同
v 基本类型无法表达null、数字类型的默认值为0。
v 包装类默认值是null。当对于默认值有业务意义的时候需要使用包装类。
SQL、Hibernate和对象类型对应
Java数据类型 | Hibernate数据类型 | 标准SQL数据类型 |
byte、java.lang.Byte | byte | TINYINT |
short、java.lang.Short | short | SMALLINT |
int、java.lang.Integer | integer | INGEGER |
long、java.lang.Long | long | BIGINT |
float、java.lang.Float | float | FLOAT |
double、java.lang.Double | double | DOUBLE |
java.math.BigDecimal | big_decimal | NUMERIC |
char、java.lang.Character | character | CHAR(1) |
boolean、java.lang.Boolean | boolean | BIT |
java.lang.String | string | VARCHAR |
boolean、java.lang.Boolean | yes_no | CHAR(1)('Y'或'N') |
boolean、java.lang.Boolean | true_false | CHAR(1)('Y'或'N') |
java.util.Date、java.sql.Date | date | DATE |
java.util.Date、java.sql.Time | time | TIME |
java.util.Date、java.sql.Timestamp | timestamp | TIMESTAMP |
java.util.Calendar | calendar | TIMESTAMP |
java.util.Calendar | calendar_date | DATE |
byte[] | binary | VARBINARY、BLOB |
java.lang.String | text | CLOB |
java.io.Serializable | serializable | VARBINARY、BLOB |
java.sql.Clob | clob | CLOB |
java.sql.Blob | blob | BLOB |
java.lang.Class | class | VARCHAR |
java.util.Locale | locale | VARCHAR |
java.util.TimeZone | timezone | VARCHAR |
java.util.Currency | currency | VARCHAR |
主键的生成策略【重要】
<id name="uid" column="id">
<!-- generator:id的生成策略
increment:也会自动增长id,但是它的这种增长是自己Hibernate实现
执行select max(id) 查询,这种会有线程并发问题
sequence:一般在oracle数据库才用
hilo:hibernate自己实现的id规则【不用,不用学】
native:【经常常用】
如果是mysql数据库,id会自动增长
如果是oracle数据库,会自动增长,sequence
uuid:【经常常用】一个长字符串,需要把模型的id改成字符串
保存的时候,不用自己设置ID,hibernate会设置id
assigned:【经常常用】要手动设置id属性
-->
<generator class="assigned"></generator>
</id>
普通属性
² class标签的dynamic-insert="true" 是否动态生成插入语句,
² 【如果属性字段为空,就不会有些字段的插入语句】
² class标签的dynamic-update="true" 与insert类似
type的使用
v type是设置
- 上一篇:防止表单重复提交(拦截器)
- 下一篇:Hibernate[二]
Powered By Cheug's Blog
Copyright Cheug Rights Reserved.