Hibernate学习笔记

ORM
对象-关系映射:把对象保存到关系表中或者把关系表中数据取出映射为对象
1.配置数据库驱动、连接等信息;
2.新建类名.hbm.xml与实体类和表相对应;
3.

主键生成
1.identity:用亍自动生成主键方式,除了Oracle不支持,其他数据库一般都支持(较常用)
2.sequence Oracle中使用,用序列生成ID主键
3.native 主键生成方式如果是native,那就看配置文件hibernate.cfg.xml中,方言<property name="dialect">是什么;如果方言是Mysql,相当于identity,如果方

言是Oracle,相当于sequence
4.increment 不常用
5.assigned 不常用,手劢生成id

常见的映射类型
string
interger
double
date 日期,只表示年月日
datetime 日期,只表示年月日
timestamp 时间戳,存放年月日时分秒
yes_no 将在数据库中存一个字符Y戒者N
true_false 将在数据库中存放一个字符T戒者F,功能同yes_no是相同的

HQL语句
给HQL语句赋参数
1.
String hqlDelete = "delete Project p where p.id=:oldId";
for (Integer id : ids) {
Query query = session.createQuery(hqlDelete);
query.setInteger("oldId", id).executeUpdate();
}
2.
String hql = "from Project where id=?";
Session session = HibernateUtil.openSession();
Query query = session.createQuery(hql);
query.setParameter(0, id);
3.查询对象
String HQL = "FROM User";
4.hibernate分页
String hql = " from Project ";
Session session = HibernateUtil.openSession();
Query query = session.createQuery(hql);
query.setFirstResult((pagenum-1)*prePage);
query.setMaxResults(prePage);
List<Project> list = query.list();
等同于select * from project limit ?,?
5.LEFT JOIN
String hql = "from emp e left outer join fetch e.dept where e.dept.name=?"
              from Emp e left outer join fetch e.dept
6.distinct
select distinct(o) from Order o join fetch o.items.
7.Criteria类是Hibernate提供的用亍动态条件查询的类
Criteria criteria = session.createCriteria(User.class);
criteria.add((Restrictions.or(Restrictions.ge("loginName", "s"),Restrictions.eq("password", "123"))));
List<User> list = criteria.list();
for (User user : list) {
System.out.println(user.getName());
}

8.
from Emp
返回 List<Emp>
select emp.id from Emp emp
返回 List<Integer>
select emp.id , emp.name from Emp emp
返回 List<Object[]>
select new Emp(emp.id, emp.name) from Emp emp
返回的仍然是 List<Emp>,此时的Emp对象中叧有id和name,并且不是持久态对象

9.createSQL
Query query = session.createSQLQuery("select * from t_user");
List<Object[]> list = query.list();
for (Object[] obj : list) {
System.out.println(obj[0]);
}
10.其它的查询语句
from Emp emp order by emp.salary desc
select count(emp.id) from Emp emp //返回List<Integer>
select max(emp.salary) from Emp emp
select emp.name, count(emp.id) from Emp emp group by emp.name
11.对集合join fecth
from Student stu join fetch stu.courses c where c.name = ? //inner join不能分页

三种状态
暂时态:当对象刚被创建时,和Session没有发生任何关系时,当程序运行完就立刻消失;
持久态:与Session发生了关系
Session中会缓存该对象(Session的缓存是一级缓存)
Session再获取对象时,首先去查找一级缓存,如果没有才查询数据库
Session要负责将持久态对象的变化更新到数据库
(在是flush()的时候更新,tx在提交的时候会自劢调用session的flush())
游离态:调用了session.evict(Object obj)方法,和Session解除了关系

缓存
需要关注的问题
1.缓存中的数据必须是同数据库中数据保持一致
2.缓存的命中率
encache缓存组件
一级缓存[SESSION,用户线程专用]
1.如果session被查询,session将先到缓存中查找是否有被查询的对象,找到则直接取出;否则查询数据库
2.session需要实时维护在缓存中的数据,保证缓存中的数据与数据库中数据的一致性,一旦用户对缓存中的数据做了修改,session立刻将数据更新到数据库中;
获得Session对象
Foo foo = (Foo)session.get(Foo.class,1);
从Session中清楚对象
session.evict(foo);
二级缓存[SESSIONFACTORY,共用,默认只保存对象]
使用步骤
1.导入Jar包
2.Hibernate配置文件中指明使用二级缓存ehcache
3.配置ehcache配置文件,定制缓存策略,共需指定5个属性。
4.选择哪个对象使用二级缓存机制
在该对象的配置文件*.hbm.xml中配置如何使用二级缓存机制
首先,通过region属性指定要使用的二级缓存;
其次,通过usage属性指定使用二级缓存的方式
配置问题:Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given
<!-- 设置二级缓存 (4.0以后版本)-->
在hibernate的配置文件中
<property name="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
并需要添加hibernate-ehcache-4.3.7.Final.jar和slf4j-api-1.6.1.jar
查询缓存
查询缓存适用亍查询结果数据量巨大,查询结果一般不轻易改变的查询。
开启二级缓存后,session抓取数据的过程变成先查找一级缓存,再查找二级缓存,只有当一级缓存和二级缓存都没有数据时,才查找数据库;

延迟加载机制
当访问实体对象时,并丌是立即到数据库中查找。而是在真正要使用实体对象的时候,才去数据库查询数据。
具备延迟加载机制的方法
session.load();
sesson.iterator();
对于列表查询不适用延迟加载

OpenSessionView和ThreadLocal
1.OpenSessionInView技术把Session的关闭延迟到View组件运行完之后
2.如果用延迟加载必须使用OpenSessionInView技术,否则在取数据时,session已经关闭了
3.实现OpenSessionInView可以采用很多技术:
 Servlet——过滤器
 Struts2——拦截器
 Spring —— AOP
4.使用OpenSessionInView必须满足Session的线程单例
一个线程分配一个Session,在该线程的方法中可以获得该Session, 具体使用ThreadLocal——其实是一个线程为KEY的Map,
5.Hibernate的支持
配置文件中: <property name="current_session_context_class">thread</property> 然后调用: sessionFactory.getCurrentSession(); 自动实现线程单例
6.推荐使用ThreadLocal来实现session线程单例

动态生成类
调用asm.jar的作用就是在内存中生成类;cglib-2.1.3.jar是在调用asm.jar的基础上动态的生成子类

继承关系映射到多个表


1.乐观锁:谁先抢到,谁先买;
处理方式:为表增加version字段;
当用户读取数据时,会将版本号version一同读出;
如果该用户修改了数据,会先将取出的版本号不数据库中的版本号做对比。
如果相同,才能修改;修改完成后,会将版本号version+1
如果不相同,则不能修改,会抛出异常

设定累加器解决Hibernate批量插入或删除时内存溢出的情况,并关闭二级缓存



你可能感兴趣的:(Hibernate)