(一)Hibernate之基础

有关Spring的知识大部分都已经温习完毕,今天开始转向Hibernate的温习工作了

必须包hibernate-distribution-3.5.3-Final\hibernate3.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

首先在hibernate资源包中找到:hibernate-distribution-3.5.3-Final\project\tutorials\web\src\main\resources\hibernate.cfg.xml将这个配置文件复制到你的项目SRC目录下,然后根据实际情况进行适当修改,我的示例中修改后为


Xml代码  收藏代码
  1. <span style="font-size: large;"><span style="font-size: large;"><?xml version="1.0" encoding="utf-8" ?>  
  2. <!DOCTYPE hibernate-configuration PUBLIC  
  3.     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  5. <hibernate-configuration>  
  6.     <session-factory>  
  7.       <!--数据库连接设置-->  
  8.         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
  9.         <property name="connection.url">jdbc:mysql:///test</property>  
  10.         <property name="connection.username">root</property>  
  11.         <property name="connection.password">root</property>  
  12.   
  13.         <!--JDBC连接池大小-->  
  14.         <property name="connection.pool_size">2</property>  
  15.         <!-- 数据库语言 -->  
  16.         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  
  17.         <!-- Hibernate当前的会话上下文 -->  
  18.         <property name="current_session_context_class">org.hibernate.context.ManagedSessionContext</property>  
  19.         <!-- 禁用二级缓存 -->  
  20.         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>  
  21.         <!-- 控制台显示SQL语句 -->  
  22.         <property name="show_sql">true</property>  
  23.        <!-- 格式化SQL语句 -->  
  24.         <property name="hibernate.format_sql">true</property>  
  25.   
  26.     <!--  
  27.         启动时删数据库中的表,然后创建,退出时不删除数据表   
  28.         <property name="hbm2ddl.auto">create</property>  
  29.     -->  
  30.     <!--  
  31.         启动时删数据库中的表,然后创建,退出时自动删除所有表   
  32.         <property name="hbm2ddl.auto">create-drop</property>  
  33.     -->  
  34.     <!--  
  35.         自动修改,如果表结构与实体类不一致,那么就更新表结构,数据会保留  
  36.         (如果原表不存在,就创建新表;如果缺少相应的字段,就加入;对于原来存在的多余字段,不作处理)  
  37.         <property name="hbm2ddl.auto">update</property>  
  38.     -->  
  39.     <!--  
  40.         自动校验,如果表结构与实体类不一致,那么不做任何操作,报错  
  41.          <property name="hbm2ddl.auto">validate</property>  
  42.     -->  
  43.          <!-- Drop and re-create the database schema on startup -->  
  44.         <property name="hbm2ddl.auto">create</property>  
  45.   
  46.         <!-- 实体关系映射文件 -->  
  47.         <mapping resource="com/javacrazyer/domain/Student.hbm.xml"/>  
  48.     </session-factory>  
  49. </hibernate-configuration></span></span>  


 数据库方言一定要设定对,跟数据库驱动匹配org.hibernate.dialect.MySQLDialect

 否则的话就会出现下面这个错误


Java代码  收藏代码
  1. <span style="font-size: large;"><span style="font-size: large;">Unknown table 'system_sequences' in information_schema</span></span>  


 其次,看看实体类Student.java


Java代码  收藏代码
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.domain;  
  2.   
  3. import java.util.Date;  
  4.   
  5. /** 
  6.  * 学生实体类 --> 按JavaBean的形式定义 
  7.  *  
  8.  */  
  9. public class Student {  
  10.     private int id;  //OID 对象标识符  
  11.     private String name;  
  12.     private int age;  
  13.     private boolean gender;  
  14.     private Date birthday;  
  15.     private double score;  
  16.       
  17.     public int getId() {  
  18.         return id;  
  19.     }  
  20.     public void setId(int id) {  
  21.         this.id = id;  
  22.     }  
  23.     public String getName() {  
  24.         return name;  
  25.     }  
  26.     public void setName(String name) {  
  27.         this.name = name;  
  28.     }  
  29.     public int getAge() {  
  30.         return age;  
  31.     }  
  32.     public void setAge(int age) {  
  33.         this.age = age;  
  34.     }  
  35.     public boolean isGender() {  
  36.         return gender;  
  37.     }  
  38.     public void setGender(boolean gender) {  
  39.         this.gender = gender;  
  40.     }  
  41.     public Date getBirthday() {  
  42.         return birthday;  
  43.     }  
  44.     public void setBirthday(Date birthday) {  
  45.         this.birthday = birthday;  
  46.     }  
  47.     public double getScore() {  
  48.         return score;  
  49.     }  
  50.     public void setScore(double score) {  
  51.         this.score = score;  
  52.     }  
  53.       
  54.     @Override  
  55.     public String toString(){  
  56.         return "id=" + id + ",name=" + name + ",gender=" + gender + ",age=" + age  
  57.         + ",birthday=" + this.birthday + ",score=" + score;  
  58.     }  
  59.       
  60. }</span></span>  


 实体关系映射文件Student.hbm.xml,具体内容也可以参照hibernate资源包下:

hibernate-distribution-3.5.3Final\project\tutorials\web\src\main\resources\org\hibernate\tutorial\

domain\Person.hbm.xml

那么进行修改后的内容为


Xml代码  收藏代码
  1. <span style="font-size: large;"><span style="font-size: large;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  3. <hibernate-mapping>  
  4.     <class name="com.javacrazyer.domain.Student" table="student">  
  5.         <id name="id" column="id">  
  6.             <generator class="native"/>  
  7.         </id>  
  8.         <property name="name" column="name"/>  
  9.         <property name="age"/>  
  10.         <property name="gender"/>  
  11.         <property name="birthday"/>  
  12.         <property name="score"/>  
  13.     </class>  
  14. </hibernate-mapping></span></span>  


 现在介绍下hbm.xml映射文件中各种属性的介绍吧

1.class 节点
name: 类名

table: 类对应表名,默认为类名称

dynamic-update: 生成更新字段时,只包含发生变动的字段,默认为false。

dynamic-insert: 生成insert语句时仅包含非null字段

Proxy: 代理类,默认为空

discriminator-value: 子类辨别标识用于多态支持

where: 通过限定条件查询结果集。如:查询有籍在校学生的信息可以使用"where studentstatus='0'"

2.id节点
1.column                字段名称
2.type                  字段类型
3.length                字段长度
4.unsaved-value         用于判断对象值是否已经保存
5.generator-class       主键产生方式
                        assigned
                        hilo
                        seqhilo
                        increment
                        identity
                        sequence
                        native
                        uuid.hex
                        uuid.string
                        foreign

---------------------------------------------------------------------------------------------------------------
主键产生方式说明

increment(递增) 
用于为long, short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。

identity 
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是long, short 或者int类型的。

sequence (序列) 
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。

hilo (高低位) 
使用一个高/低位算法来高效的生成long, short或者 int类型的标识符。给定一个表和字段(默认分别是是hibernate_unique_key 和next_hi)作为高位值得来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。在使用JTA获得的连接或者用户自行提供的连接中,不要 使用这种生成器。

seqhilo(使用序列的高低位) 
使用一个高/低位算法来高效的生成long, short或者 int类型的标识符,给定一个数据库序列(sequence)的名字。

