Java回顾之ORM框架

  第一篇:Java回顾之I/O

  第二篇:Java回顾之网络通信

  第三篇:Java回顾之多线程

  第四篇:Java回顾之多线程同步

  第五篇:Java回顾之集合

  第六篇:Java回顾之序列化

  第七篇:Java回顾之反射

  第八篇:Java回顾之一些基础概念

  第九篇:Java回顾之JDBC

 

  这篇文章里,我们主要讨论ORM框架,以及在使用上和JDBC的区别。

  概述

  ORM框架不是一个新话题,它已经流传了很多年。它的优点在于提供了概念性的、易于理解的数据模型,将数据库中的表和内存中的对象建立了很好的映射关系。

  我们在这里主要关注Java中常用的两个ORM框架:Hibernate和iBatis。下面来介绍这两个框架简单的使用方法,如果将来有时间,我会深入的写一些更有意思的相关文章。

  Hibernate

  Hibernate是一个持久化框架和ORM框架,持久化和ORM是两个有区别的概念,持久化注重对象的存储方法是否随着程序的退出而消亡,ORM关注的是如何在数据库表和内存对象之间建立关联。

  Hibernate使用POJO来表示Model,使用XML配置文件来配置对象和表之间的关系,它提供了一系列API来通过对对象的操作而改变数据库中的过程。

  Hibernate更强调如何对单条记录进行操作,对于更复杂的操作,它提供了一种新的面向对象的查询语言:HQL。

  我们先来定义一个关于Hibernate中Session管理的类,这里的Session类似于JDBC中的Connection。

Hibernate的Session管理类
 1 public class HibernateSessionManager {

 2 

 3     private static SessionFactory sessionFactory;

 4     

 5     static

 6     {

 7         try

 8         {

 9             sessionFactory = new Configuration().configure("sample/orm/hibernate/hibernate.cfg.xml").buildSessionFactory();

10         }

11         catch(Exception ex)

12         {

13             ex.printStackTrace();

14         }

15     }

16     

17     public static final ThreadLocal tl = new ThreadLocal();

18     

19     public static Session currentSession()

20     {

21         Session s = (Session)tl.get();

22         if (s == null)

23         {

24             s = sessionFactory.openSession();

25             tl.set(s);

26         }

27         

28         return s;

29     }

30     

31     public static void closeSession()

32     {

33         Session s = (Session)tl.get();

34         tl.set(null);

35         if (s != null)

36         {

37             s.close();

38         }

39     }

40 }

  基于单张表进行操作

  下面我们来看一个简单的示例,它沿用了Java回顾之JDBC中的数据库,使用MySQL的test数据库中的user表。

  首先,我们来定义VO对象:

定义User对象
 1 public class User implements Serializable

 2 {

 3     private static final long serialVersionUID = 1L;

 4     private int userID;

 5     private String userName;

 6     public void setUserID(int userID) {

 7         this.userID = userID;

 8     }

 9     public int getUserID() {

10         return userID;

11     }

12     public void setUserName(String userName) {

13         this.userName = userName;

14     }

15     public String getUserName() {

16         return userName;

17     }

18 }

  然后,我们定义User对象和数据库中user表之间的关联,user表中只有两列:id和name。

 1 <?xml version="1.0"?>

 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 4 

 5 <hibernate-mapping>

 6     <class name="sample.orm.hibernate.User" table="user" catalog="test">

 7         <id name="userID" type="java.lang.Integer">

 8             <column name="id" />

 9             <generator class="assigned" />

10         </id>

11         <property name="userName" type="java.lang.String">

12             <column name="name" />

13         </property>

14     </class>

15 </hibernate-mapping>

  将上述内容存储为User.hbm.xml。

  接下来,我们需要定义一个关于Hibernate的全局配置文件,这里文件名是hibernate.cfg.xml。

 1 <?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 

 6 <hibernate-configuration>

 7     <session-factory>

 8         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

 9         <property name="connection.url">jdbc:mysql://localhost/test</property>

