欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于Java ORM框架的使用详解

程序员文章站 2023-12-17 08:46:16
orm框架不是一个新话题,它已经流传了很多年。它的优点在于提供了概念性的、易于理解的数据模型,将数据库中的表和内存中的对象建立了很好的映射关系。我们在这里主要关注java中...
orm框架不是一个新话题,它已经流传了很多年。它的优点在于提供了概念性的、易于理解的数据模型,将数据库中的表和内存中的对象建立了很好的映射关系。
我们在这里主要关注java中常用的两个orm框架:hibernate和ibatis。下面来介绍这两个框架简单的使用方法,如果将来有时间,我会深入的写一些更有意思的相关文章。
hibernate
hibernate是一个持久化框架和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 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对象
 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 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对象
 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 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的区别。

上一篇:

下一篇: