Hibernate读后感

hibernate读后总结

马士兵视频

http://www.youku.com/playlist_show/id_3923405_ascending_1_mode_pic_page_4.html

马士兵文档

http://www.cnblogs.com/alamps/archive/2012/05/13/2498332.html

------------------------------------------------------------------------------------------------------------------------------
1.增
在hibernate中对象有3中状态:
1.Transient(刚刚new出来)内存中一个对象,没id,缓存中也没有
2.Persistent 内存中有,缓存中有,数据库有(Id)
3.Detached 内存有,缓存没有,数据库有id
2.删除
删除是根据id来删除的
3.查询
load 并不会执行sql语句。只是返回一个代理对象,只有用到对象时候才会执行sql语句
     不存再对应记录的时候 不会报错
get  立即执行sql语句,不会延迟
    不存在对应记录的时候会报错
    
load的代理对象:


------------------------------------------------------------------------------------------------------------------------------
映射关系:对象之间的关系


1、一对一


单项


双向

2、一对多

单项


     使用注解的时候 要在一的一方使用onetomany,并且还要有@JoinColumn(name="XXXXX")这个属性,不然hibernate会默认创建一张中间表
双向
3、多对一


单项


双向

4、多对多

单项


双向

5.组建映射
表现形式
在数据库表中是一个表结构。在java中是两个类一个中包含一个
比如:用户实体类+用户详细信息实体类
在xml中使用component标签来表示
在注解中使用@embedded(这里和组合主键有点像)


------------------------------------------------------------------------------------------------------------------------------
级联关键词
@ManyToOne(cascade=(CascadeType.ALL))
merge合并
all所有操作
.双向关系在程序中需要设置双相关联
.双向的一定要设定mappedBy
.双向关联最好只在一方设FetchType.EAGER,不然会出现多次加载 相当于 inverse="true"
------------------------------------------------------------------------------------------------------------------------------
hibernate性能优化

1.session.clear() 批量查询的时候来session.clear()

2.1+n问题(如果在一个对象中关联另外一个对象,主要是针对manyToOne的)

解决方法:{
   1.FetchType.Lazy
   2.使用createCriteria(默认是join的)类似于在createQuery(from A a left outer join B b on a.id= b.id)这个也是一种
      注意:也可以说createCriteria使用了join的方式
   3.BatchSize 设置在one


  }


3.List 和 Iterator
表结构如下:

Category 和 Topic


区别一、获取方式不一样

             。List直接把对象全部取出来

             。把主键先取出来,用到对象的时候根据主键从数据库取

List测试代码如下:

@Test
	public void testQueryList() {
		Session session = sf.openSession();
		session.beginTransaction();
		//List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
		List<Category> categories = (List<Category>)session.createQuery("from Category").list();
		
		for(Category c : categories) {
			System.out.println(c.getName());
		}
		session.getTransaction().commit();
		session.close();
		
	}

运行结果:(直接把对象全部取出来)

Hibernate: 
    select
        category0_.id as id0_,
        category0_.name as name0_ 
    from
        Category category0_
c0
c1
c2
c3
c4
c5
c6
c7
c8
c9


Iterator
	@Test
	public void testQueryIterate() {
		Session session = sf.openSession();
		session.beginTransaction();
		//List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
		Iterator<Category> categories = (Iterator<Category>)session.createQuery("from Category").iterate();
		
		
		while(categories.hasNext()) {
			Category c = categories.next();
			System.out.println(c.getName());
		}
		session.getTransaction().commit();
		session.close();
		
	}

运行结果:把主键先取出来,用到对象的时候才从数据库取

Hibernate: 
    select
        category0_.id as col_0_0_ 
    from
        Category category0_
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c0
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c1
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c2
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c3
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c4
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c5
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c6
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c7
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c8
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c9
区别二、
                    。List 没法利用session级的查询缓存 查询第二次仍然会发出sql查询

                    。Iterator利用session级的查询缓存 查询第二次不会发出sql查询

List代码

	@Test
	public void testQueryList() {
		Session session = sf.openSession();
		session.beginTransaction();
		//List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
		List<Category> categories = (List<Category>)session.createQuery("from Category").list();
		
		for(Category c : categories) {
			System.out.println(c.getName());
		}
		
		List<Category> categories2 = (List<Category>)session.createQuery("from Category").list();
		for(Category c : categories2) {
			System.out.println(c.getName());
		}
		session.getTransaction().commit();
		session.close();
		
	}

运行结果:

Hibernate: 
    select
        category0_.id as id0_,
        category0_.name as name0_ 
    from
        Category category0_
c0
c1
c2
c3
c4
c5
c6
c7
c8
c9
Hibernate: 
    select
        category0_.id as id0_,
        category0_.name as name0_ 
    from
        Category category0_
c0
c1
c2
c3
c4
c5
c6
c7
c8
c9

