基于Java ORM框架的使用详解
基于Java ORM框架的使用详解
发布时间:2016-12-28 来源:查字典编辑
摘要:ORM框架不是一个新话题,它已经流传了很多年。它的优点在于提供了概念性的、易于理解的数据模型,将数据库中的表和内存中的对象建立了很好的映射关...

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 />

</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 />

</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/>

</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 />

</id>

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

<column name="classname" />

</property>

<many-to-one name="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 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 />

</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 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 />

</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>

<>

<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的区别。

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Java学习
热门Java学习
编程开发子分类