拿出来大家共勉,不足之处请指正。
很久之前的学习笔记了,一直存放在本地中。
文章目录
Hibernate
概述
什么是框架?
使用框架写程序时,框架会自己实现一部分功能,我们就可以少些一部分代码。
什么hibernate框架?
- 此框架在javaee三层结构中DAO层框架
- 在dao层里面对数据库进行crud操作(无需写jdbc和复杂的sql语句就能实现功能 )
- 开源的轻量级框架
- hibernate版本
Orm思想
object\relational\mapping 对象关系映射
(1)实体类和数据表一一对应
让实体类和数据库表对应
让实体类属性 和 表里面字段对应
(2)不需要直接操作数据库表,而操作表对应实体类对象
入门
实体类
CRUD操作(重点)
public void testSave() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
//得到sessionFactory
sessionFactory = HibernateUtils.getSessionFactory();
//得到session
session = sessionFactory.openSession();
//开启事务
tx = session.beginTransaction();
//添加两个用户,为每个用户添加两个角色
//1 创建对象
User user1 = new User();
user1.setUser_name("lucy");
user1.setUser_password("123");
User user2 = new User();
user2.setUser_name("mary");
user2.setUser_password("456");
Role r1 = new Role();
r1.setRole_name("总经理");
r1.setRole_memo("总经理");
Role r2 = new Role();
r2.setRole_name("秘书");
r2.setRole_memo("秘书");
Role r3 = new Role();
r3.setRole_name("保安");
r3.setRole_memo("保安");
//2 建立关系,把角色放到用户里面
// user1 -- r1/r2
user1.getSetRole().add(r1);
user1.getSetRole().add(r2);
// user2 -- r2/r3
user2.getSetRole().add(r2);
user2.getSetRole().add(r3);
//3 保存用户
session.save(user1);
session.save(user2);
//提交事务
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
//sessionFactory不需要关闭
sessionFactory.close();
}
}
事务操作
事务代码的规范写法(重点)
try {
开启事务
提交事务
}catch() {
回滚事务
}finally {
关闭
}
public void testTx() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
//开启事务
tx = session.beginTransaction();
//添加
User user = new User();
user.setUsername("小马");
user.setPassword("250");
user.setAddress("美国");
session.save(user);
int i = 10/0;
//提交事务
tx.commit();
}catch(Exception e) {
e.printStackTrace();
//回滚事务
tx.rollback();
}finally {
//关闭操作
session.close();
sessionFactory.close();
}
}
Hibernate绑定session
在核心配置文件中配置
调用sessionFactory里面的方法得到
与本地线程绑定后无需再关闭事务,自己本身会自动关闭
API使用
Query
hql:hibernate query language,hibernate提供查询语言
Criteria
Restrictions.eq --> equal,等于.
Restrictions.allEq --> 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq的效果
Restrictions.gt --> great-than > 大于
Restrictions.ge --> great-equal >= 大于等于
Restrictions.lt --> less-than, < 小于
Restrictions.le --> less-equal <= 小于等于
Restrictions.between --> 对应SQL的between子句
Restrictions.like --> 对应SQL的LIKE子句
Restrictions.in --> 对应SQL的in子句
Restrictions.and --> and 关系
Restrictions.or --> or 关系
Restrictions.isNull --> 判断属性是否为空,为空则返回true
Restrictions.isNotNull --> 与isNull相反
Restrictions.sqlRestriction --> SQL限定的查询
Order.asc --> 根据传入的字段进行升序排序
Order.desc --> 根据传入的字段进行降序排序
MatchMode.EXACT --> 字符串精确匹配.相当于"like ‘value’"
MatchMode.ANYWHERE --> 字符串在中间匹配.相当于"like ‘%value%’"
MatchMode.START --> 字符串在最前面的位置.相当于"like ‘value%’"
MatchMode.END --> 字符串在最后面的位置.相当于"like ‘%value’"
SQLQuery
返回list集合每部分是数组形式
返回list集合每部分是对象形式
一对多操作
1、创建两个实体类
2、两个实体类相互表示
hibernate要求使用集合表示多的数据,使用set集合
3、配置映射关系
一个实体类对应一映射文件
客户-联系人 以对多
客户配置
联系人配置
4、创建核心配置文件,把映射文件引入到核心配置文件中
一对多····级联保存
1、较为复杂的方法.
public void testAddDemo1() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
//得到sessionFactory
sessionFactory = HibernateUtils.getSessionFactory();
//得到session
session = sessionFactory.openSession();
//开启事务
tx = session.beginTransaction();
// 添加一个客户,为这个客户添加一个联系人
//1 创建客户和联系人对象
Customer customer = new Customer();
customer.setCustName("传智播客");
customer.setCustLevel("vip");
customer.setCustSource("网络");
customer.setCustPhone("110");
customer.setCustMobile("999");
LinkMan linkman = new LinkMan();
linkman.setLkm_name("lucy");
linkman.setLkm_gender("男");
linkman.setLkm_phone("911");
//2 在客户表示所有联系人,在联系人表示客户
// 建立客户对象和联系人对象关系
//2.1 把联系人对象 放到客户对象的set集合里面
customer.getSetLinkMan().add(linkman);
//2.2 把客户对象放到联系人里面
linkman.setCustomer(customer);
//3 保存到数据库
session.save(customer);
session.save(linkman);
//提交事务
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
//sessionFactory不需要关闭
sessionFactory.close();
}
}
2、较为简单的方法,在开发中用的较多
– 在客户映射文件里面set标签进行配置,添加多一个save-update操作
public void testAddDemo2() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
//得到sessionFactory
sessionFactory = HibernateUtils.getSessionFactory();
//得到session
session = sessionFactory.openSession();
//开启事务
tx = session.beginTransaction();
// 添加一个客户,为这个客户添加一个联系人
//1 创建客户和联系人对象
Customer customer = new Customer();
customer.setCustName("百度");
customer.setCustLevel("普通客户");
customer.setCustSource("网络");
customer.setCustPhone("110");
customer.setCustMobile("999");
LinkMan linkman = new LinkMan();
linkman.setLkm_name("小宏");
linkman.setLkm_gender("男");
linkman.setLkm_phone("911");
//2 把联系人放到客户里面
customer.getSetLinkMan().add(linkman);
//3 保存客户
session.save(customer);
//提交事务
tx.commit();
}catch(Exception e) {
tx.rollback();
}finally {
session.close();
//sessionFactory不需要关闭
sessionFactory.close();
}
}
一对多····级联删除
1、第一步 在客户映射文件set标签,进行配置
2、代码直接删除
系统执行过程
-根据id查询客户
-根据外键id值查询联系人
-把联系人外键设置为null
-删除联系人和客户
inverse属性
hibernate是双向的外键维护,写是效率,读是性能,双向外键维护会让性能降低,为了提高性能,有以下解决方案。
一对多的关系里,让 “一” 放弃对外键的维护。
在放弃关系维护映射文件中,进行配置,在set标签上使用inverse属性
多对多操作
多对多···映射配置
1、创建两个实体类,用户和角色
2、实体类之间相互表示
- 一个用户多个角色
- 一个角色多个用户
- 用户配置文件中表示所有角色
- 角色配置文件中表示所有用户
3、核心配置文件中引入映射文件
多对多···级联保存
1、在用户配置文件中set标签进行配置,cascade值save-update
角色放在用户里,最终保存用户
多对多···级联删除(了解)
维护第三张表
- 赋予某些角色,先查找再操作
- 删除某些,先查找再操作
hibernate查询方式
对象导航查询
查询某个客户里面所有联系人过程,使用对象导航实现
OID查询
根据id查询某一条记录,返回对象
hql查询
Query对象,写hql语句实现查询
1 hql:hibernate query language,hibernate提供一种查询语言,hql语言和普通sql很相似,区别:普通sql操作数据库表和字段,hql操作实体类和属性
2 常用的hql语句
(1)查询所有: from 实体类名称
(2)条件查询: from 实体类名称 where 属性名称=?
(3)排序查询: from 实体类名称 order by 实体类属性名称 asc/desc
3 使用hql查询操作时候,使用Query对象
(1)创建Query对象,写hql语句
(2)调用query对象里面的方法得到结果
(1)查询所有
(2)条件查询
from 实体类名称 where 实体类属性名称=? and实体类属性名称=?
from 实体类名称 where 实体类属性名称 like ?
- 模糊查询
(3)排序查询
from 实体类名称 order by 实体类属性名称 asc/desc
(4)分页查询
- mysql实现分页
- Hql不写limit,Query对象封装两个方法实现
(5)投影查询
查询不是所有字段值,而是部分字段的值
(1)select 实体类属性名称1, 实体类属性名称2 from 实体类名称
(2)select 后面不能写 * ,不支持的
(6)聚集函数使用
count、sum、avg、max、min
QBC查询
1 使用hql查询需要写hql语句实现,但是使用qbc时候,不需要写语句了,使用方法实现
2 使用qbc时候,操作实体类和属性
3 使用qbc,使用Criteria对象实现
Restrictions.eq --> equal,等于.
Restrictions.allEq --> 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq的效果
Restrictions.gt --> great-than > 大于
Restrictions.ge --> great-equal >= 大于等于
Restrictions.lt --> less-than, < 小于
Restrictions.le --> less-equal <= 小于等于
Restrictions.between --> 对应SQL的between子句
Restrictions.like --> 对应SQL的LIKE子句
Restrictions.in --> 对应SQL的in子句
Restrictions.and --> and 关系
Restrictions.or --> or 关系
Restrictions.isNull --> 判断属性是否为空,为空则返回true
Restrictions.isNotNull --> 与isNull相反
Restrictions.sqlRestriction --> SQL限定的查询
Order.asc --> 根据传入的字段进行升序排序
Order.desc --> 根据传入的字段进行降序排序
MatchMode.EXACT --> 字符串精确匹配.相当于"like ‘value’"
MatchMode.ANYWHERE --> 字符串在中间匹配.相当于"like ‘%value%’"
MatchMode.START --> 字符串在最前面的位置.相当于"like ‘value%’"
MatchMode.END --> 字符串在最后面的位置.相当于"like ‘%value’"
(1)查询所有
1 创建Criteria对象
2 调用方法得到结果
(2)条件查询
(3)排序查询
(4)分页查询
(5)统计查询
(6)离线查询
servlet调用service,service调用dao
(1)在dao里面对数据库crud操作
(2)在dao里面使用hibernate框架,使用hibernate框架时候,调用session里面的方法实现功能
hql多表查询
左连接:不牵手,返回的是数组形式
迫切左连接:牵手,返回的是对象形式
(1)mysql多表查询回顾
(2)hql多表查询
内连接
from Customer c inner join r join c.setLinkMan
迫切内连接
from Customer c inner join fetch c.setLinkMan
左外连接
from Customer c left outer join c.setLinkMan
迫切左外连接
from Customer c left outer join fetch c.setLinkMan
右外连接
from Customer c right outer join c.setLinkMan
迫切右外连接
from Customer c right outer join fetch c.setLinkMan
hibernate的检索策略
(1)概念
(2)关联级别延迟操作
批量抓取
查询所有的客户,返回list集合,遍历list集合,得到每个客户,得到每个客户的所有联系人
在客户的映射文件中,set标签配置
(1)batch-size值,值越大发送语句越少