码迷,mamicode.com
首页 > Web开发 > 详细

Hibernate的学习详解(1)

时间:2015-09-15 12:45:27      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:

    ORM(对象关系映射):将关系数据库中表中的记录映射成为对象,以对象的形式展现.

          
  流行的ORM框架:
 
           Hibernate:
                                                          
               非常优秀、成熟的 ORM 框架。                                            
               完成对象的持久化操作                                                                                        
               Hibernate 允许开发者采用面向对象的方式来操作关系数据库。
               消除那些针对特定数据库厂商的 SQL 代码.
              
          myBatis:
          
               相比 Hibernate 灵活高,运行速度快                                
               开发速度慢,不支持纯粹的面向对象操作,需熟悉sql语句,并且熟练使用sql语句优化功能
               
               
          TopLink
          
          OJB    

     hibernate的环境搭建:
    
             首先hibernate插件:hibernatetools-4.1.1.Final
             
             hibernate所需的jar包:

                                            技术分享

 

      开发步骤:

                 1.创建hibernate配置文件;

                 2.创建持久化类;

                 3.创建对象关系映射文件;

                 4.通过API编写访问数据库的代码;

    创建hibernate的配置文件:

 

                     

 1      <!-- Hibernate 连接数据库的基本信息 -->
 2         <property name="connection.username">root</property>
 3         <property name="connection.password">1230</property>
 4         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 5         <property    name="connection.url">jdbc:mysql:///hibernate5</property>
 6 
 7         <!-- Hibernate 的基本配置 -->
 8         <!-- Hibernate 使用的数据库方言 -->
 9         <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