10         <property name="connection.username">root</property>

11         <property name="connection.password">123</property>    

12         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

13         <property name="show_sql">true</property>

14         <property name="jdbc.fetch_size">50</property>

15         <property name="jdbc.batch_size">25</property>

16         

17         <mapping resource="sample/orm/hibernate/User.hbm.xml" />        

18     </session-factory>

19 </hibernate-configuration>

  可以看到,上述配置文件中包含了数据库连接的信息,诸如driver信息、数据库url、用户名、密码等等,还包括了我们上面定义的User.hbm.xml。

  最后,我们编写测试代码,来对user表进行增、删、查、改的操作:

使用Hibernate对user表进行操作
 1 private static void getUser(int id)

 2 {

 3     Session session = HibernateSessionManager.currentSession();

 4     System.out.println("=====Query test=====");

 5     User user = (User)session.get(User.class, new Integer(id));

 6     if (user != null)

 7     {

 8         System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName());

 9     }

10     HibernateSessionManager.closeSession();

11 }

12 

13 private static void insertUser()

14 {

15     Session session = HibernateSessionManager.currentSession();

16     System.out.println("=====Insert test=====");

17     Transaction transaction = session.beginTransaction();

18     User user = new User();

19     user.setUserID(6);

20     user.setUserName("Zhang Fei");

21     session.save(user);

22     session.flush();

23     transaction.commit();

24     HibernateSessionManager.closeSession();

25     getUser(6);

26 }

27 

28 private static void updateUser(int id)

29 {

30     Session session = HibernateSessionManager.currentSession();

31     System.out.println("=====Update test=====");

32     Transaction transaction = session.beginTransaction();

33     User user = (User)session.get(User.class, new Integer(id));

34     System.out.println("=====Before Update=====");

35     if (user != null)

36     {

37         System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName());

38     }

39     user.setUserName("Devil");

40     session.save(user);

41     session.flush();

42     transaction.commit();

43     user = (User)session.get(User.class, new Integer(id));

44     System.out.println("=====After Update=====");

45     if (user != null)

46     {

47         System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName());

48     }

49     HibernateSessionManager.closeSession();

50 }

51 

52 private static void deleteUser(int id)

53 {

54     Session session = HibernateSessionManager.currentSession();

55     System.out.println("=====Delete test=====");

56     Transaction transaction = session.beginTransaction();

57     User user = (User)session.get(User.class, new Integer(id));

58     System.out.println("=====Before Delte=====");

59     if (user != null)

60     {

61         System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName());

62     }

63     session.delete(user);

64     transaction.commit();

65     user = (User)session.get(User.class, new Integer(id));

66     System.out.println("=====After Update=====");

67     if (user != null)

68     {

69         System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName());

70     }

71     else

72     {

73         System.out.println("Delete successfully.");

74     }

75     HibernateSessionManager.closeSession();

76 }

  我们按照如下顺序调用测试代码:

1 insertUser();

2 updateUser(6);

3 deleteUser(6);

  可以看到如下结果:

=====Insert test=====

Hibernate: insert into test.user (name, id) values (?, ?)

=====Query test=====

Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from test.user user0_ where user0_.id=?

ID:6; Name:Zhang Fei

=====Update test=====

Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from test.user user0_ where user0_.id=?

=====Before Update=====

ID:6; Name:Zhang Fei

Hibernate: update test.user set name=? where id=?

=====After Update=====

ID:6; Name:Devil

=====Delete test=====

Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from test.user user0_ where user0_.id=?

=====Before Delte=====

ID:6; Name:Devil

Hibernate: delete from test.user where id=?

Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from test.user user0_ where user0_.id=?

=====After Delete=====

Delete successfully.

  请注意,上面的结果中,输出了每次数据库操作时的SQL语句,这是因为在配置文件中有如下配置:

