文章目录
什么是Hibernate
Hibernate是一个数据持久化层的ORM框架。ORM即Object Rational Mapping 对象关系映射,是一种程序技术。
Hibernate将javaBean对象与数据库的表产生一种映射关系,可以以面向对象的的方式操作数据库。
常用术语
PO:persistent object ,持久对象,用于与数据库交互数据。–dao层 (JavaBean + hbm )
BO:Business object 业务数据对象。–service层
VO:Value Object 值对象。–web层
SessionFaction
相当于JDBC数据库连接池。是线程安全的,可以为成员变量。
Session 会话
相当于JDBC的连接Connection,是线程不安全的,不要编写为成员变量,使用局部变量。
Session 相当于 JDBC的 Connection – 会话
session api
save 保存
update 更新
delete 删除
get 通过id查询,如果没有 null
load 通过id查询,如果没有抛异常
createQuery("hql") 获得Query对象
createCriteria(Class) 获得Criteria对象
Transaction 事务
开启事务 beginTransaction()
获得事务 getTransaction()
提交事务:commit()
回滚事务:rollback()
try{
//开启
//session操作
//提交
} catch(e){
//回滚
}
扩展:不需要手动的管理事务,之后所有的事务管理都交予spring。
Query对象
hibernate执行hql语句
hql语句:hibernate提供面向对象查询语句,使用对象(类)和属性进行查询。区分大小写。
获得 session.createQuery(“hql”)
方法:
list() 查询所有
uniqueResult() 获得一个结果。如果没有查询到返回null,如果查询多条抛异常。
setFirstResult(int) 分页,开始索引数startIndex
setMaxResults(int) 分页,每页显示个数 pageSize
Criteria对象
QBC(query by criteria),hibernate提供纯面向对象查询语言,提供直接使用PO对象进行操作。
获得方式:
Criteria criteria = session.createCriteria(User.class);
//条件
criteria.add(Restrictions.eq("username", "tom"));
// Restrictions.gt(propertyName, value) 大于
// Restrictions.ge(propertyName, value) 大于等于
// Restrictions.lt(propertyName, value) 小于
// Restrictions.le(propertyName, value) 小于等于
// Restrictions.like(propertyName, value) 模糊查询,注意:模糊查询值需要使用 %
工具类
public class H3Utils {
// 会话工厂,整个程序只有一份。
private static SessionFactory factory;
static{
//1 加载配置
Configuration config = new Configuration().configure();
//2 获得工厂
factory = config.buildSessionFactory();
//3 关闭虚拟机时,释放SessionFactory
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
System.out.println("虚拟机关闭!释放资源");
sf.close();
}
}));
}
/**
* 获得一个新的session
* @return
*/
public static Session openSession(){
return factory.openSession();
}
/**
* 获得当前线程中绑定session
* * 注意:必须配置
* @return
*/
public static Session getCurrentSession(){
return factory.getCurrentSession();
}
}
对象的三种状态
瞬时态、持久态、脱管态
瞬时态(Transient):直接new出来的对象就是瞬时态,Sava/update/ 变成了持久态了
持久态(Persistent):get、loat、createQuery、createCriteria 等 获得都是持久态。delete() 后就是瞬时态了
脱管态:new一个对象并设置了OID,就是脱管态了
关联关系映射
一对多/多对一
Cutomer 客户 <---> Order 订单
1 <---> 多
id, name id, name, customer_id
- Cutomer.hbm.xml
<!-- 一对多:一个客户用【多个订单】 -->
<set name="orders" cascade=".." inverse="true">
<key name="customer_id"/>
<one-to-many class="cn.htj.domain.Order"/>
</set>
- Order.hbm.xml
<!-- 多对一:多个订单属于【一个用户】 -->
<many-to-one name="customer" class="cn.htj.domain.Customer" column="customer_id"/>
多对多
多对多,需要一个中间表
数据库表:
student: course: stu_cour:
sid cid sno
sname cname cno
实体类:
Student:
public class Student {
private Integer sid;
private String sname;
// 学生选择多门课程.
private Set<Course> courses = new HashSet<Course>();
...
}
Course:
public class Course {
private Integer cid;
private String cname;
// 课程可以被多个学生选择:
private Set<Student> students = new HashSet<Student>();
...
}
hibernate映射文件:
Student.hbm.xml
<hibernate-mapping>
<class name="cn.htj.Student" table="student">
<id name="sid" column="sid">
<generator class="native"/>
</id>
<property name="sname" column="sname"/>
<!-- 配置多对多关联关系 -->
<set name="courses" table="stu_cour">
<key column="sno"/>
<many-to-many class="cn.htj.Course" column="cno"/>
</set>
</class>
</hibernate-mapping>
-------------------------------------------------------
Course.hbm.xml
<hibernate-mapping>
<class name="cn.htj.Course" table="course">
<id name="cid" column="cid">
<generator class="native"/>
</id>
<property name="cname" column="cname"/>
<!-- 配置多对多关联关系映射 -->
<set name="students" table="stu_cour">
<key column="cno"/>
<many-to-many class="cn.htj.Student" column="sno"/>
</set>
</class>
</hibernate-mapping>
一对一
情况1:主表的主键,与从表的外键(唯一),形成主外键关系
情况2:主表的主键,与从表的主键,形成主外键关系 (从表的主键又是外键)
情况1:
数据库表:
t_company: t_address:
cid aid
cname addr
compony_id
----------------------------------------------
Compony.hbm.xml
<class name="cn.htj.domain.Compony" table="t_compony">
<id name="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<one-to-one name="address" class="cn.htj.domain.Address" property-ref="compony"/>
</class>
--------------------------------------------------
Address.hbm.xml
<class name="cn.htj.domain.Address" table="t_address">
<id name="aid">
<generator class="native"/>
</id>
<property name="addr"/>
<many-to-one name="compony" class="cn.htj.domain.Compony" column="compony_id" unique="true"/>
</class>
情况2:
数据库表:
t_company: t_address:
cid aid 既是主键又是外键,即与cid保持一致
cname addr
----------------------------------------------
Compony.hbm.xml
<class name="cn.htj.domain.Compony" table="t_compony">
<id name="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<one-to-one name="address" class="cn.htj.domain.Address"/>
</class>
--------------------------------------------------
Address.hbm.xml
<class name="cn.htj.domain.Address" table="t_address">
<id name="aid">
<generator class="foreign">
<param name="property">compony</param>
</generator>
</id>
<property name="addr"/>
<one-to-one name="compony" class="cn.htj.domain.Compony" constrained="true"/>
</class>