目录
- 表与表之间的回顾
- 一对多
- 多对多
- 冬眠一对多操作
- 一对多映射配置
- 一对多级联保存
- 一对多级联删除
- 逆属性
- 冬眠多对多操作
- 多对多映射配置
- 多对多级联保存
- 多对多级联删除
- 维护第三张表
表与表之间的关系
一对多
- 一对多建表,通过外键建立关系
多对多
- 创建中间表,进行描述,多对多的关系
一对一
hibernate的一对多的操作(重点)
一对多的映射配置
第一步创建实体类
- 创建两个实体类(客户和联系人为例)
- 属性\得到\设置方法
第二步让两个实体类之间互相表示
- 在客户实体类中表示多个联系人>>一个客户有多个联系人
- 休眠要求使用设置集合表示
- 新的HashSet <?>();
- 休眠要求使用设置集合表示
- 在联系人类中表示所属的客户>>一个联系人只能有一个客户
- 使用对象的方式表示
第三步配置映射关系
- 一般一个实体类对应一个映射文件
- 把映射文件最基本的配置完成
- 在映射文件中,配置一对多的关系
- 客户映射文件中,表示所有联系人
- 标签> set <表示联系人
- 属性>名称<>>设置集合的名称
- 标签> key <表示外键
- 属性> cilumn <表示外键名称
- 标签> one-to-many <表示一对多的关系
- 属性> class <表示联系人实体类的路径
- 标签> set <表示联系人
- 联系人映射文件中,表示所属客户
- 标签> many-to-one <表示都对一的关系
- 属性>名称<实体类名称
- 属性> class <实体类路径
- 属性> column <外键名称
- 标签> many-to-one <表示都对一的关系
- 客户映射文件中,表示所有联系人
第四步引入核心配置文件
第五步生成表
一对多级联操作
级联操作
1. 级联保存
* 添加一个客户,为客户添加多个联系人
2. 级联删除
* 删除某一个客户,这个客户的所有联系人也要删除
一对多级联保存
- 添加一个客户,给予一个联系人
- 复杂写法
- 创建客户和联系人的对象(id已经设置为自动)
- 建立两个对象之间的关系
- 把联系人放到客户对象的集合里面
- 把客户放入联系人里面
- 保存数据
- 两个对象都需要save(对象名);
- 简化写法(与复杂写法的差异)
- 在客户映射文件中进行配置
- 标签 > set < 中添加
- 属性 > cascade = " save-update" <
- 把联系人放入客户
- 保存 客户 save( 对象名 );
- 在客户映射文件中进行配置
- 复杂写法
一对多级联删除
- 删除某个客户,把客户的所有联系人删除
- 配置映射文件联系人的
- 标签 > set < 中添加
- 属性 > cascade = " save-update , delete " <
- 直接删除
- 根据id查询 获取对象
- 方法 delete( 对象名 ) 直接删除
- 配置映射文件联系人的
- 执行过程
- 根据 id 查询 客户
- 根据 客户的外键 查询联系人
- 把联系人的外键设置为 null
- 删除 联系人 和 客户
一对多连接修改
- 修改
- 根据 id 查询联系人 根据id查询客户
- 设置持久态对象的值
- 把联系人放入客户中
- 把客户放入联系人中
- inverse属性
- 因为hibernate是双向维护外键
- 修改让其中一方放弃外键维护(一对多的一的)
- 比如所有人都认识习近平,但习近平不认识所有人
- 具体实现
- 标签 > set < 中添加
- 属性 > inverse = " true " < 表示放弃外键维护
- 标签 > set < 中添加
hibern多对多的操作
多对多的映射配置
* 以用户和角色为例
- 创建实体类
- 两个实体类互相表示
- 用户里面表示所有角色,使用set集合
- 角色里面表示多个用户,使用set集合
配置映射关系
- 基本配置
配置多对多关系
在用户里表示所有角色
- 标签 > set < 中添加
- 属性 > table = " 中间表名 " < 表示他关联的中间表
- 标签 > key < 当前的外键配置
- 属性 > column = " 当前外键名称 "<
- 标签 > many-to-many < 关联表
- 属性 > class = " 路径 "<
- 属性 > column = " 关联字段"<
- 标签 > set < 中添加
在角色里表示所有用户
- 属性 > table = " 中间表名 " < 表示他关联的中间表
- 标签 > key < 当前的外键配置
- 属性 > column = " 当前外键名称 "<
- 标签 > key < 当前的外键配置
- 标签 > many-to-many < 关联表
- 属性 > class = " 路径 "<
- 属性 > column = " 关联字段"<
- 属性 > table = " 中间表名 " < 表示他关联的中间表
set > table : 表名一致时,表示关联同一张表
key > column : 声明本表的外键 与 关联表的 many-to-many > column 相同
many-to-many > class : 关联表的实体类路径 > column : 关联表的外键
在核心配置文件中引入映射
多对多级联保存
* 根据用户保存角色
- 在用户配置文件中set标签配置 , cascade 值 seve-update
- 写代码实现
- 创建用户和橘色对象
- 把角色放入到用户里面
- 最终保存用户
多对多级联删除
* 一般不会这样删除
- 在用户配置文件中set标签配置 , cascade 值 delete
- 写代码实现
- 查找用户
- 调用delete ( ) ;
维护中间表关系
用户和角色是多对多的关系,维护关系通过第三张表维护
拥有一个角色
- 根据 id 查询用户和角色
- 把角色放到用户里面去
- 把角色对象放入用户的set集合里
移除一个角色
- 根据 id 查询用户和角色
- 从用户里面把角色移除
- 从set集合里面把角色移除
hibernate 查询方式
对象导航查询
- 根据id查询某个客户,再查询这个客户里面所有的联系人
- session.get(实体类.class , id值 )
OID查询
- 根据id查询某一条记录,返回对象
hql查询
Query 对象, 写hql语句实现查询
- 和sql相似,区别是:sql根据表名和字段查找,hql根据实体类和属性查找
- 常用的hql 语句
查询所有
- 使用hql查询的时候使用Query 对象
- 创建Query对象
- Query query = session.createQuery(from 实体类名称);
- 调用Query对象获得结果
- List list = query.list();
- 创建Query对象
条件查询
- 语句
- from 实体类名称 where 实体类属性名称=? and 实体类属性名称=?;
- from 实体类名称 where 实体类属性名称 like ? ;
代码
设置条件值
- 向 ? 里面设置值 >
setParamenter方法();
Query query = session.createQuery( " from user u where u.uid=? and u.uname=? " ) ; //条件查询
该方法第一个参数 > 开始位置 (从"0"开始)
扫描二维码关注公众号,回复: 1877660 查看本文章- 该方法第二个参数 > 具体修改的值
设置第一个 ?
query.setParameter( 0 , 1 );
设置第二个 ?
query.setParameter( 1 , "雷鸣" ) ;
- 调用方法得到结果
List<?> list = query.list( ) ;
分页查询
hql语句使用查询所有的语句
" from 对象名"
代码实现
创建Query对象
Query query = session.createQuery( from user );
设置分页属性
query.setFirstResult( 0 ) ; //设置开始位置
query.setMaxResult( 10 ) ; // 设置每页的记录数
调用方法
List<?> list = query.list();
投影查询
- 什么是投影查询
- 查询的不是所有的值,而是查询部分的值
- 语句的写法
select 属性名 from 实体类名
代码
创建query对象
Query query = session.createQuery( "select > 属性名 < from > 实体类名 <" )
调用方法获得结果
List<?> list = query.list();
聚集函数
- 聚合函数
- count
- sum
- avg
- max
- min
- 聚合函数查询语句
select count(*) from 实体类名
代码
创建Query对象
Query query = session,createQuery( "select count(*) from 实体类名");
调用方法得到结果
Object ob = query.uniqueResult();
//这是一个返回单个对象的方法- 返回值处理
- 返回值不能直接强转为 int
- 应该为 object >> long >> int
Long lob = (Long) ob ;
//先变成 Longint count = lob.intValue();
// 再变成 int
否则会报异常 ClassCastException
QBC查询
使用Criteria对象
查询所有
创建Criteria对象
Criteria criteria = session.createCriteria(实体类名)
调用方法得到结果
List<?> list = criteria.list();
条件查询
**Restrictions**
创建Criteria对象
Criteria criteria = session.createCriteria(实体类名)
使用Criteria对象的方法设置条件(Restrictions)
criteria.add(Restrictions.eq("属性名1" , 值1 )) ;
criteria.add(Restrictions.eq("属性名2" , 值2 )) ;
调用方法得到结果
List<?> list = criteria.list();
排序查询
***Order**
创建Criteria对象
Criteria criteria = session.createCriteria(实体类名)
使用Criteria对象的方法设置条件(Order)
criteria.addOrder(Order.desc( "属性名1 ")) ;
//降序criteria.addOrder(Order.asc( "属性名2" )) ;
//升序调用方法得到结果
List<?> list = criteria.list();
分页查询
`"setFirstResult() 和 setMaxResult()`
代码实现
创建Criteria对象
Criteria criteria = session.createCriteria(实体类名);
设置分页属性
criteria.setFirstResult( 0 ) ; //设置开始位置
criteria.setMaxResult( 10 ) ; // 设置每页的记录数
调用方法
List<?> list = query.list();
统计(聚合)查询1. 聚合函数
`Porjection.rowCount();`
代码
创建Criteria对象
Criteria criteria = session,createCriteria(实体类名);
设置操作
criteria.setProjection(Projections.rowCount());
- 调用方法得到结果
Object ob = Criteria.uniqueResult();
//这是一个返回单个对象的方法 - 返回值处理
- 返回值不能直接强转为 int
- 应该为 object >> long >> int
Long lob = (Long) ob ;
//先变成 Longint count = lob.intValue();
// 再变成 int
离线查询
DetachedCriteria;
应用场景:提前写入条件,之后再调用session使用;
创建对象
DetachedCriteria detachedCriteria = DetachdeCrteria.forClass(实体类名);
- 最终执行时候才需要session
Criteria criteria = detachedVriteria.getExecutableCriteria(session);
2018/6/10 15:31:13