H5W3
当前位置:H5W3 > 其他技术问题 > 正文

基于Java ORM框架的使用详解

ORM框架不是一个新话题,它已经流传了很多年。它的优点在于提供了概念性的、易于理解的数据模型,将数据库中的表和内存中的对象建立了很好的映射关系。我们在这里主要关注Java中常用的两个ORM框架:Hibernate和iBatis。下面来介绍这两个框架简单的使用方法,如果将来有时间,我会深入的写一些更有意思的相关文章。HibernateHibernate是一个持久化框架和ORM框架,持久化和ORM是两个有区别的概念,持久化注重对象的存储方法是否随着程序的退出而消亡,ORM关注的是如何在数据库表和内存对象之间建立关联。Hibernate使用POJO来表示Model,使用XML配置文件来配置对象和表之间的关系,它提供了一系列API来通过对对象的操作而改变数据库中的过程。Hibernate更强调如何对单条记录进行操作,对于更复杂的操作,它提供了一种新的面向对象的查询语言:HQL。我们先来定义一个关于Hibernate中Session管理的类,这里的Session类似于JDBC中的Connection。

代码如下:
Hibernate的Session管理类  public class HibernateSessionManager {     private static SessionFactory sessionFactory;     static     {         try         {             sessionFactory = new Configuration().configure(“sample/orm/hibernate/hibernate.cfg.xml”).buildSessionFactory();         }         catch(Exception ex)         {             ex.printStackTrace();         }     }     public static final ThreadLocal tl = new ThreadLocal();     public static Session currentSession()     {         Session s = (Session)tl.get();         if (s == null)         {             s = sessionFactory.openSession();             tl.set(s);         }         return s;     }     public static void closeSession()     {         Session s = (Session)tl.get();         tl.set(null);         if (s != null)         {             s.close();         }     } }

基于单张表进行操作下面我们来看一个简单的示例,它沿用了<基于Java回顾之JDBC的使用详解>中的数据库,使用MySQL的test数据库中的user表。首先,我们来定义VO对象:

代码如下:
定义User对象  public class User implements Serializable {     private static final long serialVersionUID = 1L;     private int userID;     private String userName;     public void setUserID(int userID) {         this.userID = userID;     }     public int getUserID() {         return userID;     }     public void setUserName(String userName) {         this.userName = userName;     }     public String getUserName() {         return userName;     } }

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

代码如下:
<?xml version=”1.0″?> <!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”> <hibernate-mapping>     <class name=”sample.orm.hibernate.User” table=”user” catalog=”test”>         <id name=”userID” type=”java.lang.Integer”>             <column name=”id” />             <generator class=”assigned” />         </id>         <property name=”userName” type=”java.lang.String”>             <column name=”name” />         </property>     </class> </hibernate-mapping>

将上述内容存储为User.hbm.xml。接下来,我们需要定义一个关于Hibernate的全局配置文件,这里文件名是hibernate.cfg.xml。

代码如下:
<?xml version=’1.0′ encoding=’UTF-8′?> <!DOCTYPE hibernate-configuration PUBLIC           “-//Hibernate/Hibernate Configuration DTD 3.0//EN”           “http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”> <hibernate-configuration>     <session-factory>         <property name=”connection.driver_class”>com.mysql.jdbc.Driver</property>         <property name=”connection.url”>jdbc:mysql://localhost/test</property>         <property name=”connection.username”>root</property>         <property name=”connection.password”>123</property>             <property name=”dialect”>org.hibernate.dialect.MySQLDialect</property>         <property name=”show_sql”>true</property>         <property name=”jdbc.fetch_size”>50</property>         <property name=”jdbc.batch_size”>25</property>         <mapping resource=”sample/orm/hibernate/User.hbm.xml” />             </session-factory> </hibernate-configuration>

可以看到,上述配置文件中包含了数据库连接的信息,诸如driver信息、数据库url、用户名、密码等等,还包括了我们上面定义的User.hbm.xml。最后,我们编写测试代码,来对user表进行增、删、查、改的操作:

代码如下:
使用Hibernate对user表进行操作  private static void getUser(int id) {     Session session = HibernateSessionManager.currentSession();     System.out.println(“=====Query test=====”);     User user = (User)session.get(User.class, new Integer(id));     if (user != null)     {         System.out.println(“ID:” + user.getUserID() + “; Name:” + user.getUserName());     }     HibernateSessionManager.closeSession(); } private static void insertUser() {     Session session = HibernateSessionManager.currentSession();     System.out.println(“=====Insert test=====”);     Transaction transaction = session.beginTransaction();     User user = new User();     user.setUserID(6);     user.setUserName(“Zhang Fei”);     session.save(user);     session.flush();     transaction.commit();     HibernateSessionManager.closeSession();     getUser(6); } private static void updateUser(int id) {     Session session = HibernateSessionManager.currentSession();     System.out.println(“=====Update test=====”);     Transaction transaction = session.beginTransaction();     User user = (User)session.get(User.class, new Integer(id));     System.out.println(“=====Before Update=====”);     if (user != null)     {         System.out.println(“ID:” + user.getUserID() + “; Name:” + user.getUserName());     }     user.setUserName(“Devil”);     session.save(user);     session.flush();     transaction.commit();     user = (User)session.get(User.class, new Integer(id));     System.out.println(“=====After Update=====”);     if (user != null)     {         System.out.println(“ID:” + user.getUserID() + “; Name:” + user.getUserName());     }     HibernateSessionManager.closeSession(); } private static void deleteUser(int id) {     Session session = HibernateSessionManager.currentSession();     System.out.println(“=====Delete test=====”);     Transaction transaction = session.beginTransaction();     User user = (User)session.get(User.class, new Integer(id));     System.out.println(“=====Before Delte=====”);     if (user != null)     {         System.out.println(“ID:” + user.getUserID() + “; Name:” + user.getUserName());     }     session.delete(user);     transaction.commit();     user = (User)session.get(User.class, new Integer(id));     System.out.println(“=====After Update=====”);     if (user != null)     {         System.out.println(“ID:” + user.getUserID() + “; Name:” + user.getUserName());     }     else     {         System.out.println(“Delete successfully.”);     }     HibernateSessionManager.closeSession(); }

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

代码如下:
insertUser();updateUser(6);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 FeiHibernate: 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:DevilHibernate: 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对象  package sample.orm.hibernate; import java.io.Serializable; import java.util.Set; public class Grade implements Serializable {     private static final long serialVersionUID = 1L;     private int gradeID;     private String gradeName;     private Set classes;     public void setGradeID(int gradeID) {         this.gradeID = gradeID;     }     public int getGradeID() {         return gradeID;     }     public void setGradeName(String gradeName) {         this.gradeName = gradeName;     }     public String getGradeName() {         return gradeName;     }     public void setClasses(Set classes) {         this.classes = classes;     }     public Set getClasses() {         return classes;     } }
代码如下:
定义Class对象  package sample.orm.hibernate; import java.io.Serializable; import java.util.Set; public class Class implements Serializable {     private static final long serialVersionUID = 1L;     private int classID;     private Grade grade;     private Set classrooms;     private String className;     public void setClassID(int classID) {         this.classID = classID;     }     public int getClassID() {         return classID;     }     public void setClassName(String className) {         this.className = className;     }     public String getClassName() {         return className;     }     public void setGrade(Grade grade) {         this.grade = grade;     }     public Grade getGrade() {         return grade;     }     public void setClassrooms(Set classrooms) {         this.classrooms = classrooms;     }     public Set getClassrooms() {         return classrooms;     } }
代码如下:
定义ClassRoom对象  package sample.orm.hibernate; import java.io.Serializable; import java.util.Set; public class ClassRoom implements Serializable {     private static final long serialVersionUID = 1L;     private int classRoomID;     private String classRoomName;     private Set classes;     public void setClassRoomID(int classRoomID) {         this.classRoomID = classRoomID;     }     public int getClassRoomID() {         return classRoomID;     }     public void setClassRoomName(String classRoomName) {         this.classRoomName = classRoomName;     }     public String getClassRoomName() {         return classRoomName;     }     public void setClasses(Set classes) {         this.classes = classes;     }     public Set getClasses() {         return classes;     } }
代码如下:
定义Schedule对象  package sample.orm.hibernate; import java.io.Serializable; import java.util.Set; public class Schedule implements Serializable {     private static final long serialVersionUID = 1L;     private int scheduleID;     private int classRoomID;     private int classID;     private Set classes;     public void setClassRoomID(int classRoomID) {         this.classRoomID = classRoomID;     }     public int getClassRoomID() {         return classRoomID;     }     public void setClassID(int classID) {         this.classID = classID;     }     public int getClassID() {         return classID;     }     public void setClasses(Set classes) {         this.classes = classes;     }     public Set getClasses() {         return classes;     }     public void setScheduleID(int scheduleID) {         this.scheduleID = scheduleID;     }     public int getScheduleID() {         return scheduleID;     } }

接着是各个表的关联配置文件:1)Grade.hbm.xml

代码如下:
<?xml version=”1.0″?> <!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”> <hibernate-mapping>     <class name=”sample.orm.hibernate.Grade” table=”grade” catalog=”test”>         <id name=”gradeID” type=”java.lang.Integer”>             <column name=”gradeid” />             <generator class=”assigned” />         </id>         <property name=”gradeName” type=”java.lang.String”>             <column name=”gradename” />         </property>         <set name=”classes” lazy=”true” inverse=”true” cascade=”all-delete-orphan”>             <key>                 <column name=”gradeid”/>             </key>             <one-to-many class=”sample.orm.hibernate.Class”/>         </set>     </class> </hibernate-mapping>

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

代码如下:
<?xml version=”1.0″?> <!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”> <hibernate-mapping>     <class name=”sample.orm.hibernate.Class” table=”class” catalog=”test”>         <id name=”classID” type=”java.lang.Integer”>             <column name=”classid” />             <generator class=”assigned” />         </id>         <property name=”className” type=”java.lang.String”>             <column name=”classname” />         </property>         <many-to-one name=”grade” class=”sample.orm.hibernate.Grade” lazy=”proxy” not-null=”true”>             <column name=”gradeid”/>         </many-to-one>         <set name=”classrooms” lazy=”true” inverse=”true” cascade=”all-delete-orphan” table=”schedule”>             <key column =”classid”/>             <many-to-many class=”sample.orm.hibernate.ClassRoom” column=”classroomid”/>         </set>     </class> </hibernate-mapping>

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

代码如下:
<?xml version=”1.0″?> <!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”> <hibernate-mapping>     <class name=”sample.orm.hibernate.ClassRoom” table=”classroom” catalog=”test”>         <id name=”classRoomID” type=”java.lang.Integer”>             <column name=”classroomid” />             <generator class=”assigned” />         </id>         <property name=”classRoomName” type=”java.lang.String”>             <column name=”classroomname” />         </property>         <set name=”classes” lazy=”true” inverse=”true” cascade=”all-delete-orphan” table=”schedule”>             <key column=”classroomid”/>             <many-to-many class=”sample.orm.hibernate.Class” column=”classid”/>         </set>     </class> </hibernate-mapping>

它只定义了一个关联:和Class之间的多对多关联。4)Schedule.hbm.xml

代码如下:
<?xml version=”1.0″?> <!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”> <hibernate-mapping>     <class name=”sample.orm.hibernate.Schedule” table=”schedule” catalog=”test”>         <id name=”scheduleID” type=”java.lang.Integer”>             <column name=”scheduleid” />             <generator class=”assigned” />         </id>         <property name=”classID” type=”java.lang.Integer”>             <column name=”classid” />         </property>         <property name=”classRoomID” type=”java.lang.Integer”>             <column name=”classroomid” />         </property>     </class> </hibernate-mapping>