<property name="show_sql">true</property>

  我们可以在开发调试阶段将其打开,在部署到客户方时,将其关闭。

  基于多表关联的操作

  Hibernate在建立多表关联时,根据主外键的设置,表之间的关联可以分为三种:一对一、一对多和多对多。这些关联会体现在表的配置文件以及VO中。

  下面我们来看一个经典的多表关联示例:排课表。数据库中建立如下四张表:Grade/Class/ClassRoom/Schedule。刚发现,使用MySQL自带的管理器导出表定义基本是一件不可能的任务。。。。

  上述各表除ID以及必要外键外,只有Name一列。

  然后看各个VO的定义:

定义Grade对象
 1 package sample.orm.hibernate;

 2 

 3 import java.io.Serializable;

 4 import java.util.Set;

 5 

 6 public class Grade implements Serializable

 7 {

 8     private static final long serialVersionUID = 1L;

 9     private int gradeID;

10     private String gradeName;

11     private Set classes;

12     public void setGradeID(int gradeID) {

13         this.gradeID = gradeID;

14     }

15     public int getGradeID() {

16         return gradeID;

17     }

18     public void setGradeName(String gradeName) {

19         this.gradeName = gradeName;

20     }

21     public String getGradeName() {

22         return gradeName;

23     }

24     public void setClasses(Set classes) {

25         this.classes = classes;

26     }

27     public Set getClasses() {

28         return classes;

29     }

30 }
定义Class对象
 1 package sample.orm.hibernate;

 2 

 3 import java.io.Serializable;

 4 import java.util.Set;

 5 

 6 public class Class implements Serializable

 7 {

 8     private static final long serialVersionUID = 1L;

 9     private int classID;

10     private Grade grade;

11     private Set classrooms;

12     private String className;

13     public void setClassID(int classID) {

14         this.classID = classID;

15     }

16     public int getClassID() {

17         return classID;

18     }

19     public void setClassName(String className) {

20         this.className = className;

21     }

22     public String getClassName() {

23         return className;

24     }

25     public void setGrade(Grade grade) {

26         this.grade = grade;

27     }

28     public Grade getGrade() {

29         return grade;

30     }

31     public void setClassrooms(Set classrooms) {

32         this.classrooms = classrooms;

33     }

34     public Set getClassrooms() {

35         return classrooms;

36     }

37 }
定义ClassRoom对象
 1 package sample.orm.hibernate;

 2 

 3 import java.io.Serializable;

 4 import java.util.Set;

 5 

 6 public class ClassRoom implements Serializable

 7 {

 8     private static final long serialVersionUID = 1L;

 9     private int classRoomID;

10     private String classRoomName;

11     private Set classes;

12     public void setClassRoomID(int classRoomID) {

13         this.classRoomID = classRoomID;

14     }

15     public int getClassRoomID() {

16         return classRoomID;

17     }

18     public void setClassRoomName(String classRoomName) {

19         this.classRoomName = classRoomName;

20     }

21     public String getClassRoomName() {

22         return classRoomName;

23     }

24     public void setClasses(Set classes) {

25         this.classes = classes;

26     }

27     public Set getClasses() {

28         return classes;

29     }

30 }
定义Schedule对象
 1 package sample.orm.hibernate;

 2 

 3 import java.io.Serializable;

 4 import java.util.Set;

 5 

 6 public class Schedule implements Serializable

 7 {

 8     private static final long serialVersionUID = 1L;

 9     private int scheduleID;

10     private int classRoomID;

11     private int classID;

12     private Set classes;

13     public void setClassRoomID(int classRoomID) {

14         this.classRoomID = classRoomID;

15     }

16     public int getClassRoomID() {

17         return classRoomID;

18     }

19     public void setClassID(int classID) {

20         this.classID = classID;

21     }

22     public int getClassID() {

23         return classID;

24     }

25     public void setClasses(Set classes) {

26         this.classes = classes;

27     }

28     public Set getClasses() {

29         return classes;

30     }

31     public void setScheduleID(int scheduleID) {

32         this.scheduleID = scheduleID;

33     }

34     public int getScheduleID() {

35         return scheduleID;

36     }

37 }

  接着是各个表的关联配置文件:

  1)Grade.hbm.xml

 1 <?xml version="1.0"?>

 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 4 

 5 <hibernate-mapping>

 6     <class name="sample.orm.hibernate.Grade" table="grade" catalog="test">

 7         <id name="gradeID" type="java.lang.Integer">

 8             <column name="gradeid" />

 9             <generator class="assigned" />

