Java回顾之ORM框架
来源:互联网 发布:淘宝女装网店名字 编辑:程序博客网 时间:2024/06/03 16:03
这篇文章里,我们主要讨论ORM框架,以及在使用上和JDBC的区别。
概述
ORM框架不是一个新话题,它已经流传了很多年。它的优点在于提供了概念性的、易于理解的数据模型,将数据库中的表和内存中的对象建立了很好的映射关系。
我们在这里主要关注Java中常用的两个ORM框架:Hibernate和iBatis。下面来介绍这两个框架简单的使用方法,如果将来有时间,我会深入的写一些更有意思的相关文章。
Hibernate
Hibernate是一个持久化框架和ORM框架,持久化和ORM是两个有区别的概念,持久化注重对象的存储方法是否随着程序的退出而消亡,ORM关注的是如何在数据库表和内存对象之间建立关联。
Hibernate使用POJO来表示Model,使用XML配置文件来配置对象和表之间的关系,它提供了一系列API来通过对对象的操作而改变数据库中的过程。
Hibernate更强调如何对单条记录进行操作,对于更复杂的操作,它提供了一种新的面向对象的查询语言:HQL。
我们先来定义一个关于Hibernate中Session管理的类,这里的Session类似于JDBC中的Connection。
Hibernate的Session管理类public class HibernateSessionManager { private static SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure("sample/orm/hibernate/hibernate.cfg.xml").buildSessionFactory(); } catch(Exception ex) { ex.printStackTrace(); } } public static final ThreadLocal tl = new ThreadLocal(); public static Session currentSession() { Session s = (Session)tl.get(); if (s == null) { s = sessionFactory.openSession(); tl.set(s); } return s; } public static void closeSession() { Session s = (Session)tl.get(); tl.set(null); if (s != null) { s.close(); } }}
基于单张表进行操作
下面我们来看一个简单的示例,它沿用了Java回顾之JDBC中的数据库,使用MySQL的test数据库中的user表。
首先,我们来定义VO对象:
定义User对象public class User implements Serializable{ private static final long serialVersionUID = 1L; private int userID; private String userName; public void setUserID(int userID) { this.userID = userID; } public int getUserID() { return userID; } public void setUserName(String userName) { this.userName = userName; } public String getUserName() { return userName; }}然后,我们定义User对象和数据库中user表之间的关联,user表中只有两列:id和name
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="sample.orm.hibernate.User" table="user" catalog="test"> <id name="userID" type="java.lang.Integer"> <column name="id" /> <generator class="assigned" /> </id> <property name="userName" type="java.lang.String"> <column name="name" /> </property> </class></hibernate-mapping>
将上述内容存储为User.hbm.xml。
接下来,我们需要定义一个关于Hibernate的全局配置文件,这里文件名是hibernate.cfg.xml。
<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/test</property> <property name="connection.username">root</property> <property name="connection.password">123</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="jdbc.fetch_size">50</property> <property name="jdbc.batch_size">25</property> <mapping resource="sample/orm/hibernate/User.hbm.xml" /> </session-factory></hibernate-configuration>
可以看到,上述配置文件中包含了数据库连接的信息,诸如driver信息、数据库url、用户名、密码等等,还包括了我们上面定义的User.hbm.xml。
最后,我们编写测试代码,来对user表进行增、删、查、改的操作:
使用Hibernate对user表进行操作private static void getUser(int id){ Session session = HibernateSessionManager.currentSession(); System.out.println("=====Query test====="); User user = (User)session.get(User.class, new Integer(id)); if (user != null) { System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName()); } HibernateSessionManager.closeSession();}private static void insertUser(){ Session session = HibernateSessionManager.currentSession(); System.out.println("=====Insert test====="); Transaction transaction = session.beginTransaction(); User user = new User(); user.setUserID(6); user.setUserName("Zhang Fei"); session.save(user); session.flush(); transaction.commit(); HibernateSessionManager.closeSession(); getUser(6);}private static void updateUser(int id){ Session session = HibernateSessionManager.currentSession(); System.out.println("=====Update test====="); Transaction transaction = session.beginTransaction(); User user = (User)session.get(User.class, new Integer(id)); System.out.println("=====Before Update====="); if (user != null) { System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName()); } user.setUserName("Devil"); session.save(user); session.flush(); transaction.commit(); user = (User)session.get(User.class, new Integer(id)); System.out.println("=====After Update====="); if (user != null) { System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName()); } HibernateSessionManager.closeSession();}private static void deleteUser(int id){ Session session = HibernateSessionManager.currentSession(); System.out.println("=====Delete test====="); Transaction transaction = session.beginTransaction(); User user = (User)session.get(User.class, new Integer(id)); System.out.println("=====Before Delte====="); if (user != null) { System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName()); } session.delete(user); transaction.commit(); user = (User)session.get(User.class, new Integer(id)); System.out.println("=====After Update====="); if (user != null) { System.out.println("ID:" + user.getUserID() + "; Name:" + user.getUserName()); } else { System.out.println("Delete successfully."); } HibernateSessionManager.closeSession();}我们按照如下顺序调用测试代码:
insertUser();updateUser(6);deleteUser(6);可以看到如下结果:
=====Insert test=====Hibernate: insert into test.user (name, id) values (?, ?)=====Query test=====Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from test.user user0_ where user0_.id=?ID:6; Name:Zhang Fei=====Update test=====Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from test.user user0_ where user0_.id=?=====Before Update=====ID:6; Name:Zhang FeiHibernate: update test.user set name=? where id=?=====After Update=====ID:6; Name:Devil=====Delete test=====Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from test.user user0_ where user0_.id=?=====Before Delte=====ID:6; Name:DevilHibernate: delete from test.user where id=?Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from test.user user0_ where user0_.id=?=====After Delete=====Delete successfully.
请注意,上面的结果中,输出了每次数据库操作时的SQL语句,这是因为在配置文件中有如下配置:
<property name="show_sql">true</property>
我们可以在开发调试阶段将其打开,在部署到客户方时,将其关闭。
基于多表关联的操作
Hibernate在建立多表关联时,根据主外键的设置,表之间的关联可以分为三种:一对一、一对多和多对多。这些关联会体现在表的配置文件以及VO中。
下面我们来看一个经典的多表关联示例:排课表。数据库中建立如下四张表:Grade/Class/ClassRoom/Schedule。刚发现,使用MySQL自带的管理器导出表定义基本是一件不可能的任务。。。。
上述各表除ID以及必要外键外,只有Name一列。
然后看各个VO的定义:
定义Grade对象package sample.orm.hibernate;import java.io.Serializable;import java.util.Set;public class Grade implements Serializable{ private static final long serialVersionUID = 1L; private int gradeID; private String gradeName; private Set classes; public void setGradeID(int gradeID) { this.gradeID = gradeID; } public int getGradeID() { return gradeID; } public void setGradeName(String gradeName) { this.gradeName = gradeName; } public String getGradeName() { return gradeName; } public void setClasses(Set classes) { this.classes = classes; } public Set getClasses() { return classes; }}
定义Class对象package sample.orm.hibernate;import java.io.Serializable;import java.util.Set;public class Class implements Serializable{ private static final long serialVersionUID = 1L; private int classID; private Grade grade; private Set classrooms; private String className; public void setClassID(int classID) { this.classID = classID; } public int getClassID() { return classID; } public void setClassName(String className) { this.className = className; } public String getClassName() { return className; } public void setGrade(Grade grade) { this.grade = grade; } public Grade getGrade() { return grade; } public void setClassrooms(Set classrooms) { this.classrooms = classrooms; } public Set getClassrooms() { return classrooms; }}
定义ClassRoom对象package sample.orm.hibernate;import java.io.Serializable;import java.util.Set;public class ClassRoom implements Serializable{ private static final long serialVersionUID = 1L; private int classRoomID; private String classRoomName; private Set classes; public void setClassRoomID(int classRoomID) { this.classRoomID = classRoomID; } public int getClassRoomID() { return classRoomID; } public void setClassRoomName(String classRoomName) { this.classRoomName = classRoomName; } public String getClassRoomName() { return classRoomName; } public void setClasses(Set classes) { this.classes = classes; } public Set getClasses() { return classes; }}
定义Schedule对象package sample.orm.hibernate;import java.io.Serializable;import java.util.Set;public class Schedule implements Serializable{ private static final long serialVersionUID = 1L; private int scheduleID; private int classRoomID; private int classID; private Set classes; public void setClassRoomID(int classRoomID) { this.classRoomID = classRoomID; } public int getClassRoomID() { return classRoomID; } public void setClassID(int classID) { this.classID = classID; } public int getClassID() { return classID; } public void setClasses(Set classes) { this.classes = classes; } public Set getClasses() { return classes; } public void setScheduleID(int scheduleID) { this.scheduleID = scheduleID; } public int getScheduleID() { return scheduleID; }}
接着是各个表的关联配置文件:
1)Grade.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="sample.orm.hibernate.Grade" table="grade" catalog="test"> <id name="gradeID" type="java.lang.Integer"> <column name="gradeid" /> <generator class="assigned" /> </id> <property name="gradeName" type="java.lang.String"> <column name="gradename" /> </property> <set name="classes" lazy="true" inverse="true" cascade="all-delete-orphan"> <key> <column name="gradeid"/> </key> <one-to-many class="sample.orm.hibernate.Class"/> </set> </class></hibernate-mapping>
注意上面的<set>配置,里面的<one-to-many>节点说明了Grade和Class之间一对多的关系。
2)Class.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="sample.orm.hibernate.Class" table="class" catalog="test"> <id name="classID" type="java.lang.Integer"> <column name="classid" /> <generator class="assigned" /> </id> <property name="className" type="java.lang.String"> <column name="classname" /> </property> <many-to-one name="grade" class="sample.orm.hibernate.Grade" lazy="proxy" not-null="true"> <column name="gradeid"/> </many-to-one> <set name="classrooms" lazy="true" inverse="true" cascade="all-delete-orphan" table="schedule"> <key column ="classid"/> <many-to-many class="sample.orm.hibernate.ClassRoom" column="classroomid"/> </set> </class></hibernate-mapping>
注意它定义两个关联:一个是和Grade之间多对一的关系,一个适合ClassRoom之间多对多的关系。
3)ClassRoom.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="sample.orm.hibernate.ClassRoom" table="classroom" catalog="test"> <id name="classRoomID" type="java.lang.Integer"> <column name="classroomid" /> <generator class="assigned" /> </id> <property name="classRoomName" type="java.lang.String"> <column name="classroomname" /> </property> <set name="classes" lazy="true" inverse="true" cascade="all-delete-orphan" table="schedule"> <key column="classroomid"/> <many-to-many class="sample.orm.hibernate.Class" column="classid"/> </set> </class></hibernate-mapping>
它只定义了一个关联:和Class之间的多对多关联。
4)Schedule.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="sample.orm.hibernate.Schedule" table="schedule" catalog="test"> <id name="scheduleID" type="java.lang.Integer"> <column name="scheduleid" /> <generator class="assigned" /> </id> <property name="classID" type="java.lang.Integer"> <column name="classid" /> </property> <property name="classRoomID" type="java.lang.Integer"> <column name="classroomid" /> </property> </class></hibernate-mapping>
这里就不需要再定义关联了。
我们需要在Hibernate全局配置文件中添加如下内容:
<mapping resource="sample/orm/hibernate/Grade.hbm.xml" /><mapping resource="sample/orm/hibernate/Class.hbm.xml" /><mapping resource="sample/orm/hibernate/ClassRoom.hbm.xml" /><mapping resource="sample/orm/hibernate/Schedule.hbm.xml" />
下面是各种测试方法,在有关联的情况下,Hibernate提供了下面几个特性:
- 延迟加载
- 级联添加
- 级联修改
- 级联删除
多表关联情况下的一些测试方法private static void getClass(int gradeid){ Session session = HibernateSessionManager.currentSession(); System.out.println("=====Get Class info====="); Transaction transaction = session.beginTransaction(); Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid)); Hibernate.initialize(grade); Iterator iterator = grade.getClasses().iterator(); System.out.println("年级:" + grade.getGradeName() + "包括以下班级:"); while(iterator.hasNext()) { System.out.println(grade.getGradeName() + ((Class)iterator.next()).getClassName()); } HibernateSessionManager.closeSession();}private static void getSchedule(int gradeid){ Session session = HibernateSessionManager.currentSession(); Transaction transaction = session.beginTransaction(); Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid)); if (grade != null) { System.out.println("ID:" + grade.getGradeID() + "; Name:" + grade.getGradeName()); } Hibernate.initialize(grade.getClasses()); Iterator iterator = grade.getClasses().iterator(); while(iterator.hasNext()) { Class c = (Class)iterator.next(); System.out.println(grade.getGradeName() + c.getClassName() + "使用以下教室:"); Hibernate.initialize(c.getClassrooms()); Iterator iterator1 = c.getClassrooms().iterator(); while(iterator1.hasNext()) { System.out.println(((ClassRoom)iterator1.next()).getClassRoomName()); } } HibernateSessionManager.closeSession();}private static void insertGrade(){ Session session = HibernateSessionManager.currentSession(); Transaction transaction = session.beginTransaction(); Grade grade = new Grade(); grade.setGradeID(4); grade.setGradeName("四年级"); Class c1 = new Class(); c1.setClassID(7); c1.setGrade(grade); c1.setClassName("一班"); Class c2 = new Class(); c2.setClassID(8); c2.setGrade(grade); c2.setClassName("二班"); Set set = new HashSet(); set.add(c1); set.add(c2); grade.setClasses(set); session.save(grade); session.flush(); transaction.commit(); HibernateSessionManager.closeSession(); getClass(4);}private static void deleteGrade(int gradeid){ Session session = HibernateSessionManager.currentSession(); Transaction transaction = session.beginTransaction(); Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid)); if (grade != null) { session.delete(grade); session.flush(); } transaction.commit(); grade = (Grade)session.get(Grade.class, new Integer(gradeid)); if (grade == null) { System.out.println("删除成功"); } HibernateSessionManager.closeSession();}private static void updateGrade1(int gradeid){ Session session = HibernateSessionManager.currentSession(); Transaction transaction = session.beginTransaction(); Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid)); if (grade != null) { System.out.println("ID:" + grade.getGradeID() + "; Name:" + grade.getGradeName()); } grade.setGradeName("Grade " + gradeid); session.save(grade); session.flush(); transaction.commit(); HibernateSessionManager.closeSession(); getClass(gradeid);}private static void updateGrade2(int gradeid){ Session session = HibernateSessionManager.currentSession(); Transaction transaction = session.beginTransaction(); Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid)); if (grade != null) { System.out.println("ID:" + grade.getGradeID() + "; Name:" + grade.getGradeName()); } Grade newGrade = new Grade(); newGrade.setGradeID(10); newGrade.setGradeName(grade.getGradeName()); Set set = grade.getClasses(); Set newSet = new HashSet(); Iterator iterator = set.iterator(); while(iterator.hasNext()) { Class c = (Class)iterator.next(); Class temp = new Class(); temp.setClassID(c.getClassID()); temp.setClassName(c.getClassName()); temp.setGrade(newGrade); newSet.add(temp); } newGrade.setClasses(newSet); session.delete(grade); session.flush(); session.save(newGrade); session.flush(); transaction.commit(); grade = (Grade)session.get(Grade.class, new Integer(gradeid)); if (grade == null) { System.out.println("删除成功"); } HibernateSessionManager.closeSession(); getClass(10);}按顺序调用上面的方法:
getClass(1);getSchedule(1);insertGrade();updateGrade1(4);updateGrade2(4);deleteGrade(10);执行结果如下:
=====Get Class info=====Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?年级:一年级包括以下班级:一年级二班一年级一班Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?ID:1; Name:一年级Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?一年级一班使用以下教室:Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?教室二教室五教室一一年级二班使用以下教室:Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?教室四教室二教室六Hibernate: select class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ from test.class class_ where class_.classid=?Hibernate: select class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ from test.class class_ where class_.classid=?Hibernate: insert into test.grade (gradename, gradeid) values (?, ?)Hibernate: insert into test.class (classname, gradeid, classid) values (?, ?, ?)Hibernate: insert into test.class (classname, gradeid, classid) values (?, ?, ?)=====Get Class info=====Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?年级:四年级包括以下班级:四年级二班四年级一班Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?ID:4; Name:四年级Hibernate: update test.grade set gradename=? where gradeid=?=====Get Class info=====Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?年级:Grade 4包括以下班级:Grade 4二班Grade 4一班Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?ID:4; Name:Grade 4Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?Hibernate: delete from test.class where classid=?Hibernate: delete from test.class where classid=?Hibernate: delete from test.grade where gradeid=?Hibernate: select class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ from test.class class_ where class_.classid=?Hibernate: select class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ from test.class class_ where class_.classid=?Hibernate: insert into test.grade (gradename, gradeid) values (?, ?)Hibernate: insert into test.class (classname, gradeid, classid) values (?, ?, ?)Hibernate: insert into test.class (classname, gradeid, classid) values (?, ?, ?)Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?删除成功=====Get Class info=====Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?年级:Grade 4包括以下班级:Grade 4一班Grade 4二班Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?Hibernate: select classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ from test.class classes0_ where classes0_.gradeid=?Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?Hibernate: select classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ from schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?Hibernate: delete from test.class where classid=?Hibernate: delete from test.class where classid=?Hibernate: delete from test.grade where gradeid=?Hibernate: select grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ from test.grade grade0_ where grade0_.gradeid=?删除成功
同样,执行结果中包含了各个SQL语句。
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 SanID:2;Name:TEST=====Insert test==========user info=====ID:10;Name:Angel=====Update test==========user info=====ID:10;Name:Devil=====Delete test==========user info=====ID:1;Name:Zhang SanID:2;Name:TEST
这篇文章只是简单介绍了Hibernate和iBatis的用法,并没有涉及全部,例如Hibernate的事务、拦截、HQL、iBatis的缓存等等。这里主要是为了描述ORM框架的基本轮廓,以及在使用方式上它和JDBC的区别。
- Java回顾之ORM框架
- Java回顾之ORM框架
- ORM 框架之 GreenDao
- Java ORM 框架
- Android ORM框架之 ORMLite
- Android ORM 框架之 ActiveAndroid
- Android ORM 框架之 greenDAO
- Android ORM 框架之 greenDAO
- Android ORM 框架之 greenDAO
- Android ORM 框架之 greenDAO
- Android ORM 框架之 greenDAO
- Android ORM框架之GreenDAO
- Android ORM框架之greenDAO
- Android ORM 框架之 greenDAO
- ORM 框架之 greenDAO 使用
- java开源mongodb orm框架
- 自己动手写ORM框架-java
- Java 回顾笔记_集合框架之_linkedList_arrayList
- 欢迎使用CSDN-markdown编辑器
- hiho121
- java.lang.UnsatisfiedLinkError: Native method not found: com.baidu.platform.comjni.engine.JNIEngine.
- android常用控件ViewPager(二) ViewPager与Fragment
- 汇编语言之寄存器(详细介绍)
- Java回顾之ORM框架
- 雷塞DMC1380的使用:常用编程函数
- [uboot] (第四章)uboot流程——uboot编译流程
- C语言文件概述
- AspectJ 在spring项目中的maven配置
- 解决(CRON) info (No MTA installed, discarding output)
- Nim游戏
- 使用canvas绘制一个时钟
- vue实例