这里就不需要再定义关联了。我们需要在Hibernate全局配置文件中添加如下内容:

代码如下:
<mapping resource=”sample/orm/hibernate/Grade.hbm.xml” /><mapping resource=”sample/orm/hibernate/Class.hbm.xml” /><mapping resource=”sample/orm/hibernate/ClassRoom.hbm.xml” /><mapping resource=”sample/orm/hibernate/Schedule.hbm.xml” />

下面是各种测试方法,在有关联的情况下,Hibernate提供了下面几个特性:•延迟加载•级联添加•级联修改•级联删除

代码如下:
多表关联情况下的一些测试方法  private static void getClass(int gradeid) {     Session session = HibernateSessionManager.currentSession();     System.out.println(“=====Get Class info=====”);     Transaction transaction = session.beginTransaction();     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));     Hibernate.initialize(grade);     Iterator iterator = grade.getClasses().iterator();     System.out.println(“年级:” + grade.getGradeName() + “包括以下班级:”);     while(iterator.hasNext())     {         System.out.println(grade.getGradeName() + ((Class)iterator.next()).getClassName());     }     HibernateSessionManager.closeSession(); } private static void getSchedule(int gradeid) {     Session session = HibernateSessionManager.currentSession();     Transaction transaction = session.beginTransaction();     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));     if (grade != null)     {         System.out.println(“ID:” + grade.getGradeID() + “; Name:” + grade.getGradeName());     }     Hibernate.initialize(grade.getClasses());     Iterator iterator = grade.getClasses().iterator();     while(iterator.hasNext())     {         Class c = (Class)iterator.next();         System.out.println(grade.getGradeName() + c.getClassName() + “使用以下教室:”);         Hibernate.initialize(c.getClassrooms());         Iterator iterator1 = c.getClassrooms().iterator();         while(iterator1.hasNext())         {             System.out.println(((ClassRoom)iterator1.next()).getClassRoomName());         }     }     HibernateSessionManager.closeSession(); } private static void insertGrade() {     Session session = HibernateSessionManager.currentSession();     Transaction transaction = session.beginTransaction();     Grade grade = new Grade();     grade.setGradeID(4);     grade.setGradeName(“四年级”);     Class c1 = new Class();     c1.setClassID(7);     c1.setGrade(grade);     c1.setClassName(“一班”);     Class c2 = new Class();     c2.setClassID(8);     c2.setGrade(grade);     c2.setClassName(“二班”);     Set set = new HashSet();     set.add(c1);     set.add(c2);     grade.setClasses(set);     session.save(grade);     session.flush();     transaction.commit();     HibernateSessionManager.closeSession();     getClass(4); } private static void deleteGrade(int gradeid) {     Session session = HibernateSessionManager.currentSession();     Transaction transaction = session.beginTransaction();     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));     if (grade != null)     {         session.delete(grade);         session.flush();     }     transaction.commit();     grade = (Grade)session.get(Grade.class, new Integer(gradeid));     if (grade == null)     {         System.out.println(“删除成功”);     }     HibernateSessionManager.closeSession(); } private static void updateGrade1(int gradeid) {     Session session = HibernateSessionManager.currentSession();     Transaction transaction = session.beginTransaction();     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));     if (grade != null)     {         System.out.println(“ID:” + grade.getGradeID() + “; Name:” + grade.getGradeName());     }     grade.setGradeName(“Grade ” + gradeid);     session.save(grade);     session.flush();     transaction.commit();     HibernateSessionManager.closeSession();     getClass(gradeid); } private static void updateGrade2(int gradeid) {     Session session = HibernateSessionManager.currentSession();     Transaction transaction = session.beginTransaction();     Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));     if (grade != null)     {         System.out.println(“ID:” + grade.getGradeID() + “; Name:” + grade.getGradeName());     }     Grade newGrade = new Grade();     newGrade.setGradeID(10);     newGrade.setGradeName(grade.getGradeName());     Set set = grade.getClasses();     Set newSet = new HashSet();     Iterator iterator = set.iterator();     while(iterator.hasNext())     {         Class c = (Class)iterator.next();         Class temp = new Class();         temp.setClassID(c.getClassID());         temp.setClassName(c.getClassName());         temp.setGrade(newGrade);         newSet.add(temp);     }     newGrade.setClasses(newSet);     session.delete(grade);     session.flush();     session.save(newGrade);     session.flush();     transaction.commit();     grade = (Grade)session.get(Grade.class, new Integer(gradeid));     if (grade == null)     {         System.out.println(“删除成功”);     }     HibernateSessionManager.closeSession();     getClass(10); }