10         </id>

11         <property name="gradeName" type="java.lang.String">

12             <column name="gradename" />

13         </property>

14         

15         <set name="classes" lazy="true" inverse="true" cascade="all-delete-orphan">

16             <key>

17                 <column name="gradeid"/>

18             </key>

19             <one-to-many class="sample.orm.hibernate.Class"/>

20         </set>

21     </class>

22 </hibernate-mapping>

  注意上面的<set>配置,里面的<one-to-many>节点说明了Grade和Class之间一对多的关系。

  2)Class.hbm.xml

 1 <?xml version="1.0"?>

 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 4 

 5 <hibernate-mapping>

 6     <class name="sample.orm.hibernate.Class" table="class" catalog="test">

 7         <id name="classID" type="java.lang.Integer">

 8             <column name="classid" />

 9             <generator class="assigned" />

10         </id>

11         <property name="className" type="java.lang.String">

12             <column name="classname" />

13         </property>

14         

15         <many-to-one name="grade" class="sample.orm.hibernate.Grade" lazy="proxy" not-null="true">

16             <column name="gradeid"/>

17         </many-to-one>

18         

19         <set name="classrooms" lazy="true" inverse="true" cascade="all-delete-orphan" table="schedule">

20             <key column ="classid"/>

21             <many-to-many class="sample.orm.hibernate.ClassRoom" column="classroomid"/>

22         </set>

23     </class>

24 </hibernate-mapping>

  注意它定义两个关联:一个是和Grade之间多对一的关系,一个适合ClassRoom之间多对多的关系。

  3)ClassRoom.hbm.xml

 1 <?xml version="1.0"?>

 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 4 

 5 <hibernate-mapping>

 6     <class name="sample.orm.hibernate.ClassRoom" table="classroom" catalog="test">

 7         <id name="classRoomID" type="java.lang.Integer">

 8             <column name="classroomid" />

 9             <generator class="assigned" />

10         </id>

11         <property name="classRoomName" type="java.lang.String">

12             <column name="classroomname" />

13         </property>

14         

15         <set name="classes" lazy="true" inverse="true" cascade="all-delete-orphan" table="schedule">

16             <key column="classroomid"/>

17             <many-to-many class="sample.orm.hibernate.Class" column="classid"/>

18         </set>

19     </class>

20 </hibernate-mapping>

  它只定义了一个关联:和Class之间的多对多关联。

  4)Schedule.hbm.xml

 1 <?xml version="1.0"?>

 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 4 

 5 <hibernate-mapping>

 6     <class name="sample.orm.hibernate.Schedule" table="schedule" catalog="test">

 7         <id name="scheduleID" type="java.lang.Integer">

 8             <column name="scheduleid" />

 9             <generator class="assigned" />

10         </id>

11         <property name="classID" type="java.lang.Integer">

12             <column name="classid" />

13         </property>

14         <property name="classRoomID" type="java.lang.Integer">

15             <column name="classroomid" />

16         </property>

17     </class>

18 </hibernate-mapping>

  这里就不需要再定义关联了。

  我们需要在Hibernate全局配置文件中添加如下内容:

1 <mapping resource="sample/orm/hibernate/Grade.hbm.xml" />

2 <mapping resource="sample/orm/hibernate/Class.hbm.xml" />

3 <mapping resource="sample/orm/hibernate/ClassRoom.hbm.xml" />

4 <mapping resource="sample/orm/hibernate/Schedule.hbm.xml" />

  下面是各种测试方法,在有关联的情况下,Hibernate提供了下面几个特性:

  • 延迟加载
  • 级联添加
  • 级联修改
  • 级联删除