Iterator测试代码

	@Test
	public void testQueryIterate() {
		Session session = sf.openSession();
		session.beginTransaction();
		//List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
		Iterator<Category> categories = (Iterator<Category>)session.createQuery("from Category").iterate();
		
		
		while(categories.hasNext()) {
			Category c = categories.next();
			System.out.println(c.getName());
		}
		
		Iterator<Category> categories2 = (Iterator<Category>)session.createQuery("from Category").iterate();
		
		while(categories2.hasNext()) {
			Category c = categories2.next();
			System.out.println(c.getName());
		}
		session.getTransaction().commit();
		session.close();
		
	}
运行结果

Hibernate: 
    select
        category0_.id as col_0_0_ 
    from
        Category category0_
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c0
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c1
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c2
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c3
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c4
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c5
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c6
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c7
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c8
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c9
Hibernate: 
    select
        category0_.id as col_0_0_ 
    from
        Category category0_
c0
c1
c2
c3
c4
c5
c6
c7
c8
c9

注意:第一次使用list,第二次使用Iterator,也可以使用缓存


4.hibernate缓存

什么是缓存?

介于客户端和数据源之间,源于数据源,快速给客户端提供数据的数据源

缓存的算法:(缓存算法定义:内存中缓存满了之后怎么处理?)

A、最近不用的 

B、使用最少的

C、最早进入的

cpu闪存 > 内存 > 硬盘 > 数据库

A、一级缓存

     session级别的缓存

	@Test
	public void testCache1() {
		Session session = sf.openSession();
		session.beginTransaction();
		Category c = (Category)session.load(Category.class, 1);
		System.out.println(c.getName());
		
		Category c2 = (Category)session.load(Category.class, 1);
		System.out.println(c2.getName());
		session.getTransaction().commit();
		session.close();
		
	}
运行结果:
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c0
c0
一级缓存只在session范围内,如果在其他session中如下:这样就不能从缓存中查询,这样就需要使用二级缓存

@Test
	public void testCache2() {
		Session session = sf.openSession();
		session.beginTransaction();
		Category c = (Category)session.load(Category.class, 1);
		System.out.println(c.getName());
		
		
		session.getTransaction().commit();
		session.close();
		
		Session session2 = sf.openSession();
		session2.beginTransaction();
		Category c2 = (Category)session2.load(Category.class, 1);
		System.out.println(c2.getName());
		
		
		session2.getTransaction().commit();
		session2.close();
	}


B、二级缓存

sessionFactory级别的缓存,对session来说是公用的

使用条件:

1、经常访问

2、改动不频繁

3、数量有限


使用

1、加注解 @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

2、增加配置

<!-- 开关 -->
        <property name="cache.use_second_level_cache">true</property>
        <!-- 使用二级缓存的类别 -->
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 
<property name="cache.use_query_cache">true</property> -->

3、ehcache配置xml

4、添加ehcache.jar


      默认情况下load、iterator会使用二级缓存

     默认情况下List查询出来的数据 会加载到二级缓存中,但是查询的时候不使用二级缓存

C、三级缓存(查询缓存) 依赖与二级缓存

重复的查询(相同的sql语句)会使用查询缓存

使用

在配置文件中打开查询缓存

<property name="cache.use_query_cache">true</property> 

	//join fetch
	@Test
	public void testQueryCache() {
		Session session = sf.openSession();
		session.beginTransaction();
		List<Category> categories = (List<Category>)session.createQuery("from Category")
									.setCacheable(true).list();

		session.getTransaction().commit();
		session.close();
		
		Session session2 = sf.openSession();
		session2.beginTransaction();
		List<Category> categories2 = (List<Category>)session2.createQuery("from Category")
		.setCacheable(true).list();
		
		session2.getTransaction().commit();
		session2.close();
	}

5、事务并发处理

事物特性:ACID

原子性(Atomicity)、

一致性(Consistency)、

隔离性(Isolation)、

持久性(Durability)


事物并发出现的问题:

A、丢失更新(一般数据库【支持事务】都有这块的处理)

B、脏读(读了另外一个事务没提交的数据)

C、不可重复读(同一个事务读了两次,两次数据都不一样)

D、幻读(两次查询不一样) 一般不考虑

处理事务并发---------》


数据库事务隔离级别:

A、read-uncommitted 允许读取没提交的数据    代码:1

B、read-committed 读取提交的数据 代码:2

C、repeatable read 不可重复读(MySql默认的事务隔离级别) 代码:4

D、serial 禁止事务并发(一般适用数据库调优) 代码: 8

hibernate处理事务并发

1、hibernate事务级别设定

hibernate.connection.isolation=2  不设置的话 默认为数据库设定值

可以解决赃读、丢失更新

2、使用悲观锁,乐观锁

悲观锁,乐观锁 解决repeatable read的问题【还是依赖数据库本身机制】

A、悲观锁

借助数据库的锁,在数据库中给要读取的数据设定一把锁.load(XXX.class,LockMode.UPGRADE) 

生成的sql语句中多一个【for update】

B、乐观锁

查询的时候给字段设定一个标识版本字段,每改动一次版本号改动一次

做法

在实体类上添加字段:

        private int version;
	@Version
	public int getVersion() {
		return version;
	}
	public void setVersion(int version) {
		this.version = version;
	}














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值