10     
11         <!-- 运行时是否打印 SQL -->
12         <property name="show_sql">true</property>
13     
14         <!-- 运行时是否格式化 SQL -->
15         <property name="format_sql">true</property>
16     
17         <!-- 生成数据表的策略 -->
18         <property name="hbm2ddl.auto">update</property>
19         
20         <!-- 设置 Hibernate 的事务隔离级别 -->
21         <property name="connection.isolation">2</property>
22         
23         <!-- 删除对象后, 使其 OID 置为 null -->
24         <property name="use_identifier_rollback">true</property>
25         
26         <!-- 配置 C3P0 数据源 -->
27         <property name="hibernate.c3p0.max_size">10</property>
28         <property name="hibernate.c3p0.min_size">5</property>
29         <property name="c3p0.acquire_increment">2</property>
30         
31         <property name="c3p0.idle_test_period">2000</property>
32         <property name="c3p0.timeout">2000</property>
33         
34         <property name="c3p0.max_statements">10</property>
35         
36         <!-- 设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数 -->
37         <property name="hibernate.jdbc.fetch_size">100</property>
38         
39         <!-- 设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小 -->
40         <property name="jdbc.batch_size">30</property>

 

              持久化类的注意事项                                   

                                      •提供一个无参的构造器:使Hibernate可以使用Constructor.newInstance() 来实例化持久化类                                                
                                      •提供一个标识属性(identifier property): 通常映射为数据库表的主键字段. 如果没有该属性,一些功能将不起作用,如:Session.saveOrUpdate()
                                      •为类的持久化类字段声明访问方法(get/set): Hibernate对JavaBeans 风格的属性实行持久化。
                                      •使用非 final 类: 在运行时生成代理是 Hibernate 的一个重要的功能. 如果持久化类没有实现任何接口, Hibnernate 使用 CGLIB 生成代理. 如果使用的是 final 类, 则无法生成 CGLIB 代理.
                                      •重写 eqauls 和 hashCode 方法: 如果需要把持久化类的实例放到 Set 中(当需要进行关联映射时), 则应该重写这两个方法
 
 
            首先要了解configuration类的信息:                      
                           Configuration 类负责管理 Hibernate 的配置信息                                                                         
                           Hibernate 运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数据库Dialect,数据库连接池等(对应 hibernate.cfg.xml 文件)
                           持久化类与数据表的映射关系(*.hbm.xml 文件)
                         
                          •创建 Configuration 的两种方式
                                         属性文件(hibernate.properties):
                                                        Configuration cfg = new Configuration();
                                        Xml文件(hibernate.cfg.xml)
                                                         Configuration cfg = new Configuration().configure();
                                        Configuration 的 configure 方法还支持带参数的访问:
                                                          File file = new File(“simpleit.xml”);
                                                         Configuration cfg = new Configuration().configure(file);
 
      Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。此对象的生命周期很短。Session 对象有一个一级缓存,显式执行 flush 之前,所有的 持久层操作的数据都缓存在 session 对象处。相当于 JDBC 中的 Connection
 
     Transaction:

                                   Transaction tx = session.beginTransaction();

               常用方法:
                                   commit():提交相关联的session实例
                                   rollback():撤销事务操作
                                   wasCommitted():检查事务是否提交
 
      Hibernate 配置文件的两个配置项:
 
                hbm2ddl.auto:自动生成表                              
                             –create : 会根据 .hbm.xml  文件来生成数据表, 但是每次运行都会删除上一次的表 ,重新生成表, 哪怕二次没有任何改变
                             –create-drop : 会根据 .hbm.xml 文件生成表,但是SessionFactory一关闭, 表就自动删除
                             –update : 最常用的属性值,也会根据 .hbm.xml 文件生成表, 但若 .hbm.xml  文件和数据库中对应的数据表的表结构不同, Hiberante  将更新数据表结构,但不会删除已有的行和列
                             –validate : 会和数据库中的表进行比较, 若 .hbm.xml 文件中的列在数据表中不存在,则抛出异常
 
            
           format_sql:是否将 SQL 转化为格式良好的 SQL . 取值 true | false
 
 
      Hibernate 把对象分为 4 种状态: 持久化状态, 临时状态, 游离状态, 删除状态. Session 的特定方法能使对象从一个状态转换到另一个状态.、
 
                               技术分享
 
         技术分享
 
 
    
  1 @Before
  2     public void init(){
  3         Configuration configuration = new Configuration().configure();
  4         ServiceRegistry serviceRegistry = 
  5                 new ServiceRegistryBuilder().applySettings(configuration.getProperties())
  6                                             .buildServiceRegistry();
  7         sessionFactory = configuration.buildSessionFactory(serviceRegistry);
  8         
  9         session = sessionFactory.openSession();
 10         transaction = session.beginTransaction();
 11     }
 12 
 13 
 14 @After
 15     public void destroy(){
 16         transaction.commit();
 17         session.close();
 18         sessionFactory.close();
 19     }
 20 
 21 /**
 22      * flush: 使数据表中的记录和 Session 缓存中的对象的状态保持一致. 为了保持一致, 则可能会发送对应的 SQL 语句.
 23      * 1. 在 Transaction 的 commit() 方法中: 先调用 session 的 flush 方法, 再提交事务
 24      * 2. flush() 方法会可能会发送 SQL 语句, 但不会提交事务. 
 25      * 3. 注意: 在未提交事务或显式的调用 session.flush() 方法之前, 也有可能会进行 flush() 操作.
 26      * 1). 执行 HQL 或 QBC 查询, 会先进行 flush() 操作, 以得到数据表的最新的记录
 27      * 2). 若记录的 ID 是由底层数据库使用自增的方式生成的, 则在调用 save() 方法时, 就会立即发送 INSERT 语句. 
 28      * 因为 save 方法后, 必须保证对象的 ID 是存在的!
 29      */
 30     @Test
 31     public void testSessionFlush2(){
 32         News news = new News("Java", "SUN", new Date());
 33         session.save(news);
 34     }
 35 
 36 /**
 37      * refresh(): 会强制发送 SELECT 语句, 以使 Session 缓存中对象的状态和数据表中对应的记录保持一致!
 38      */
 39     @Test
 40     public void testRefresh(){
 41         News news = (News) session.get(News.class, 1);
 42         System.out.println(news);
 43         
 44         session.refresh(news); 
 45         System.out.println(news); 
 46     }
 47 
 48 /**
 49      * clear(): 清理缓存
 50      */
 51     @Test
 52     public void testClear(){
 53         News news1 = (News) session.get(News.class, 1);
 54         
 55         session.clear();
 56         
 57         News news2 = (News) session.get(News.class, 1);
 58     }
 59 
 60 /**
 61      * 1. save() 方法
 62      * 1). 使一个临时对象变为持久化对象
 63      * 2). 为对象分配 ID.
 64      * 3). 在 flush 缓存时会发送一条 INSERT 语句.
 65      * 4). 在 save 方法之前的 id 是无效的
 66      * 5). 持久化对象的 ID 是不能被修改的!
 67      */
 68     @Test
 69     public void testSave(){
 70         News news = new News();
 71         news.setTitle("CC");
 72         news.setAuthor("cc");
 73         news.setDate(new Date());
 74         news.setId(100); 
 75         
 76         System.out.println(news);
 77         
 78         session.save(news);
 79 
 80         System.out.println(news);
 81 //        news.setId(101); 
 82     }
 83 
 84 
 85     /**
 86      * persist(): 也会执行 INSERT 操作
 87      * 
 88      * 和 save() 的区别 : 
 89      * 在调用 persist 方法之前, 若对象已经有 id 了, 则不会执行 INSERT, 而抛出异常
 90      */
 91     @Test
 92     public void testPersist(){
 93         News news = new News();
 94         news.setTitle("EE");
 95         news.setAuthor("ee");
 96         news.setDate(new Date());
 97         news.setId(200); 
 98         
 99         session.persist(news); 
100     }
101 
102 /**
103      * get VS load:
104      * 
105      * 1. 执行 get 方法: 会立即加载对象. 
106      *    执行 load 方法, 若不适用该对象, 则不会立即执行查询操作, 而返回一个代理对象
107      *    
108      *    get 是 立即检索, load 是延迟检索. 
109      * 
110      * 2. load 方法可能会抛出 LazyInitializationException 异常: 在需要初始化
111      * 代理对象之前已经关闭了 Session
112      * 
113      * 3. 若数据表中没有对应的记录, Session 也没有被关闭.  
114      *    get 返回 null
115      *    load 若不使用该对象的任何属性, 没问题; 若需要初始化了, 抛出异常.  
116      */
117     @Test
118     public void testLoad(){
119         
120         News news = (News) session.load(News.class, 10);
121         System.out.println(news.getClass().getName()); 
122         
123 //        session.close();
124 //        System.out.println(news); 
125     }
126 
127 /**
128      * update:
129      * 1. 若更新一个持久化对象, 不需要显示的调用 update 方法. 因为在调用 Transaction
130      * 的 commit() 方法时, 会先执行 session 的 flush 方法.
131      * 2. 更新一个游离对象, 需要显式的调用 session 的 update 方法. 可以把一个游离对象
132      * 变为持久化对象
133      * 
134      * 需要注意的:
135      * 1. 无论要更新的游离对象和数据表的记录是否一致, 都会发送 UPDATE 语句. 
136      *    如何能让 updat 方法不再盲目的出发 update 语句呢 ? 在 .hbm.xml 文件的 class 节点设置
137      *    select-before-update=true (默认为 false). 但通常不需要设置该属性. 
138      * 
139      * 2. 若数据表中没有对应的记录, 但还调用了 update 方法, 会抛出异常
140      * 
141      * 3. 当 update() 方法关联一个游离对象时, 
142      * 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常. 因为在 Session 缓存中
143      * 不能有两个 OID 相同的对象!
144      *    
145      */
146     @Test
147     public void testUpdate(){
148         News news = (News) session.get(News.class, 1);
149         
150         transaction.commit();
151         session.close();
152         
153 //        news.setId(100);
154 
155         session = sessionFactory.openSession();
156         transaction = session.beginTransaction();
157         
158 //        news.setAuthor("SUN"); 
159         
160         News news2 = (News) session.get(News.class, 1);
161         session.update(news);
162     }
163 
164 /**
165      * 注意:
166      * 1. 若 OID 不为 null, 但数据表中还没有和其对应的记录. 会抛出一个异常. 
167      * 2. 了解: OID 值等于 id 的 unsaved-value 属性值的对象, 也被认为是一个游离对象
168      */
169     @Test
170     public void testSaveOrUpdate(){
171         News news = new News("FFF", "fff", new Date());
172         news.setId(11);
173         
174         session.saveOrUpdate(news); 
175     }
176 /**
177      * delete: 执行删除操作. 只要 OID 和数据表中一条记录对应, 就会准备执行 delete 操作
178      * 若 OID 在数据表中没有对应的记录, 则抛出异常
179      * 
180      * 可以通过设置 hibernate 配置文件 hibernate.use_identifier_rollback 为 true,
181      * 使删除对象后, 把其 OID 置为  null
182      */
183     @Test
184     public void testDelete(){
185 //        News news = new News();
186 //        news.setId(11);
187         
188         News news = (News) session.get(News.class, 163840);
189         session.delete(news); 
190         
191         System.out.println(news);
192     }
193 
194 /**
195      * evict: 从 session 缓存中把指定的持久化对象移除
196      */
197     @Test
198     public void testEvict(){
199         News news1 = (News) session.get(News.class, 1);
200         News news2 = (News) session.get(News.class, 2);
201         
202         news1.setTitle("AA");
203         news2.setTitle("BB");
204         
205         session.evict(news1); 
206     }
207     @Test //大数据
208     public void testBlob() throws Exception{
209 //        News news = new News();
210 //        news.setAuthor("cc");
211 //        news.setContent("CONTENT");
212 //        news.setDate(new Date());
213 //        news.setDesc("DESC");
214 //        news.setTitle("CC");
215 //        
216 //        InputStream stream = new FileInputStream("Hydrangeas.jpg");
217 //        Blob image = Hibernate.getLobCreator(session)
218 //                              .createBlob(stream, stream.available());
219 //        news.setImage(image);
220 //        
221 //        session.save(news);
222         
223         News news = (News) session.get(News.class, 1);
224         Blob image = news.getImage();
225         
226         InputStream in = image.getBinaryStream();
227         System.out.println(in.available()); 
228     }

 

 

       技术分享

                         
 
  
                

 

 

 

  

 

 

 

 

   

 

 

        

                                        

      

 

 

    

Hibernate的学习详解(1)

标签:

原文地址:http://www.cnblogs.com/liuqing-bk/p/4809593.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!