多表关联情况下的一些测试方法
  1 private static void getClass(int gradeid)

  2 {

  3     Session session = HibernateSessionManager.currentSession();

  4     System.out.println("=====Get Class info=====");

  5     Transaction transaction = session.beginTransaction();

  6     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));

  7     

  8     Hibernate.initialize(grade);

  9     Iterator iterator = grade.getClasses().iterator();

 10     System.out.println("年级:" + grade.getGradeName() + "包括以下班级:");

 11     while(iterator.hasNext())

 12     {

 13         System.out.println(grade.getGradeName() + ((Class)iterator.next()).getClassName());

 14     }

 15     HibernateSessionManager.closeSession();

 16 }

 17 

 18 private static void getSchedule(int gradeid)

 19 {

 20     Session session = HibernateSessionManager.currentSession();

 21     Transaction transaction = session.beginTransaction();

 22     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));

 23     if (grade != null)

 24     {

 25         System.out.println("ID:" + grade.getGradeID() + "; Name:" + grade.getGradeName());

 26     }

 27     

 28     Hibernate.initialize(grade.getClasses());

 29     

 30     Iterator iterator = grade.getClasses().iterator();

 31     while(iterator.hasNext())

 32     {

 33         Class c = (Class)iterator.next();

 34         System.out.println(grade.getGradeName() + c.getClassName() + "使用以下教室:");

 35         Hibernate.initialize(c.getClassrooms());

 36         Iterator iterator1 = c.getClassrooms().iterator();

 37         while(iterator1.hasNext())

 38         {

 39             System.out.println(((ClassRoom)iterator1.next()).getClassRoomName());

 40         }

 41     }

 42     HibernateSessionManager.closeSession();

 43 }

 44 

 45 private static void insertGrade()

 46 {

 47     Session session = HibernateSessionManager.currentSession();

 48     Transaction transaction = session.beginTransaction();

 49     Grade grade = new Grade();

 50     grade.setGradeID(4);

 51     grade.setGradeName("四年级");

 52     

 53     Class c1 = new Class();

 54     c1.setClassID(7);

 55     c1.setGrade(grade);

 56     c1.setClassName("一班");

 57     Class c2 = new Class();

 58     c2.setClassID(8);

 59     c2.setGrade(grade);

 60     c2.setClassName("二班");

 61     

 62     Set set = new HashSet();

 63     set.add(c1);

 64     set.add(c2);

 65     

 66     grade.setClasses(set);

 67     

 68     session.save(grade);

 69     session.flush();

 70     transaction.commit();

 71     HibernateSessionManager.closeSession();

 72     getClass(4);

 73 }

 74 

 75 private static void deleteGrade(int gradeid)

 76 {

 77     Session session = HibernateSessionManager.currentSession();

 78     Transaction transaction = session.beginTransaction();

 79     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));

 80     if (grade != null)

 81     {

 82         session.delete(grade);

 83         session.flush();

 84     }

 85     

 86     transaction.commit();

 87     

 88     grade = (Grade)session.get(Grade.class, new Integer(gradeid));

 89     if (grade == null)

 90     {

 91         System.out.println("删除成功");

 92     }

 93     HibernateSessionManager.closeSession();

 94 }

 95 

 96 private static void updateGrade1(int gradeid)

 97 {

 98     Session session = HibernateSessionManager.currentSession();

 99     Transaction transaction = session.beginTransaction();

100     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));

101     if (grade != null)

102     {

103         System.out.println("ID:" + grade.getGradeID() + "; Name:" + grade.getGradeName());

104     }

105     grade.setGradeName("Grade " + gradeid);

106     session.save(grade);

107     session.flush();

108     transaction.commit();

109     HibernateSessionManager.closeSession();

110     getClass(gradeid);

111 }

112 

113 private static void updateGrade2(int gradeid)