按顺序调用上面的方法:

代码如下:
getClass(1); getSchedule(1); insertGrade(); updateGrade1(4); updateGrade2(4); 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 4Hibernate: 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语句。iBatisiBatis是另外一种ORM框架,和Hibernate擅长操作单条记录不同,iBatis是基于SQL模板的,可以说,iBatis每次和数据库进行操作时,都有明确的SQL语句,而这些SQL语句,就是我们定义在配置文件中的。我们还是以test数据库中的user表为例,简单说明iBatis的操作流程:首先,我们还是需要定义VO对象,这里还是使用和Hibernate讲解时相同的User:

代码如下:
定义User对象  package sample.orm.ibatis; import java.io.Serializable; public class User implements Serializable {     private static final long serialVersionUID = 1L;     private int userID;     private String userName;     public void setUserID(int userID) {         this.userID = userID;     }     public int getUserID() {         return userID;     }     public void setUserName(String userName) {         this.userName = userName;     }     public String getUserName() {         return userName;     } }

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

代码如下:
<?xml version=”1.0″ encoding=”UTF-8″?> <!DOCTYPE sqlMap      PUBLIC “-//iBATIS.com//DTD SQL Map 2.0//EN”      “http://www.ibatis.com/dtd/sql-map-2.dtd”> <sqlMap namespace=”User”>     <typeAlias alias=”user” type=”sample.orm.ibatis.User” />          <cacheModel id=”user-cache” type=”OSCache” readOnly=”true” serialize=”true”>         <flushInterval milliseconds=”1″ />         <flushOnExecute statement=”insertUser” />         <flushOnExecute statement=”updateUser” />         <flushOnExecute statement=”getUser” />         <flushOnExecute statement=”getAllUser” />         <property value=”1″ name=”size” />      </cacheModel>     <!–     <resultMap >         <result property=”userID” column=”id” />         <result property=”userName” column=”name” />     </resultMap>     –>          <select id=”getUser” parameterClass=”java.lang.Integer” resultClass=”user” cacheModel=”user-cache” >         select id as userID,name as userName from user where id = #userID#     </select>     <select id=”getAllUser” resultClass=”user” cacheModel=”user-cache”>         select id as userID,name as userName from user     </select>     <update id=”updateUser” parameterClass=”user”>         update user SET name=#userName# WHERE id = #userID#     </update>     <insert id=”insertUser” parameterClass=”user”>         insert into user ( id, name ) VALUES ( #userID#,#userName#)     </insert>     <delete id=”deleteUser” parameterClass=”java.lang.Integer”>         delete from user where id=#userID#     </delete> </sqlMap>

这个配置文件主要包括三部分:1)缓存的配置2)对象属性和表字段之间的关联3)针对表的各种CRUD操作然后是关于iBatis的全局配置文件SqlMapConfig.xml:

代码如下:
<?xml version=”1.0″ encoding=”UTF-8″?> <!DOCTYPE sqlMapConfig      PUBLIC “-//iBATIS.com//DTD SQL Map Config 2.0//EN”      “http://www.ibatis.com/dtd/sql-map-config-2.dtd”> <sqlMapConfig>     <settings cacheModelsEnabled=”true” enhancementEnabled=”true”         lazyLoadingEnabled=”true” errorTracingEnabled=”true” maxRequests=”32″         maxSessions=”10″ maxTransactions=”5″ useStatementNamespaces=”false” />     <transactionManager type=”JDBC”>         <dataSource type=”SIMPLE”>            <property name=”JDBC.Driver” value=”com.mysql.jdbc.Driver” />            <property name=”JDBC.ConnectionURL” value=”jdbc:mysql://localhost/test” />            <property name=”JDBC.Username” value=”root” />            <property name=”JDBC.Password” value=”123″ />            <property name=”Pool.MaximumActiveConnections” value=”10″ />            <property name=”Pool.MaximumIdleConnections” value=”5″ />            <property name=”Pool.MaximumCheckoutTime” value=”120000″ />            <property name=”Pool.TimeToWait” value=”500″ />            <property name=”Pool.PingQuery” value=”select 1 from user” />            <property name=”Pool.PingEnabled” value=”false” />         </dataSource>     </transactionManager>     <sqlMap resource=”sample/orm/ibatis/User.xml” /> </sqlMapConfig>

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

代码如下:
iBatis测试方法  public class Sample {     private SqlMapClient sqlMap = null;     private void buildMap() throws IOException     {         String resource = “sample/orm/ibatis/SqlMapConfig.xml”;                   Reader reader = Resources.getResourceAsReader(resource);         this.sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);     }     private void insertUser() throws IOException, SQLException     {         System.out.println(“=====Insert test=====”);         if (this.sqlMap == null)         {             this.buildMap();         }         this.sqlMap.startTransaction();         User user = new User();         user.setUserID(10);         user.setUserName(“Angel”);         this.sqlMap.insert(“insertUser”, user);         this.sqlMap.commitTransaction();         user = getUser(10);         printUserInfo(user);     }     private void updateUser() throws IOException, SQLException, InterruptedException     {         System.out.println(“=====Update test=====”);         if (this.sqlMap == null)         {             this.buildMap();         }         this.sqlMap.startTransaction();         User user = new User();         user.setUserID(10);         user.setUserName(“Devil”);         this.sqlMap.update(“updateUser”, user);         this.sqlMap.commitTransaction();         this.sqlMap.flushDataCache(); //        Thread.sleep(3000);         user = getUser(10);         printUserInfo(user);     }     private void deleteUser() throws IOException, SQLException     {         System.out.println(“=====Delete test=====”);         if (this.sqlMap == null)         {             this.buildMap();         }         sqlMap.flushDataCache();         this.sqlMap.startTransaction();         this.sqlMap.delete(“deleteUser”, 10);         this.sqlMap.commitTransaction();         getAllUser();     }     private User getUser(int id) throws IOException, SQLException     {         if (this.sqlMap == null)         {             this.buildMap();         }         User user = (User)this.sqlMap.openSession().queryForObject(“getUser”, id);         return user;     }      private List<User> getAllUser() throws IOException, SQLException       {             if(this.sqlMap==null)                this.buildMap();          List userList=null;            userList=this.sqlMap.openSession().queryForList(“getAllUser”);          printUserInfo(userList);          return userList;      }      private void printUserInfo(User user)      {          System.out.println(“=====user info=====”);          System.out.println(“ID:” + user.getUserID() + “;Name:” + user.getUserName());      }      private void printUserInfo(List<User> users)      {          System.out.println(“=====user info=====”);          for(User user:users)          {              System.out.println(“ID:” + user.getUserID() + “;Name:” + user.getUserName());          }      }      public static void main(String[] args) throws IOException, SQLException, InterruptedException      {          Sample sample = new Sample();          sample.getAllUser();          sample.insertUser();          sample.updateUser();          sample.deleteUser();      } }

它的执行结果如下:

代码如下:
=====user info=====ID:1;Name:Zhang SanID: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 SanID:2;Name:TEST

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

本文地址:H5W3 » 基于Java ORM框架的使用详解

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址