uuid.hex 
用一个128-bit的UUID算法生成字符串类型的标识符。在一个网络中唯一(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。

uuid.string 
使用同样的UUID算法。UUID被编码为一个16个字符长的任意ASCII字符组成的字符串。不能使用在PostgreSQL数据库中

native(本地) 
根据底层数据库的能力选择identity, sequence 或者hilo中的一个。

assigned(程序设置) 
让应用程序在save()之前为对象分配一个标示符。

foreign(外部引用)

-------------------------------------------------------------------------------------------------------------------------

3.property 节点
1.column                数据库表字段名称
2.type                  类型
3.length                长度
4.not-null              字段是否允许为空
5.unique                字段是否允许唯一(是否允许重复值)
6.insert                insert操作时,是否允许包含本字段数值
7.update                update操作时,是否包含本字段数据



特别说明

现在有个问题,按平常思路就是,得在数据库中创建一个student表吧,字段及类型得与Student类吻合,其实不用,为什么这么说,因为在hibernate.cfg.xml中 <property name="hibernate.hbm2ddl.auto">update</property>这句话配置的值为update就表示没有表的情况下会在执行数据库操作前自动创建数据库表,这下就省了好多事了



不过,如果你非要手工去创建,写SQL语句在数据库工具中也没必要,hibernate有相应的API支持你生成对应的数据库表

下面这个类就就可以

创建数据库表的类DBScriptExport .Java



Java代码  收藏代码
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.common;  
  2.   
  3. import org.hibernate.cfg.Configuration;  
  4. import org.hibernate.tool.hbm2ddl.SchemaExport;  
  5.   
  6. /** 
  7.  * 根据对象关系映射文件直接生成数据库表或生成建表的脚本 
  8.  *  
  9.  */  
  10. public class DBScriptExport {  
  11.   
  12.     public static void main(String[] args) {  
  13.         export2File("dbcript.sql");  
  14.     }  
  15.       
  16.     public static void export2DB(){  
  17.         //加载Hibernate的全局配置文件  
  18.         Configuration config = new Configuration().configure();  
  19.         SchemaExport export = new SchemaExport(config);  
  20.         export.create(truetrue);  
  21.     }  
  22.       
  23.     public static void export2File(String dest){  
  24.         Configuration config = new Configuration().configure();  
  25.         SchemaExport export = new SchemaExport(config);  
  26.           
  27.         export.setOutputFile(dest)  
  28.             .setDelimiter(";")  
  29.             .setFormat(true)  
  30.             .create(truefalse);  
  31.     }  
  32.   
  33. }  
  34. </span></span>  

 

获取session的HibernateUtil.java


Java代码  收藏代码
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.common;  
  2.   
  3. import org.hibernate.Session;  
  4. import org.hibernate.SessionFactory;  
  5. import org.hibernate.cfg.Configuration;  
  6.   
  7. /** 
  8.  * Hibernate工具类 
  9.  *  
  10.  */  
  11. public class HibernateUtil {  
  12.     private static final SessionFactory factory;  
  13.       
  14.     private HibernateUtil(){}  
  15.       
  16.     static{  
  17.         //加载Hibernate全局配置文件,根据配置信息创建SessionFactory工厂实例  
  18.         factory = new Configuration().configure().buildSessionFactory();  
  19.     }  
  20.       
  21.     public static SessionFactory getSessionFactory(){  
  22.         return factory;  
  23.     }  
  24.       
  25.     public static Session getSession(){  
  26.         return factory.openSession();  
  27.     }  
  28. }  
  29. </span></span>  

 最后的测试类HibernateTest.java


Java代码  收藏代码
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.test;  
  2.   
  3. import java.util.Date;  
  4. import java.util.List;  
  5.   
  6. import org.hibernate.Criteria;  
  7. import org.hibernate.HibernateException;  
  8. import org.hibernate.Query;  
  9. import org.hibernate.Session;  
  10. import org.hibernate.Transaction;  
  11. import org.hibernate.criterion.Order;  
  12. import org.junit.Assert;  
  13. import org.junit.Test;  
  14.   
  15. import com.javacrazyer.common.HibernateUtil;  
  16. import com.javacrazyer.domain.Student;  
  17.   
  18. /** 
  19.  * 使用Hibernate API完成CRUD 
  20.  * 更复杂的持久化操作需要使用到Query接口 
  21.  *  
  22.  */  
  23. public class HibernateTest {  
  24.       
  25.     @Test  
  26.     public void testAdd(){  
  27.         Student stu = new Student();  
  28.         stu.setName("test");  
  29.         stu.setBirthday(new Date());  
  30.         stu.setAge(1);  
  31.         stu.setGender(true);  
  32.         stu.setScore(66.8);  
  33.           
  34.         //利用工厂打开一个Session实例  
  35.         Session session = HibernateUtil.getSession();  
  36.           
  37.         //开启一个操作事务  
  38.         Transaction tx = session.beginTransaction();  
  39.           
  40.         //利用session进行持久化操作  
  41.         session.save(stu);  
  42.           
  43.         //提交事务  
  44.         tx.commit();  
  45.           
  46.         //关闭Session  
  47.         session.close();  
  48.     }  
  49.       
  50.     @Test  
  51.     public void getStu(){  
  52.           
  53.         //持久化管理器  
  54.         Session session = null;  
  55.         Transaction tx = null;  
  56.         try{  
  57.             session = HibernateUtil.getSession();  
  58.           
  59.             tx = session.beginTransaction();  
  60.           
  61.             //根据ID查询实体对象  
  62.             Student stu = (Student)session.get(Student.class1);  
  63.               
  64.             Assert.assertNotNull(stu);  
  65.             System.out.println(stu);  
  66.           
  67.             tx.commit();  
  68.         }catch(HibernateException he){  
  69.             he.printStackTrace();  
  70.             tx.rollback();  
  71.         }finally{  
  72.             if(null != session && session.isOpen()){  
  73.                 try{  
  74.                     session.close();  
  75.                 }catch(HibernateException e){  
  76.                     e.printStackTrace();  
  77.                 }  
  78.             }  
  79.         }  
  80.     }  
  81.       
  82.     @Test  
  83.     public void testUpdate(){  
  84.         Session session = null;  
  85.           
  86.         try{  
  87.             session = HibernateUtil.getSession();  
  88.               
  89.             session.beginTransaction();  
  90.               
  91.             Student stu = (Student)session.get(Student.class1);  
  92.             stu.setName("zs");  
  93.             stu.setScore(52.1);  
  94.           
  95.             session.update(stu);  
  96.               
  97.             session.getTransaction().commit();  
  98.         }catch(HibernateException e){  
  99.             Assert.fail();  
  100.             e.printStackTrace();  
  101.             session.getTransaction().rollback();  
  102.         }finally{  
  103.             if(session != null && session.isOpen()){  
  104.                 session.close();  
  105.             }  
  106.         }  
  107.     }  
  108.       
  109.     @Test  
  110.     public void testDelete(){  
  111.         Session session = null;  
  112.           
  113.         try{  
  114.             session = HibernateUtil.getSession();  
  115.             //session.beginTransaction();  
  116.               
  117.             Student stu = (Student)session.get(Student.class2);  
  118.             System.out.println(stu);  
  119.             session.delete(stu);  
  120.               
  121.             //session.getTransaction().commit();  
  122.         }catch(HibernateException e){  
  123.             Assert.fail();  
  124.             e.printStackTrace();  
  125.             //session.getTransaction().rollback();  
  126.         }finally{  
  127.             if(session != null && session.isOpen()){  
  128.                 session.close();  
  129.             }  
  130.         }  
  131.     }  
  132.       
  133.     @Test  
  134.     public void testGet(){  
  135.         Session session = null;  
  136.           
  137.         try{  
  138.             session = HibernateUtil.getSession();  
  139.             session.beginTransaction();  
  140.               
  141.             Student stu = (Student)session.get(Student.class2);  
  142.   
  143.             System.out.println(stu);  
  144.               
  145.             Student stu2 = (Student) session.get(Student.class2);  
  146.               
  147.             System.out.println(stu2);  
  148.               
  149.             session.getTransaction().commit();  
  150.         }catch(HibernateException e){  
  151.             Assert.fail();  
  152.             e.printStackTrace();  
  153.             session.getTransaction().rollback();  
  154.         }finally{  
  155.             if(session != null && session.isOpen()){  
  156.                 session.close();  
  157.             }  
  158.         }  
  159.     }  
  160.       
  161.     @Test  
  162.     public void testGet2(){  
  163.             Session session = null;  
  164.           
  165.             session = HibernateUtil.getSession();  
  166.             session.beginTransaction();  
  167.             Student stu = (Student)session.get(Student.class2);  
  168.             System.out.println(stu);  
  169.             session.getTransaction().commit();  
  170.             session.close();  
  171.               
  172.             session = HibernateUtil.getSession();  
  173.             session.beginTransaction();  
  174.             Student stu2 = (Student) session.get(Student.class2);  
  175.             System.out.println(stu2);  
  176.             session.getTransaction().commit();  
  177.             session.close();  
  178.     }  
  179.       
  180.     @SuppressWarnings("unchecked")  
  181.     @Test  
  182.     public void testQuery(){  
  183.         Session session = null;  
  184.         try{  
  185.             session = HibernateUtil.getSession();  
  186.             session.beginTransaction();  
  187.               
  188.             Query query = session.createQuery("from Student");  
  189.             List<Student> stus = query.list();  
  190.               
  191.             for(Student stu : stus){  
  192.                 System.out.println(stu);  
  193.             }  
  194.               
  195.             session.getTransaction().commit();  
  196.           
  197.         }catch(HibernateException e){  
  198.             e.printStackTrace();  
  199.             session.getTransaction().rollback();  
  200.         }finally{  
  201.             if(session != null && session.isOpen()){  
  202.                 session.close();  
  203.             }  
  204.         }  
  205.     }  
  206.       
  207.     @SuppressWarnings("unchecked")  
  208.     @Test  
  209.     public void testCriteria(){  
  210.         Session session = null;  
  211.         try{  
  212.             session = HibernateUtil.getSession();  
  213.             session.beginTransaction();  
  214.               
  215.             Criteria criteria = session.createCriteria(Student.class);  
  216.               
  217.             List<Student> stus = criteria.addOrder(Order.desc("id")).list();  
  218.               
  219.             for(Student stu : stus){  
  220.                 System.out.println(stu);  
  221.             }  
  222.               
  223.             session.getTransaction().commit();  
  224.           
  225.         }catch(HibernateException e){  
  226.             e.printStackTrace();  
  227.             session.getTransaction().rollback();  
  228.         }finally{  
  229.             if(session != null && session.isOpen()){  
  230.                 session.close();  
  231.             }  
  232.         }  
  233.     }  
  234.       
  235. }</span></span>  

 

补充说明:

如果在hibernate.cfg.xml中配置的是

 <property name="hibernate.hbm2ddl.auto">create</property>

这种配置前提是表已经存在

在这种情况下,只要你在项目的src下新建一个文件夹命名为import.sql,并且里面写上数据库插入语句,那么就会执行插入操作,为什么只是插入,这得跟create值的这种创建啊方式有关,它是启动hibernate时先删除已存在的表,后新建表,新建的表本身就是空的,当然只能进行插入操作了

import.sql

Java代码  收藏代码
  1. <span style="font-size: large;">insert into student(name,age,gender,birthday,score) values('test2',10,false,now(),11.2);</span>  
 这时,如果你在执行上面那个测试类的添加方法,就会发现,结果插入了两条数据,一条是import.sql中的,一条是测试方法中的,显然import.sql中的先执行,因为在hibernate启动时就执行了
发布了7 篇原创文章 · 获赞 6 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章