114 {

115     Session session = HibernateSessionManager.currentSession();

116     Transaction transaction = session.beginTransaction();

117     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));

118     if (grade != null)

119     {

120         System.out.println("ID:" + grade.getGradeID() + "; Name:" + grade.getGradeName());

121     }

122     

123     Grade newGrade = new Grade();

124     newGrade.setGradeID(10);

125     newGrade.setGradeName(grade.getGradeName());

126     Set set = grade.getClasses();

127     Set newSet = new HashSet();

128     Iterator iterator = set.iterator();

129     while(iterator.hasNext())

130     {

131         Class c = (Class)iterator.next();

132         Class temp = new Class();

133         temp.setClassID(c.getClassID());

134         temp.setClassName(c.getClassName());

135         temp.setGrade(newGrade);

136         newSet.add(temp);

137     }

138     newGrade.setClasses(newSet);

139     session.delete(grade);

140     session.flush();

141     session.save(newGrade);

142     session.flush();

143     transaction.commit();

144     grade = (Grade)session.get(Grade.class, new Integer(gradeid));

145     if (grade == null)

146     {

147         System.out.println("删除成功");

148     }

149     HibernateSessionManager.closeSession();

150     getClass(10);

151 }

  按顺序调用上面的方法:

1 getClass(1);

2 getSchedule(1);

3 insertGrade();

4 updateGrade1(4);

5 updateGrade2(4);

6 deleteGrade(10);

  执行结果如下:

=====Get Class info=====

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?

年级:一年级包括以下班级:

一年级二班

一年级一班

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

ID:1; Name:一年级

Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?

一年级一班使用以下教室:

Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?

教室二

教室五

教室一

一年级二班使用以下教室:

Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?

教室四

教室二

教室六

Hibernate: select class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ from test.class class_ where class_.classid=?

Hibernate: select class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ from test.class class_ where class_.classid=?

Hibernate: insert into test.grade (gradename, gradeid) values (?, ?)

Hibernate: insert into test.class (classname, gradeid, classid) values (?, ?, ?)

Hibernate: insert into test.class (classname, gradeid, classid) values (?, ?, ?)

=====Get Class info=====

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?

年级:四年级包括以下班级:

四年级二班

四年级一班

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

ID:4; Name:四年级

Hibernate: update test.grade set gradename=? where gradeid=?

=====Get Class info=====

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?

年级:Grade 4包括以下班级:

Grade 4二班

Grade 4一班

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

ID:4; Name:Grade 4

Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?

Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?

Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?

Hibernate: delete from test.class where classid=?

Hibernate: delete from test.class where classid=?

Hibernate: delete from test.grade where gradeid=?

Hibernate: select class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ from test.class class_ where class_.classid=?

Hibernate: select class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ from test.class class_ where class_.classid=?

Hibernate: insert into test.grade (gradename, gradeid) values (?, ?)

Hibernate: insert into test.class (classname, gradeid, classid) values (?, ?, ?)

Hibernate: insert into test.class (classname, gradeid, classid) values (?, ?, ?)

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

删除成功

=====Get Class info=====

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?

年级:Grade 4包括以下班级:

Grade 4一班

Grade 4二班

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?

Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?

Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?

Hibernate: delete from test.class where classid=?

Hibernate: delete from test.class where classid=?

Hibernate: delete from test.grade where gradeid=?

Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?

删除成功

  同样,执行结果中包含了各个SQL语句。

  iBatis

  iBatis是另外一种ORM框架,和Hibernate擅长操作单条记录不同,iBatis是基于SQL模板的,可以说,iBatis每次和数据库进行操作时,都有明确的SQL语句,而这些SQL语句,就是我们定义在配置文件中的。

  我们还是以test数据库中的user表为例,简单说明iBatis的操作流程:

  首先,我们还是需要定义VO对象,这里还是使用和Hibernate讲解时相同的User:

定义User对象
 1 package sample.orm.ibatis;

 2 

 3 import java.io.Serializable;

 4 

 5 public class User implements Serializable

 6 {

 7     private static final long serialVersionUID = 1L;

 8     private int userID;

 9     private String userName;

10     public void setUserID(int userID) {

11         this.userID = userID;

12     }

13     public int getUserID() {

14         return userID;

15     }

16     public void setUserName(String userName) {

17         this.userName = userName;

18     }

19     public String getUserName() {

20         return userName;

21     }

22     

23 }

  然后需要针对这个VO,定义一个独立的配置文件:User.xml

 1 <?xml version="1.0" encoding="UTF-8"?>

 2 <!DOCTYPE sqlMap 

 3     PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" 

 4     "http://www.ibatis.com/dtd/sql-map-2.dtd">

 5     

 6 <sqlMap namespace="User">

 7 

 8     <typeAlias alias="user" type="sample.orm.ibatis.User" />

 9     

10     

11     <cacheModel id="user-cache" type="OSCache" readOnly="true" serialize="true">

12         <flushInterval milliseconds="1" />

13         <flushOnExecute statement="insertUser" />

14         <flushOnExecute statement="updateUser" />

15         <flushOnExecute statement="getUser" />

16         <flushOnExecute statement="getAllUser" />

17         <property value="1" name="size" />

18      </cacheModel>

19     

20     <!--

21     <resultMap >

22         <result property="userID" column="id" />

23         <result property="userName" column="name" />

24     </resultMap>

25     -->

26     

27     

28     <select id="getUser" parameterClass="java.lang.Integer" resultClass="user" cacheModel="user-cache" >

29         select id as userID,name as userName from user where id = #userID#

30     </select>

31     <select id="getAllUser" resultClass="user" cacheModel="user-cache">

32         select id as userID,name as userName from user

33     </select>

34     <update id="updateUser" parameterClass="user">

35         update user SET name=#userName# WHERE id = #userID#

36     </update>

37     <insert id="insertUser" parameterClass="user">

38         insert into user ( id, name ) VALUES ( #userID#,#userName#)

39     </insert>

40     <delete id="deleteUser" parameterClass="java.lang.Integer">

41         delete from user where id=#userID#

42     </delete>

43     

44 </sqlMap>

  这个配置文件主要包括三部分:

  1)缓存的配置

  2)对象属性和表字段之间的关联

  3)针对表的各种CRUD操作

  然后是关于iBatis的全局配置文件SqlMapConfig.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>

 2 <!DOCTYPE sqlMapConfig 

 3     PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" 

 4     "http://www.ibatis.com/dtd/sql-map-config-2.dtd">

 5     

 6 <sqlMapConfig>

 7 

 8     <settings cacheModelsEnabled="true" enhancementEnabled="true"

 9         lazyLoadingEnabled="true" errorTracingEnabled="true" maxRequests="32"

10         maxSessions="10" maxTransactions="5" useStatementNamespaces="false" />

11         

12     <transactionManager type="JDBC">

13         <dataSource type="SIMPLE">

14            <property name="JDBC.Driver" value="com.mysql.jdbc.Driver" />

15            <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/test" />

16            <property name="JDBC.Username" value="root" />

17            <property name="JDBC.Password" value="123" />

18            <property name="Pool.MaximumActiveConnections" value="10" />

19            <property name="Pool.MaximumIdleConnections" value="5" />

20            <property name="Pool.MaximumCheckoutTime" value="120000" />

21            <property name="Pool.TimeToWait" value="500" />

22            <property name="Pool.PingQuery" value="select 1 from user" />

23            <property name="Pool.PingEnabled" value="false" />

24         </dataSource>

25     </transactionManager>

26     

27     <sqlMap resource="sample/orm/ibatis/User.xml" />

28 

29 </sqlMapConfig>

  和Hibernate全局配置文件类似,它也包含了数据库连接的信息、数据库连接池的信息以及我们定义的User.xml。

  下面是测试方法:

