zoukankan      html  css  js  c++  java
  • Java回顾之ORM框架

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

      概述

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

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

      Hibernate

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

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

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

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

    复制代码
     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对象:

    复制代码
     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表进行增、删、查、改的操作:

    复制代码
     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的定义:

    复制代码
     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 }
    复制代码
    复制代码
     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 }
    复制代码
    复制代码
     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 }
    复制代码
    复制代码
     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:

    复制代码
     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。

      下面是测试方法:

    复制代码
      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的区别。

  • 相关阅读:
    hdu 3666 差分约束系统
    hdu 1198农田灌溉
    常微分方程(阿諾爾德) Page 45 相空間,相流,運動,相曲線 註記
    高等微積分(高木貞治) 1.4節 例2
    常微分方程(阿諾爾德) Page 45 相空間,相流,運動,相曲線 註記
    解析函數論 Page 29 命題(2) 函數模的有界性
    高等微積分(高木貞治) 1.4節 例2
    解析函數論 Page 29 命題(1) 有界閉集上的一致連續性
    解析函數論 Page 29 命題(3) 模的下界的可達性
    解析函數論 Page 29 命題(2) 函數模的有界性
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3443713.html
Copyright © 2011-2022 走看看