Hibernate 03 - Hibernate 之 延时加载 以及 ID 生成策略

原文出处:http://www.cnblogs.com/rhythmK/p/3703112.html

Hibernate 加载数据 有get,跟Load  

1、懒加载:

      使用session.load(type,id)获取对象,并不读取数据库,只有在使用返回对象值才正真去查询数据库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
    public  void   test1()
    {
        Session session =  null ;
         try  {
             session = HibernateUtil.getSessionFactory().openSession();
             User user=(User)session.load(User. class 130 );
             user.getUserId();
             //  懒加载此时并不查询数据库
             System.out.println( "开始读取数据库..." );
             user.getName();
             
         catch  (Exception e) {
             e.printStackTrace();
         finally  {
             if  (session !=  null )
                 session.close();
 
         }
    }

 1.1、 当调用load方法时候,如果数据库不存在对应数据则抛出异常:

      输出: 

开始读取数据库...


Hibernate: select user0_.userId as userId1_0_0_, user0_.openId as openId2_0_0_, user0_.type as type3_0_0_, user0_.name as name4_0_0_, user0_.createTime as createTi5_0_0_ from user user0_ where user0_.userId=?
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.rhythmk.model.User#130]

at org.hibernate.internal.SessionFactoryImpl$1$1.handleEntityNotFound(SessionFactoryImpl.java:253)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:262)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at com.rhythmk.model.User_$$_jvst247_0.getName(User_$$_jvst247_0.java)

....

1.2 、当调用load 方法时候 如果数据库存在此对象,执行上面代码user.getUserId()并非直接从数据库中读取,只有在使用非主键属性才读取数据库  ,从上面程序输出即可看出此特征。

1.3、 当调用延时加载返回的对象,因session回话已经关闭 ,此时则抛出异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Test
  public  void   test2()
  {
       User user=getUser( 13 );
       try  {
           user.getName();
       catch  (Exception e) {
           e.printStackTrace();
       }
       
  }
   
  public  static  User getUser(Integer id) {
       Session session =  null ;
       User user =  null ;
       try  {
           session = HibernateUtil.getSessionFactory().openSession();
           user = (User) session.load(User. class , id);
 
       catch  (Exception e) {
           e.printStackTrace();
       finally  {
           if  (session !=  null )
               session.close();
       }
       return  user;
   }

  输出:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at com.rhythmk.model.User_$$_jvstc5f_0.getName(User_$$_jvstc5f_0.java)

 

2、Get获取数据

        调用get方法直接读取数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
        public  void   test3()
        {
            Session session =  null ;
             try  {
                 session = HibernateUtil.getSessionFactory().openSession();
                 User user=(User)session.get(User. class 13 );
                 System.out.println( "开始读取数据库..." );
                 user.getUserId();
                 //  懒加载此时并不查询数据库
             
                 user.getName();
                 
             catch  (Exception e) {
                 e.printStackTrace();
             finally  {
                 if  (session !=  null )
                     session.close();
             }
        }

  输出:

Hibernate: select user0_.userId as userId1_0_0_, user0_.openId as openId2_0_0_, user0_.type as type3_0_0_, user0_.name as name4_0_0_, user0_.createTime as createTi5_0_0_ from user user0_ where user0_.userId=?
开始读取数据库...

 

 

 

---------------- ID 生成策略-------------

参考表映射XML配置如下:

<id name="实体类属性名" type="java.lang.Integer"> 
      <column name="对应表中主键字段名" /> 
      <generator class="assiged|increment|identity|native|........" /> 
</id> 

1:assigned 
----表示在新增数据时由应用程序指定主键的值。主要针对主键是采用自然主键的形式。这种方式,适用于主键列不是自动增长列。 
其缺点为在执行新增操作时,需查询数据库判断生成的主键是否已经存在。

2:increment 
----表示新增数据操作时由hibernate自动生成主键值。其生成的值为:先查询该主键列的最大值,然后在最大值的基础上加上1.适用于采用代理主键形式的主键列。同样不能用于主键列是自动增长的表。但是,该主键生成策略也有些缺点。 
(1)新增数据前先查询一遍,影响了性能。 
(2)主键的类型只能为数值型的int或者long 
(3)并发操作时的冲突问题。

3:identity 
----不如说是为sqlerver数据库量身定做的。主要适用于sqlserver数据库的自动增长列的表。

4:native 
----表示根据不同的数据库采用不同的主键生成策略。比如,当前数据库为sqlserver,则会采用identity,如为oracle,则采用 
   oracle中的sequence等。区分数据库的不同是以hibernate主配置文件中sessionFactory中配置的数据库方言。 

5.uuid 
   * 唯一主键生成办法。从Hibernate中提取出来 
   优点:避免了生成ID 时,与数据库的再次交道,性能上较高。但对于有的开发人员不太习惯这种id生成方式,UUID生成的32为的字符串,不同于identity 从1开始的整数。 

 

 通常情况下,用的比较多的是代理主键的形式。而且,我们习惯于于让该主键字段能够自动增长,来保证其唯一性。但是,不同的数据库自动增长的方式并不是相同的。如在SQLSERVER中,用identity,MYSQL中,有increment,ORACLE中通常采用sequence。

 

一只站在树上的鸟儿,从来不会害怕树枝会断裂,因为它相信的不是树枝,而是它自己的翅膀。与其每天担心未来,不如努力做好现在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值