iBatis测试方法
  1 public class Sample {

  2 

  3     private SqlMapClient sqlMap = null;

  4     

  5     private void buildMap() throws IOException

  6     {

  7         String resource = "sample/orm/ibatis/SqlMapConfig.xml";          

  8         Reader reader = Resources.getResourceAsReader(resource);

  9         this.sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

 10     }

 11     

 12     private void insertUser() throws IOException, SQLException

 13     {

 14         System.out.println("=====Insert test=====");

 15         if (this.sqlMap == null)

 16         {

 17             this.buildMap();

 18         }

 19         this.sqlMap.startTransaction();

 20         User user = new User();

 21         user.setUserID(10);

 22         user.setUserName("Angel");

 23         

 24         this.sqlMap.insert("insertUser", user);

 25         this.sqlMap.commitTransaction();

 26         

 27         user = getUser(10);

 28         printUserInfo(user);

 29     }

 30     

 31     private void updateUser() throws IOException, SQLException, InterruptedException

 32     {

 33         System.out.println("=====Update test=====");

 34         if (this.sqlMap == null)

 35         {

 36             this.buildMap();

 37         }

 38         this.sqlMap.startTransaction();

 39         User user = new User();

 40         user.setUserID(10);

 41         user.setUserName("Devil");

 42         this.sqlMap.update("updateUser", user);

 43         this.sqlMap.commitTransaction();

 44         this.sqlMap.flushDataCache();

 45 //        Thread.sleep(3000);

 46         user = getUser(10);

 47         printUserInfo(user);

 48     }

 49     

 50     private void deleteUser() throws IOException, SQLException

 51     {

 52         System.out.println("=====Delete test=====");

 53         if (this.sqlMap == null)

 54         {

 55             this.buildMap();

 56         }

 57         sqlMap.flushDataCache();

 58         this.sqlMap.startTransaction();

 59         this.sqlMap.delete("deleteUser", 10);

 60         this.sqlMap.commitTransaction();

 61         getAllUser();

 62     }

 63     

 64     private User getUser(int id) throws IOException, SQLException

 65     {

 66         if (this.sqlMap == null)

 67         {

 68             this.buildMap();

 69         }

 70         User user = (User)this.sqlMap.openSession().queryForObject("getUser", id);

 71         

 72         return user;

 73     }

 74 

 75      private List<User> getAllUser() throws IOException, SQLException 

 76      {

 77             if(this.sqlMap==null)

 78                this.buildMap();

 79          

 80          List userList=null;  

 81          userList=this.sqlMap.openSession().queryForList("getAllUser");

 82          printUserInfo(userList);

 83          return userList;

 84      }

 85      

 86      private void printUserInfo(User user)

 87      {

 88          System.out.println("=====user info=====");

 89          System.out.println("ID:" + user.getUserID() + ";Name:" + user.getUserName());

 90      }

 91      

 92      private void printUserInfo(List<User> users)

 93      {

 94          System.out.println("=====user info=====");

 95          for(User user:users)

 96          {

 97              System.out.println("ID:" + user.getUserID() + ";Name:" + user.getUserName());

 98          }

 99      }

100      

101      public static void main(String[] args) throws IOException, SQLException, InterruptedException

102      {

103          Sample sample = new Sample();

104          sample.getAllUser();

105          sample.insertUser();

106          sample.updateUser();

107          sample.deleteUser();

108      }

109 }

  它的执行结果如下:

=====user info=====

ID:1;Name:Zhang San

ID:2;Name:TEST

=====Insert test=====

=====user info=====

ID:10;Name:Angel

=====Update test=====

=====user info=====

ID:10;Name:Devil

=====Delete test=====

=====user info=====

ID:1;Name:Zhang San

ID:2;Name:TEST

  这篇文章只是简单介绍了Hibernate和iBatis的用法,并没有涉及全部,例如Hibernate的事务、拦截、HQL、iBatis的缓存等等。这里主要是为了描述ORM框架的基本轮廓,以及在使用方式上它和JDBC的区别。

你可能感兴趣的:(java)