Hibernate二
来源:互联网 发布:zbrush for mac 编辑:程序博客网 时间:2024/04/28 10:10
Hibernate框架常用知识点总结
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
- Hibernate
- 概念
- 框架搭建
- 配置详解
- 映射文件
- hibernate-mapping
- class属性
- id属性映射主键
- property属性映射普通列
- 主配置文件
- 映射文件
- API详解
- configuration
- SessionFactory
- Session
- Transaction
- 创建实体对象规则
- 对象的三种状态
- 一级缓存
- hibernate中的事务管理
- 设置事务隔离级别
- hibernate中事务的应用
- 一对多多对一关系
- ORM
- 应用
- Cascase属性级联操作
- inverse属性是否放弃维护关系
- 多对多关系
- ORM
- 应用
- Cascade属性级联操作
- inverse属性是否放弃维护关系
- Hibernate中的查询
- HQL
- 语法
- Criteria查询
- 语法
- 离线Criteria查询对象
- 原生SQL
- 语法
- 查询策略
- 类级别查询策略
- 关联级别查询策略
- 两个问题
- HQL
Hibernate
概念
- 用于操作数据库
- hibernate可以用面向对象的方式操作数据库
- ORM框架-将对象与表的关系使用配置文件映射
框架搭建
- 导包
导入lib下的required下的包 准备实体&映射文件
在实体所在包下新建映射文件(名称:类名.hbm.xml),导入dtd约束(在hibernate-mapping-3.0.dtd)<hibernate-mapping> <class name="类名" table="表名"> <!--配置主键--> <id name="主键对应的属性名" column="表的主键名" > <!--配置id生成策略--> <generator class="native"></generator> </id> <!--配置其他属性--> <property name="属性名" column="表的字段"></property> </class></hibernate-mapping>
准备主配置文件
在src目录下,新建hibernate.cfg.xml主配置文件,导入dtd约束(在hibernate-configuration-3.0.dtd)<session-factory> <!--5个必选项--> <proprrty name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <proprrty name="hibernate.connection.url">jdbc:mysql:///test</property> <proprrty name="hibernate.connection.username">root</property> <proprrty name="hibernate.connection.password">123</property> <!--mysql方言,选择最短的选项--> <proprrty name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!--3个可选项--> <!--选择标准的sql打印在控制台--> <property name="hibernate.show_sql" >true</property> <property name="hibernate.format_sql" >true</property> <!--自动建表--> <property name="hibernate.hbm2ddl.auto">update</property> <!--引入映射文件--> <mapping resource="cn/it/domain/User.hbm.xml" /></session-factory>
书写代码
配置详解
映射文件
hibernate-mapping
package属性:填写一个包名,后续配置中默认类所在包即为package属性填写的包
class属性
映射表与类的对应
name属性:类名
table属性:表名
id属性(映射主键)
name属性:类中主键属性名
column属性:表中主键名,默认列名为属性名
length属性:当前列的长度,默认数据库对于类型最大长度
type属性:当前列的类型,默认自动检测属性
generator属性:主键生成策略
代理主键:
increment:先查询表中主键最大值,加1作为新的主键值.
identity:依赖于数据库的主键自增
sequence:使用数据库中的序列
hilo:hibernate自己用高低位算法完成主键自增
uuid:生成随机字符串作为主键(长度应大于32位)
native(常用):自动根据数据库 三选一.(identity|sequence|hilo)
自然主键:
assigned:hibernate不生成主键.由开发人员自己设置主键值.
property属性(映射普通列)
name属性:类中主键属性名
column属性:表中主键名,默认列名为属性名
length属性:当前列的长度,默认数据库对于类型最大长度
type属性:当前列的类型,默认自动检测属性
主配置文件
整体结构在框架搭建的主配置文件中。
自动建表(hibernate.hbm2ddl.auto)
create:自动建表,每次启动hibernate都会自动建表,即使表已经存在,仍然会删除重新建。
create-drop:自动建表,每次启动hibernate都会自动建表,每次运行完成后会将表删除。
update:自动建表,如果有表,就不在重新创建,如果配置改变,自动更改表结构。
validate:不会自动创建表结构,只负责在启动时检验表结构,检出问题后会抛出异常。
API详解
configuration
config,读取配置文件buildSessionFactory,创建sessionFactoryConfiguration conf = new Configuration().config;SessionFactory sf = conf.buildSessionFactory;
SessionFactory
根据配置信息创建session对象。
1. SessionFactory创建需要消耗较多的内存资源。
2. SessionFactory是线程安全的设计。
结论:在一个web项目中确保只有一个SessionFactory存在。
//获得一个全新的sessionSession session = sf.openSession();//获得与线程绑定的session,使用需要两个条件:1.在主配置文件中配置2.不需手动关闭sessionSession session = getCurrentSession
Session
hibernate中操作数据库的核心对象。
1. 操作增删改查
2. 获得事务操作对象
beginTransaction|getTransaction 获得事务对象,第一个还具有开启事务的功能。get|load 根据给定标识和实体类返回持久化对象的实例save 增delete 删update 改saveOrUpdate 根据给定的实例的标识属性的值来决定执行增或改的操作。createQuery 根据给定的HQL查询条件创建一个新的Query实例。createCriteria 根据给定的实体的名称,创建一个新的Criteria实例。createSQLQuery 根据给定的SQL查询条件创建一个新的SQLQuery实例。get方法不会应用类级别加载策略,立即加载。load方法会应用类级别加载策略,load方法调用时,不会发送任何sql语句,返回一个代理对象,使用对象时才执行查询加载数据。
Transaction
用于操作事务的对象
tx.tx.begin();//开启事务tx.commit();//提交事务tx.rollBack();//回滚事务
创建实体对象规则
- public的空参构造
- 准备属性,public的set/get方法
- 提供oid,映射主键字段
- 标识属性尽量使用基本数据类型的包装类
- 类不能被final修饰
对象的三种状态
瞬时 没id,没关联
持久 有id,有关联
游离 有id,没关联
持久化状态:持久化状态对象会在事务提交时会持久化到数据库,我们需要将对象持久化到数据库,就需要把对象转换为持久化状态。
一级缓存
一级缓存:也称为session缓存.属于线程级别缓存. 该缓存本质其实就是一个集合.该集合被放置到了session对象中.所以也叫session缓存.因为session是线程级别的.所以该缓存属于线程级别缓存.
缓存的作用:提高查询、修改效率。
查询:
1. 根据id查询对象
2. ResultSet会被封装成对象,放入缓存以及返回程序。如果缓存中存在要查id的对象,返回缓存中的对象。
修改:
1. 根据id查询对象
2. ResultSet会被封装成对象,一式两份,分别放入session缓存以及缓存快照中
3. 事务在提交时,会比对session缓存中的以及快照中的对象是否发生变化。如果发生变化执行修改。
hibernate中的事务管理
设置事务隔离级别
<!--数值可设置为1、2、4、8--><property name="hibernate.connection.isolation">4</property>
hibernate中事务的应用
- 事务在service层管理。
- 确保service层和dao层使用的时同一个Connection,调用getCurrentSession方法是从ThreadLocal中获得与线程绑定的session。
getCurrentSession必须配置才能使用
<!--指定getCurrent获得session与当前线程绑定--><property name="hibernate.current_session_context_class">thread</property>
- getCurrentSession方法获得的session对象,会在事务提交时自动关闭,不用手动关闭。
一对多|多对一关系
ORM
ORM:对象关系映射
- o:一的一方使用集合,多的一方直接引用一的属性
- r:多的一方使用外键引用一的一方
m:一对多关系映射,多对一关系映射
<!--配置一对多关系--><set name="集合属性名"> <key column="外键名"></key> <one-to-many class="多的一方对应的类名" /></set><!--配置多对一关系--><many-to-one name="引用一的属性名" column="外键名" class="一的一方对应的类名"><many-to-one>
应用
Cascase属性:级联操作
- none:默认值,不级联
- save-update:级联保存或级联更新
- delete:级联删除
- all:save-update+delete
结论:Cascase属性的性质属于减少开发时书写代码量的配置,可以不用靠写代码代替,级联操作尤其级联删除配置使用风险大,不建议使用。
inverse属性:是否放弃维护关系
inverse属性:
- true:放弃
- false(默认):维护
一对多中可以使用Inverse属性放弃维护关系,多对一中不能放弃维护关系。
<set name="linkMen" inverse="true"> <key column="lkm_cust_id"></key> <one-to-many class="LinkMan"></one-to-many></set>
结论:为了避免维护关系SQL打印冗余,可以在一的一方放弃维护。配置后注意,表达关系只能通过多的一方来维护。
多对多关系
ORM
ORM:对象关系映射
- r:使用第三张表,该表至少两列,两列都是外键
- o:两方都用集合来表达引用多个对方
m: 多对多映射文件
应用
Cascade属性:级联操作
与一对多|多对一关系中相同的操作
不推荐使用delete
inverse属性:是否放弃维护关系
inverse属性:
- true:放弃
- false(默认):维护
结论:为了避免维护关系重复造成异常抛出,根据业务需要由一方放弃维护。放弃的规则:谁不依赖,谁放弃。例如:订单和商品,商品不依赖订单的存在,商品放弃维护。
Hibernate中的查询
- 根据OID查询
- 对象属性导航
- HQL查询
- Criteria查询
- 原生SQL查询
HQL
Hibernate Query Language:hibernate查询语言
该查询语言是面向对象的查询语言.
HQL语句中绝对不可能出现与数据库相关的信息.
该语言是Hibernate独有的语言.只能在Hibernate中使用
语法
一. 基础语法
//1.书写sql //String hql = "select c from cn.it.domain.Customer c";//完整写法 String hql = "from Customer";//简写 //2.创建查询对象 Query query = session.createQuery(hql); //3.执行查询 List<Customer> list = query.list();
二. 投影查询
查询一个属性
String hql = "select c.id from Customer c"; Query query = session.createQuery(hql); List<String> list = query.list();
查询两个属性
String hql = "select c.id,c.name from Customer c"; Query query = session.createQuery(hql); List<Object[]> list = query.list();
查询多个对象,并封装到对象中
String hql = "select new Customer(c.id,c.name,c.password) from Customer c"; Query query = session.createQuery(hql); List<Customer> list = query.list();
三. 条件查询
问号占位符
String hql = "from Customer c where c.name=?";Query query = session.createQuery(hql);query.setParameter(0,"张%");//从0开始List<Customer> list = query.list();
命名占位符
String hql = "from Customer c where c.id between :low and :high";Query query = session.createQuery(hql);query.setParameter("low",2);query.setParameter("high",5);List<Customer> list = query.list();
四. 分页查询
String hql = "from Customer";Query query = session.CreateQuery(hql);query.setFirstResult(2);//startIndexquery.setMaxResults(2);//pageSizeList<Customer> list = query.list();
五. 排序
desc降序,asc升序
String hql = "from Customer c order by c.id desc ";Query query = session.createQuery(hql);List<Customer> list = query.list();
六. 聚合函数查询
Count、Max、Min、Sum、Avg
String hql = "select count(c) from Customer c";Query query = session.createQuery(hql);Long count = (Long)query.uniqueResult();
七. 多表查询
内连接
String hql = "from Customer c inner join c.linkMen";Query query = session.createQuery(hql);List<Object[]> list = query.list();
迫切内连接
String hql = "from Customer c inner join fetch c.linkMen";Query query = session.createQuery(hql);List<Customer> list = query.list();
左外连接
String hql = "from Customer c left join c.linkMen";Query query = session.createQuery(hql);List<Object[]> list = query.list();
左外迫切连接
String hql = "from Customer c left fetch c.linkMen";Query query = session.createQuery(hql);List<Customer> list = query.list();
右外连接、右外迫切连接在左的基础上把left换为right即可。
结论:HQL适用于单表或简单多表,业务逻辑较为复杂的多表仍然需要使用原生SQL书写.
Criteria查询
hibernate框架中独有的查询方式.
Criteria是无语句面向对象查询.
Criteria一般用于单表查询.
语法
一、基础查询
//1.创建查询对象Criteria c = session.createCriteria(Customer.class);//2.执行查询List<Customer> list = c.list();
二、条件查询
Criteria c = session.createCriteria(Customer.class);//设置查询参数c.add(Restrictions.and(Restrictions.between("id",2,5),Restrictions.like("name","李%")));//查询List<Customer> list = c.list();
三、分页查询
Criteria c = session.createCriteria(Customer.class);c.setFirstResult(2);c.setMaxResults(2);List<Customer> list = c.list();
四、排序查询
Criteria c = session.createCriteria(Customer.class);c.addOrder(Order.asc("age"));List<Customer> list = c.list();
五、聚合查询
Criteria c = session.createCriteria(Customer.class);c.setProjection(Projections.Count("id"));Long count = (Long)c.uniqueResult();
离线Criteria查询对象
离线Criteria:不需要session就可直接创建
//获得离线查询对象DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);//设置条件dc.add(Restrictions.like("name","王%"));//将离线查询对象与session关联Criteria c = dc.getExecutableCriteria(session);//执行操作List<Customer> list = c.list();
结论:适合单表
原生SQL
语法
一、基本查询
String sql = "select * from t_customer";//创建查询对象Query query = session.createSQLQuery(sql);List<Object[]> list = query.list();
将指定结果封装到对象中
String sql = "select * from t_customer";Query query = session.createSQLQuery(sql);//指定将结果封装到对象中query.addEntity(Customer.class);List<Customer> list = query.list();
二、条件查询
参数查询:可以用问号|命名占位符
String sql = "select * from t_customer where name like ?";Query query = session.createSQLQuery(sql);query.setParameter(0,"陈%");query.addEntity(Customer.class);List<Cutomer> list = query.list();
三、分页查询
String sql = "select * from t_customer limit ?,?";Query query = session.createSQLQuery(sql);query.setParameter(0,2);//设置起始页query.setParameter(1,3);//设置每页封装数量query.addEntity(Customer.class);List<Customer> list = query.list();
用于复杂业务查询
查询策略
类级别查询策略
lazy属性:是否懒加载|延迟加载
- true(默认值):懒加载|延迟加载
false:立即加载
<!--配置类级别查询策略--><class name="User" table="cn.it.domain.User" lazy="true"></class>
原理:懒加载时,load方法不会立即查询,会返回要查询的对象的代理对象,这个代理对象对当前操作的session进行封装,在获得对象的属性时,能够根据关联的session加载数据。
注意事项:返回对象的初始化操作一定要在session关闭之前完成,否则会抛出no-session异常。
关联级别查询策略
集合加载策略(一对多|多对多)
lazy属性:决定集合加载策略
- true(默认值):懒加载|延迟加载
- false:立即加载
- extra:极其懒惰,在查询数量时,只查询数量,不查询内容。
fetch属性:指定集合的加载方式
- select(默认值):加载集合时使用单表查询加载
- join:加载集合时使用左外连接查询(使用改属性,lazy属性会失效)
subselect:使用子查询加载多个集合,如果只加载一个,效果和select相同。
<set name="linkMen" inverse="true" lazy="true" fetch="subselect" > <key column="lkm_cust_id"></key> <one-to-many class="LinkMan"></one-to-many></set>
属性加载策略(多对一)
lazy属性:决定属性加载策略
- proxy(默认值):由对方类级别策略代我决定
- false:立即加载
fetch属性:指定属性的加载方式
- select(默认值):单表查询加载数据
join:使用多表查询同时加载数据(使用改属性,lazy属性会失效)
<many-to-one name="customer" column="lkm_cust_id" class="Customer" lazy="proxy" fetch="select"></many-to-one>
查询策略结论:查询策略中涉及的所有属性都使用默认值
两个问题
问题一:sql语句打印n+1问题
batch-size属性:一次加载几个客户的集合,默认值为1.使用该属性选择一次加载几个客户的集合来缓解n+1问题
<set name="linkMen" batch-size="5" > <key column="lkm_cust_id"></key> <one-to-many class="LinkMan"></one-to-many></set>
问题二:dao返回的代理对象,service中关闭了session。在web层使用代理对象时,session已经关闭。会抛出no-session异常。
解决方案:
1. 不使用getCurrentSession,自己将session与现程绑定。
2. 使用过滤器,由过滤器中后处理代码将session关闭。
上述操作,交由spring管理。
- 顶
- 0
- 踩
- 0
- 上一篇SVN版本管理工具的使用
- 下一篇Struts2框架搭建、标签、Action以及拦截器总结
我的同类文章
- •自定义BeanUtils处理时间格式转换2017-01-26
- •java制作验证码并进行验证2017-01-25
- •Struts2框架搭建、标签、Action以及拦截器总结2017-01-17
- •Spring框架(二)整合Junit4、AOP开发、AOP事务管理详解2017-01-12
- •Struts2框架(二)参数封装、OGNL表达式、拦截器详解2017-01-09
- •java发送邮件工具类2017-01-26
- •Spring框架之IOC、AOP详解2017-01-18
- •Spring(三)Spring整合Struts2、Hibernate2017-01-14
- •Spring框架(一)环境搭建、配置(xml、注解)、整合JDBC以及项目详解2017-01-11
- •Struts2框架(一)架构、文件配置、核心API详解2017-01-08
- Hibernate(二)
- Hibernate(二)
- Hibernate二
- Hibernate(二)
- hibernate二
- hibernate:二
- 【Hibernate】Hibernate系列(二)
- Hibernate(二) Hibernate基本查询
- Hibernate实战(二)
- hibernate实践(二)
- Hibernate实践(二)
- Hibernate初探(二)
- Hibernate要点(二)
- 遨游Hibernate之二
- Hibernate 复习笔记二
- hibernate分页查询二
- Hibernate学习笔记(二)
- hibernate学习笔记二
- 算法竞赛入门经典 第二版 习题4-10 洪水 Flooded uva815
- 32.768KHZ晶振的含义与发展
- 他娘的快排
- Hibernate知识点一
- 中华民国
- Hibernate二
- HDU 1061 Rightmost Digit 【快速幂 Or 规律(瞎搞)】
- OpenCV实践(1)-怎样扫描图像、查找表和运行效率的测定
- ACM萌新体验
- Spring配置AOP没有反应
- HDUoj 1022 Train Problem I ( 栈
- Hibernate缓存
- 不跟随手指的小球--OnGestureListener和SCROLLER的使用
- 1034. Head of a Gang (30)