Java回顾之ORM框架
添加时间:2013-5-14 点击量:
第一篇:Java回顾之I/O
第二篇:Java回顾之收集通信
第三篇:Java回顾之多线程
第四篇:Java回顾之多线程同步
第五篇:Java回顾之凑集
第六篇:Java回顾之序列化
第七篇:Java回顾之反射
第八篇:Java回顾之一些根蒂根基概念
第九篇:Java回顾之JDBC
这篇文章里,我们首要评论辩论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经管类
1 public class HibernateSessionManager {
2
3 private static SessionFactory sessionFactory;
4
5 static
6 {
7 try
8 {
9 sessionFactory = new Configuration().configure(sample/orm/hibernate/hibernate.cfg.xml).buildSessionFactory();
10 }
11 catch(Exception ex)
12 {
13 ex.printStackTrace();
14 }
15 }
16
17 public static final ThreadLocal tl = new ThreadLocal();
18
19 public static Session currentSession()
20 {
21 Session s = (Session)tl.get();
22 if (s == null)
23 {
24 s = sessionFactory.openSession();
25 tl.set(s);
26 }
27
28 return s;
29 }
30
31 public static void closeSession()
32 {
33 Session s = (Session)tl.get();
34 tl.set(null);
35 if (s != null)
36 {
37 s.close();
38 }
39 }
40 }
基于单张表进行操纵
下面我们来看一个简单的示例,它沿用了Java回顾之JDBC中的数据库,应用MySQL的test数据库中的user表。
起首,我们来定义VO对象:
定义User对象
1 public class User implements Serializable
2 {
3 private static final long serialVersionUID = 1L;
4 private int userID;
5 private String userName;
6 public void setUserID(int userID) {
7 this.userID = userID;
8 }
9 public int getUserID() {
10 return userID;
11 }
12 public void setUserName(String userName) {
13 this.userName = userName;
14 }
15 public String getUserName() {
16 return userName;
17 }
18 }
然后,我们定义User对象和数据库中user表之间的接洽关系,user表中只有两列:id和name。
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.User table=user catalog=test>
7 <id name=userID type=java.lang.Integer>
8 <column name=id />
9 <generator class=assigned />
10 </id>
11 <property name=userName type=java.lang.String>
12 <column name=name />
13 </property>
14 </class>
15 </hibernate-mapping>
将上述内容存储为User.hbm.xml。
接下来,我们须要定义一个关于Hibernate的全局设备文件,这里文件名是hibernate.cfg.xml。
1 <?xml version=1.0 encoding=UTF-8?>
2 <!DOCTYPE hibernate-configuration PUBLIC
3 -//Hibernate/Hibernate Configuration DTD 3.0//EN
4 http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd>
5
6 <hibernate-configuration>
7 <session-factory>
8 <property name=connection.driver_class>com.mysql.jdbc.Driver</property>
9 <property name=connection.url>jdbc:mysql://localhost/test</property>
10 <property name=connection.username>root</property>
11 <property name=connection.password>123</property>
12 <property name=dialect>org.hibernate.dialect.MySQLDialect</property>
13 <property name=show_sql>true</property>
14 <property name=jdbc.fetch_size>50</property>
15 <property name=jdbc.batch_size>25</property>
16
17 <mapping resource=sample/orm/hibernate/User.hbm.xml />
18 </session-factory>
19 </hibernate-configuration>
可以看到,上述设备文件中包含了数据库连接的信息,诸如driver信息、数据库url、用户名、暗码等等,还包含了我们上方定义的User.hbm.xml。
最后,我们编写测试代码,来对user表进行增、删、查、改的操纵:
应用Hibernate对user表进行操纵
1 private static void getUser(int id)
2 {
3 Session session = HibernateSessionManager.currentSession();
4 System.out.println(=====Query test=====);
5 User user = (User)session.get(User.class, new Integer(id));
6 if (user != null)
7 {
8 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
9 }
10 HibernateSessionManager.closeSession();
11 }
12
13 private static void User()
14 {
15 Session session = HibernateSessionManager.currentSession();
16 System.out.println(=====Insert test=====);
17 Transaction transaction = session.beginTransaction();
18 User user = new User();
19 user.setUserID(6);
20 user.setUserName(Zhang Fei);
21 session.save(user);
22 session.flush();
23 transaction.commit();
24 HibernateSessionManager.closeSession();
25 getUser(6);
26 }
27
28 private static void User(int id)
29 {
30 Session session = HibernateSessionManager.currentSession();
31 System.out.println(=====Update test=====);
32 Transaction transaction = session.beginTransaction();
33 User user = (User)session.get(User.class, new Integer(id));
34 System.out.println(=====Before Update=====);
35 if (user != null)
36 {
37 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
38 }
39 user.setUserName(Devil);
40 session.save(user);
41 session.flush();
42 transaction.commit();
43 user = (User)session.get(User.class, new Integer(id));
44 System.out.println(=====After Update=====);
45 if (user != null)
46 {
47 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
48 }
49 HibernateSessionManager.closeSession();
50 }
51
52 private static void User(int id)
53 {
54 Session session = HibernateSessionManager.currentSession();
55 System.out.println(=====Delete test=====);
56 Transaction transaction = session.beginTransaction();
57 User user = (User)session.get(User.class, new Integer(id));
58 System.out.println(=====Before Delte=====);
59 if (user != null)
60 {
61 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
62 }
63 session.(user);
64 transaction.commit();
65 user = (User)session.get(User.class, new Integer(id));
66 System.out.println(=====After Update=====);
67 if (user != null)
68 {
69 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
70 }
71 else
72 {
73 System.out.println(Delete successfully.);
74 }
75 HibernateSessionManager.closeSession();
76 }
我们遵守如下次序调用测试代码:
1 User();
2 User(6);
3 User(6);
可以看到如下成果:
=====Insert test=====
Hibernate: into test.user (name, id) values (?, ?)
=====Query test=====
Hibernate: user0_.id as id0_, user0_.name as name0_0_ test.user user0_ where user0_.id=?
ID:6; Name:Zhang Fei
=====Update test=====
Hibernate: user0_.id as id0_, user0_.name as name0_0_ test.user user0_ where user0_.id=?
=====Before Update=====
ID:6; Name:Zhang Fei
Hibernate: test.user set name=? where id=?
=====After Update=====
ID:6; Name:Devil
=====Delete test=====
Hibernate: user0_.id as id0_, user0_.name as name0_0_ test.user user0_ where user0_.id=?
=====Before Delte=====
ID:6; Name:Devil
Hibernate: test.user where id=?
Hibernate: user0_.id as id0_, user0_.name as name0_0_ 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对象
1 package sample.orm.hibernate;
2
3 import java.io.Serializable;
4 import java.util.Set;
5
6 public class Grade implements Serializable
7 {
8 private static final long serialVersionUID = 1L;
9 private int gradeID;
10 private String gradeName;
11 private Set classes;
12 public void setGradeID(int gradeID) {
13 this.gradeID = gradeID;
14 }
15 public int getGradeID() {
16 return gradeID;
17 }
18 public void setGradeName(String gradeName) {
19 this.gradeName = gradeName;
20 }
21 public String getGradeName() {
22 return gradeName;
23 }
24 public void setClasses(Set classes) {
25 this.classes = classes;
26 }
27 public Set getClasses() {
28 return classes;
29 }
30 }
定义Class对象
1 package sample.orm.hibernate;
2
3 import java.io.Serializable;
4 import java.util.Set;
5
6 public class Class implements Serializable
7 {
8 private static final long serialVersionUID = 1L;
9 private int classID;
10 private Grade grade;
11 private Set classrooms;
12 private String className;
13 public void setClassID(int classID) {
14 this.classID = classID;
15 }
16 public int getClassID() {
17 return classID;
18 }
19 public void setClassName(String className) {
20 this.className = className;
21 }
22 public String getClassName() {
23 return className;
24 }
25 public void setGrade(Grade grade) {
26 this.grade = grade;
27 }
28 public Grade getGrade() {
29 return grade;
30 }
31 public void setClassrooms(Set classrooms) {
32 this.classrooms = classrooms;
33 }
34 public Set getClassrooms() {
35 return classrooms;
36 }
37 }
定义ClassRoom对象
1 package sample.orm.hibernate;
2
3 import java.io.Serializable;
4 import java.util.Set;
5
6 public class ClassRoom implements Serializable
7 {
8 private static final long serialVersionUID = 1L;
9 private int classRoomID;
10 private String classRoomName;
11 private Set classes;
12 public void setClassRoomID(int classRoomID) {
13 this.classRoomID = classRoomID;
14 }
15 public int getClassRoomID() {
16 return classRoomID;
17 }
18 public void setClassRoomName(String classRoomName) {
19 this.classRoomName = classRoomName;
20 }
21 public String getClassRoomName() {
22 return classRoomName;
23 }
24 public void setClasses(Set classes) {
25 this.classes = classes;
26 }
27 public Set getClasses() {
28 return classes;
29 }
30 }
定义Schedule对象
1 package sample.orm.hibernate;
2
3 import java.io.Serializable;
4 import java.util.Set;
5
6 public class Schedule implements Serializable
7 {
8 private static final long serialVersionUID = 1L;
9 private int scheduleID;
10 private int classRoomID;
11 private int classID;
12 private Set classes;
13 public void setClassRoomID(int classRoomID) {
14 this.classRoomID = classRoomID;
15 }
16 public int getClassRoomID() {
17 return classRoomID;
18 }
19 public void setClassID(int classID) {
20 this.classID = classID;
21 }
22 public int getClassID() {
23 return classID;
24 }
25 public void setClasses(Set classes) {
26 this.classes = classes;
27 }
28 public Set getClasses() {
29 return classes;
30 }
31 public void setScheduleID(int scheduleID) {
32 this.scheduleID = scheduleID;
33 }
34 public int getScheduleID() {
35 return scheduleID;
36 }
37 }
接着是各个表的接洽关系设备文件:
1)Grade.hbm.xml
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.Grade table=grade catalog=test>
7 <id name=gradeID type=java.lang.Integer>
8 <column name=gradeid />
9 <generator class=assigned />
10 </id>
11 <property name=gradeName type=java.lang.String>
12 <column name=gradename />
13 </property>
14
15 <set name=classes lazy=true inverse=true cascade=all--orphan>
16 <key>
17 <column name=gradeid/>
18 </key>
19 <one-to-many class=sample.orm.hibernate.Class/>
20 </set>
21 </class>
22 </hibernate-mapping>
重视上方的<set>设备,里面的<one-to-many>节点说了然Grade和Class之间一对多的关系。
2)Class.hbm.xml
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.Class table=class catalog=test>
7 <id name=classID type=java.lang.Integer>
8 <column name=classid />
9 <generator class=assigned />
10 </id>
11 <property name=className type=java.lang.String>
12 <column name=classname />
13 </property>
14
15 <many-to-one name=grade class=sample.orm.hibernate.Grade lazy=proxy not-null=true>
16 <column name=gradeid/>
17 </many-to-one>
18
19 <set name=classrooms lazy=true inverse=true cascade=all--orphan table=schedule>
20 <key column =classid/>
21 <many-to-many class=sample.orm.hibernate.ClassRoom column=classroomid/>
22 </set>
23 </class>
24 </hibernate-mapping>
重视它定义两个接洽关系:一个是和Grade之间多对一的关系,一个合适ClassRoom之间多对多的关系。
3)ClassRoom.hbm.xml
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.ClassRoom table=classroom catalog=test>
7 <id name=classRoomID type=java.lang.Integer>
8 <column name=classroomid />
9 <generator class=assigned />
10 </id>
11 <property name=classRoomName type=java.lang.String>
12 <column name=classroomname />
13 </property>
14
15 <set name=classes lazy=true inverse=true cascade=all--orphan table=schedule>
16 <key column=classroomid/>
17 <many-to-many class=sample.orm.hibernate.Class column=classid/>
18 </set>
19 </class>
20 </hibernate-mapping>
它只定义了一个接洽关系:和Class之间的多对多接洽关系。
4)Schedule.hbm.xml
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.Schedule table=schedule catalog=test>
7 <id name=scheduleID type=java.lang.Integer>
8 <column name=scheduleid />
9 <generator class=assigned />
10 </id>
11 <property name=classID type=java.lang.Integer>
12 <column name=classid />
13 </property>
14 <property name=classRoomID type=java.lang.Integer>
15 <column name=classroomid />
16 </property>
17 </class>
18 </hibernate-mapping>
这里就不须要再定义接洽关系了。
我们须要在Hibernate全局设备文件中添加如下内容:
1 <mapping resource=sample/orm/hibernate/Grade.hbm.xml />
2 <mapping resource=sample/orm/hibernate/Class.hbm.xml />
3 <mapping resource=sample/orm/hibernate/ClassRoom.hbm.xml />
4 <mapping resource=sample/orm/hibernate/Schedule.hbm.xml />
下面是各类测试办法,在有接洽关系的景象下,Hibernate供给了下面几个特点:
- 延迟加载
- 级联添加
- 级联批改
- 级联删除
多表接洽关系景象下的一些测试办法
1 private static void getClass(int gradeid)
2 {
3 Session session = HibernateSessionManager.currentSession();
4 System.out.println(=====Get Class info=====);
5 Transaction transaction = session.beginTransaction();
6 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
7
8 Hibernate.initialize(grade);
9 Iterator iterator = grade.getClasses().iterator();
10 System.out.println(年级: + grade.getGradeName() + 包含以放工级:);
11 while(iterator.hasNext())
12 {
13 System.out.println(grade.getGradeName() + ((Class)iterator.next()).getClassName());
14 }
15 HibernateSessionManager.closeSession();
16 }
17
18 private static void getSchedule(int gradeid)
19 {
20 Session session = HibernateSessionManager.currentSession();
21 Transaction transaction = session.beginTransaction();
22 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
23 if (grade != null)
24 {
25 System.out.println(ID: + grade.getGradeID() + ; Name: + grade.getGradeName());
26 }
27
28 Hibernate.initialize(grade.getClasses());
29
30 Iterator iterator = grade.getClasses().iterator();
31 while(iterator.hasNext())
32 {
33 Class c = (Class)iterator.next();
34 System.out.println(grade.getGradeName() + c.getClassName() + 应用以下教室:);
35 Hibernate.initialize(c.getClassrooms());
36 Iterator iterator1 = c.getClassrooms().iterator();
37 while(iterator1.hasNext())
38 {
39 System.out.println(((ClassRoom)iterator1.next()).getClassRoomName());
40 }
41 }
42 HibernateSessionManager.closeSession();
43 }
44
45 private static void Grade()
46 {
47 Session session = HibernateSessionManager.currentSession();
48 Transaction transaction = session.beginTransaction();
49 Grade grade = new Grade();
50 grade.setGradeID(4);
51 grade.setGradeName(四年级);
52
53 Class c1 = new Class();
54 c1.setClassID(7);
55 c1.setGrade(grade);
56 c1.setClassName(一班);
57 Class c2 = new Class();
58 c2.setClassID(8);
59 c2.setGrade(grade);
60 c2.setClassName(二班);
61
62 Set set = new HashSet();
63 set.add(c1);
64 set.add(c2);
65
66 grade.setClasses(set);
67
68 session.save(grade);
69 session.flush();
70 transaction.commit();
71 HibernateSessionManager.closeSession();
72 getClass(4);
73 }
74
75 private static void Grade(int gradeid)
76 {
77 Session session = HibernateSessionManager.currentSession();
78 Transaction transaction = session.beginTransaction();
79 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
80 if (grade != null)
81 {
82 session.(grade);
83 session.flush();
84 }
85
86 transaction.commit();
87
88 grade = (Grade)session.get(Grade.class, new Integer(gradeid));
89 if (grade == null)
90 {
91 System.out.println(删除成功);
92 }
93 HibernateSessionManager.closeSession();
94 }
95
96 private static void Grade1(int gradeid)
97 {
98 Session session = HibernateSessionManager.currentSession();
99 Transaction transaction = session.beginTransaction();
100 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
101 if (grade != null)
102 {
103 System.out.println(ID: + grade.getGradeID() + ; Name: + grade.getGradeName());
104 }
105 grade.setGradeName(Grade + gradeid);
106 session.save(grade);
107 session.flush();
108 transaction.commit();
109 HibernateSessionManager.closeSession();
110 getClass(gradeid);
111 }
112
113 private static void Grade2(int gradeid)
114 {
115 Session session = HibernateSessionManager.currentSession();
116 Transaction transaction = session.beginTransaction();
117 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
118 if (grade != null)
119 {
120 System.out.println(ID: + grade.getGradeID() + ; Name: + grade.getGradeName());
121 }
122
123 Grade newGrade = new Grade();
124 newGrade.setGradeID(10);
125 newGrade.setGradeName(grade.getGradeName());
126 Set set = grade.getClasses();
127 Set newSet = new HashSet();
128 Iterator iterator = set.iterator();
129 while(iterator.hasNext())
130 {
131 Class c = (Class)iterator.next();
132 Class temp = new Class();
133 temp.setClassID(c.getClassID());
134 temp.setClassName(c.getClassName());
135 temp.setGrade(newGrade);
136 newSet.add(temp);
137 }
138 newGrade.setClasses(newSet);
139 session.(grade);
140 session.flush();
141 session.save(newGrade);
142 session.flush();
143 transaction.commit();
144 grade = (Grade)session.get(Grade.class, new Integer(gradeid));
145 if (grade == null)
146 {
147 System.out.println(删除成功);
148 }
149 HibernateSessionManager.closeSession();
150 getClass(10);
151 }
按次序调用上方的办法:
1 getClass(1);
2 getSchedule(1);
3 Grade();
4 Grade1(4);
5 Grade2(4);
6 Grade(10);
履行成果如下:
=====Get Class info=====
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
年级:一年级包含以放工级:
一年级二班
一年级一班
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
ID:1; Name:一年级
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
一年级一班应用以下教室:
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
教室二
教室五
教室一
一年级二班应用以下教室:
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
教室四
教室二
教室六
Hibernate: class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ test.class class_ where class_.classid=?
Hibernate: class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ test.class class_ where class_.classid=?
Hibernate: into test.grade (gradename, gradeid) values (?, ?)
Hibernate: into test.class (classname, gradeid, classid) values (?, ?, ?)
Hibernate: into test.class (classname, gradeid, classid) values (?, ?, ?)
=====Get Class info=====
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
年级:四年级包含以放工级:
四年级二班
四年级一班
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
ID:4; Name:四年级
Hibernate: test.grade set gradename=? where gradeid=?
=====Get Class info=====
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
年级:Grade 4包含以放工级:
Grade 4二班
Grade 4一班
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
ID:4; Name:Grade 4
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
Hibernate: test.class where classid=?
Hibernate: test.class where classid=?
Hibernate: test.grade where gradeid=?
Hibernate: class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ test.class class_ where class_.classid=?
Hibernate: class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ test.class class_ where class_.classid=?
Hibernate: into test.grade (gradename, gradeid) values (?, ?)
Hibernate: into test.class (classname, gradeid, classid) values (?, ?, ?)
Hibernate: into test.class (classname, gradeid, classid) values (?, ?, ?)
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
删除成功
=====Get Class info=====
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
年级:Grade 4包含以放工级:
Grade 4一班
Grade 4二班
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
Hibernate: test.class where classid=?
Hibernate: test.class where classid=?
Hibernate: test.grade where gradeid=?
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
删除成功
同样,履行成果中包含了各个SQL语句。
iBatis
iBatis是别的一种ORM框架,和Hibernate善于操纵单笔记录不合,iBatis是基于SQL模板的,可以说,iBatis每次和数据库进行操纵时,都有明白的SQL语句,而这些SQL语句,就是我们定义在设备文件中的。
我们还是以test数据库中的user表为例,简单申明iBatis的操纵流程:
起首,我们还是须要定义VO对象,这里还是应用和Hibernate讲解时雷同的User:
定义User对象
1 package sample.orm.ibatis;
2
3 import java.io.Serializable;
4
5 public class User implements Serializable
6 {
7 private static final long serialVersionUID = 1L;
8 private int userID;
9 private String userName;
10 public void setUserID(int userID) {
11 this.userID = userID;
12 }
13 public int getUserID() {
14 return userID;
15 }
16 public void setUserName(String userName) {
17 this.userName = userName;
18 }
19 public String getUserName() {
20 return userName;
21 }
22
23 }
然后须要针对这个VO,定义一个自力的设备文件:User.xml
1 <?xml version=1.0 encoding=UTF-8?>
2 <!DOCTYPE sqlMap
3 PUBLIC -//iBATIS.com//DTD SQL Map 2.0//EN
4 http://www.ibatis.com/dtd/sql-map-2.dtd>
5
6 <sqlMap namespace=User>
7
8 <typeAlias alias=user type=sample.orm.ibatis.User />
9
10
11 <cacheModel id=user-cache type=OSCache readOnly=true serialize=true>
12 <flushInterval milliseconds=1 />
13 <flushOnute statement=User />
14 <flushOnute statement=User />
15 <flushOnute statement=getUser />
16 <flushOnute statement=getAllUser />
17 <property value=1 name=size />
18 </cacheModel>
19
20 <!--
21 <resultMap >
22 <result property=userID column=id />
23 <result property=userName column=name />
24 </resultMap>
25 -->
26
27
28 < id=getUser parameterClass=java.lang.Integer resultClass=user cacheModel=user-cache >
29 id as userID,name as userName user where id = #userID#
30 </>
31 < id=getAllUser resultClass=user cacheModel=user-cache>
32 id as userID,name as userName user
33 </>
34 < id=User parameterClass=user>
35 user SET name=#userName# WHERE id = #userID#
36 </>
37 < id=User parameterClass=user>
38 into user ( id, name ) VALUES ( #userID#,#userName#)
39 </>
40 < id=User parameterClass=java.lang.Integer>
41 user where id=#userID#
42 </>
43
44 </sqlMap>
这个设备文件首要包含三项目组:
1)缓存的设备
2)对象属性和表字段之间的接洽关系
3)针对表的各类CRUD操纵
然后是关于iBatis的全局设备文件SqlMapConfig.xml:
1 <?xml version=1.0 encoding=UTF-8?>
2 <!DOCTYPE sqlMapConfig
3 PUBLIC -//iBATIS.com//DTD SQL Map Config 2.0//EN
4 http://www.ibatis.com/dtd/sql-map-config-2.dtd>
5
6 <sqlMapConfig>
7
8 <settings cacheModelsEnabled=true enhancementEnabled=true
9 lazyLoadingEnabled=true errorTracingEnabled=true maxRequests=32
10 maxSessions=10 maxTransactions=5 useStatementNamespaces=false />
11
12 <transactionManager type=JDBC>
13 <dataSource type=SIMPLE>
14 <property name=JDBC.Driver value=com.mysql.jdbc.Driver />
15 <property name=JDBC.ConnectionURL value=jdbc:mysql://localhost/test />
16 <property name=JDBC.Username value=root />
17 <property name=JDBC.Password value=123 />
18 <property name=Pool.MaximumActiveConnections value=10 />
19 <property name=Pool.MaximumIdleConnections value=5 />
20 <property name=Pool.MaximumCheckoutTime value=120000 />
21 <property name=Pool.TimeToWait value=500 />
22 <property name=Pool.PingQuery value= 1 user />
23 <property name=Pool.PingEnabled value=false />
24 </dataSource>
25 </transactionManager>
26
27 <sqlMap resource=sample/orm/ibatis/User.xml />
28
29 </sqlMapConfig>
和Hibernate全局设备文件类似,它也包含了数据库连接的信息、数据库连接池的信息以及我们定义的User.xml。
下面是测试办法:
iBatis测试办法
1 public class Sample {
2
3 private SqlMapClient sqlMap = null;
4
5 private void buildMap() throws IOException
6 {
7 String resource = sample/orm/ibatis/SqlMapConfig.xml;
8 Reader reader = Resources.getResourceAsReader(resource);
9 this.sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
10 }
11
12 private void User() throws IOException, SQLException
13 {
14 System.out.println(=====Insert test=====);
15 if (this.sqlMap == null)
16 {
17 this.buildMap();
18 }
19 this.sqlMap.startTransaction();
20 User user = new User();
21 user.setUserID(10);
22 user.setUserName(Angel);
23
24 this.sqlMap.(User, user);
25 this.sqlMap.commitTransaction();
26
27 user = getUser(10);
28 printUserInfo(user);
29 }
30
31 private void User() throws IOException, SQLException, InterruptedException
32 {
33 System.out.println(=====Update test=====);
34 if (this.sqlMap == null)
35 {
36 this.buildMap();
37 }
38 this.sqlMap.startTransaction();
39 User user = new User();
40 user.setUserID(10);
41 user.setUserName(Devil);
42 this.sqlMap.(User, user);
43 this.sqlMap.commitTransaction();
44 this.sqlMap.flushDataCache();
45 // Thread.sleep(3000);
46 user = getUser(10);
47 printUserInfo(user);
48 }
49
50 private void User() throws IOException, SQLException
51 {
52 System.out.println(=====Delete test=====);
53 if (this.sqlMap == null)
54 {
55 this.buildMap();
56 }
57 sqlMap.flushDataCache();
58 this.sqlMap.startTransaction();
59 this.sqlMap.(User, 10);
60 this.sqlMap.commitTransaction();
61 getAllUser();
62 }
63
64 private User getUser(int id) throws IOException, SQLException
65 {
66 if (this.sqlMap == null)
67 {
68 this.buildMap();
69 }
70 User user = (User)this.sqlMap.openSession().queryForObject(getUser, id);
71
72 return user;
73 }
74
75 private List<User> getAllUser() throws IOException, SQLException
76 {
77 if(this.sqlMap==null)
78 this.buildMap();
79
80 List userList=null;
81 userList=this.sqlMap.openSession().queryForList(getAllUser);
82 printUserInfo(userList);
83 return userList;
84 }
85
86 private void printUserInfo(User user)
87 {
88 System.out.println(=====user info=====);
89 System.out.println(ID: + user.getUserID() + ;Name: + user.getUserName());
90 }
91
92 private void printUserInfo(List<User> users)
93 {
94 System.out.println(=====user info=====);
95 for(User user:users)
96 {
97 System.out.println(ID: + user.getUserID() + ;Name: + user.getUserName());
98 }
99 }
100
101 public static void main(String[] args) throws IOException, SQLException, InterruptedException
102 {
103 Sample sample = new Sample();
104 sample.getAllUser();
105 sample.User();
106 sample.User();
107 sample.User();
108 }
109 }
它的履行成果如下:
=====user info=====
ID:1;Name:Zhang San
ID:2;Name:TEST
=====Insert test=====
=====user info=====
ID:10;Name:Angel
=====Update test=====
=====user info=====
ID:10;Name:Devil
=====Delete test=====
=====user info=====
ID:1;Name:Zhang San
ID:2;Name:TEST
这篇文章只是简单介绍了Hibernate和iBatis的用法,并没有涉及全部,例如Hibernate的事务、阻碍、HQL、iBatis的缓存等等。这里主如果为了描述ORM框架的根蒂根基轮廓,以及在应用体式格式上它和JDBC的差别。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》
第一篇:Java回顾之I/O
第二篇:Java回顾之收集通信
第三篇:Java回顾之多线程
第四篇:Java回顾之多线程同步
第五篇:Java回顾之凑集
第六篇:Java回顾之序列化
第七篇:Java回顾之反射
第八篇:Java回顾之一些根蒂根基概念
第九篇:Java回顾之JDBC
这篇文章里,我们首要评论辩论ORM框架,以及在应用上和JDBC的差别。
概述
ORM框架不是一个新话题,它已经撒播了很多年。它的长处在于供给了概念性的、易于懂得的数据模型,将数据库中的表和内存中的对象建树了很好的映射关系。
我们在这里首要存眷Java中常用的两个ORM框架:Hibernate和iBatis。下面来介绍这两个框架简单的应用办法,若是将来有时候,我会深切的写一些更有意思的相干文章。
Hibernate
Hibernate是一个持久化框架和ORM框架,持久化和ORM是两个有区此外概念,持久化重视对象的存储办法是否跟着法度的退出而灭亡,ORM存眷的是如安在数据库表和内存对象之间建树接洽关系。
Hibernate应用POJO来默示Model,应用XML设备文件来设备对象和表之间的关系,它供给了一系列API来经由过程对对象的操纵而改变数据库中的过程。
Hibernate更夸大如何对单笔记录进行操纵,对于更错杂的操纵,它供给了一种新的面向对象的查询说话:HQL。
我们先来定义一个关于Hibernate中Session经管的类,这里的Session类似于JDBC中的Connection。
1 public class HibernateSessionManager {
2
3 private static SessionFactory sessionFactory;
4
5 static
6 {
7 try
8 {
9 sessionFactory = new Configuration().configure(sample/orm/hibernate/hibernate.cfg.xml).buildSessionFactory();
10 }
11 catch(Exception ex)
12 {
13 ex.printStackTrace();
14 }
15 }
16
17 public static final ThreadLocal tl = new ThreadLocal();
18
19 public static Session currentSession()
20 {
21 Session s = (Session)tl.get();
22 if (s == null)
23 {
24 s = sessionFactory.openSession();
25 tl.set(s);
26 }
27
28 return s;
29 }
30
31 public static void closeSession()
32 {
33 Session s = (Session)tl.get();
34 tl.set(null);
35 if (s != null)
36 {
37 s.close();
38 }
39 }
40 }
基于单张表进行操纵
下面我们来看一个简单的示例,它沿用了Java回顾之JDBC中的数据库,应用MySQL的test数据库中的user表。
起首,我们来定义VO对象:
1 public class User implements Serializable
2 {
3 private static final long serialVersionUID = 1L;
4 private int userID;
5 private String userName;
6 public void setUserID(int userID) {
7 this.userID = userID;
8 }
9 public int getUserID() {
10 return userID;
11 }
12 public void setUserName(String userName) {
13 this.userName = userName;
14 }
15 public String getUserName() {
16 return userName;
17 }
18 }
然后,我们定义User对象和数据库中user表之间的接洽关系,user表中只有两列:id和name。
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.User table=user catalog=test>
7 <id name=userID type=java.lang.Integer>
8 <column name=id />
9 <generator class=assigned />
10 </id>
11 <property name=userName type=java.lang.String>
12 <column name=name />
13 </property>
14 </class>
15 </hibernate-mapping>
将上述内容存储为User.hbm.xml。
接下来,我们须要定义一个关于Hibernate的全局设备文件,这里文件名是hibernate.cfg.xml。
1 <?xml version=1.0 encoding=UTF-8?>
2 <!DOCTYPE hibernate-configuration PUBLIC
3 -//Hibernate/Hibernate Configuration DTD 3.0//EN
4 http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd>
5
6 <hibernate-configuration>
7 <session-factory>
8 <property name=connection.driver_class>com.mysql.jdbc.Driver</property>
9 <property name=connection.url>jdbc:mysql://localhost/test</property>
10 <property name=connection.username>root</property>
11 <property name=connection.password>123</property>
12 <property name=dialect>org.hibernate.dialect.MySQLDialect</property>
13 <property name=show_sql>true</property>
14 <property name=jdbc.fetch_size>50</property>
15 <property name=jdbc.batch_size>25</property>
16
17 <mapping resource=sample/orm/hibernate/User.hbm.xml />
18 </session-factory>
19 </hibernate-configuration>
可以看到,上述设备文件中包含了数据库连接的信息,诸如driver信息、数据库url、用户名、暗码等等,还包含了我们上方定义的User.hbm.xml。
最后,我们编写测试代码,来对user表进行增、删、查、改的操纵:
1 private static void getUser(int id)
2 {
3 Session session = HibernateSessionManager.currentSession();
4 System.out.println(=====Query test=====);
5 User user = (User)session.get(User.class, new Integer(id));
6 if (user != null)
7 {
8 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
9 }
10 HibernateSessionManager.closeSession();
11 }
12
13 private static void User()
14 {
15 Session session = HibernateSessionManager.currentSession();
16 System.out.println(=====Insert test=====);
17 Transaction transaction = session.beginTransaction();
18 User user = new User();
19 user.setUserID(6);
20 user.setUserName(Zhang Fei);
21 session.save(user);
22 session.flush();
23 transaction.commit();
24 HibernateSessionManager.closeSession();
25 getUser(6);
26 }
27
28 private static void User(int id)
29 {
30 Session session = HibernateSessionManager.currentSession();
31 System.out.println(=====Update test=====);
32 Transaction transaction = session.beginTransaction();
33 User user = (User)session.get(User.class, new Integer(id));
34 System.out.println(=====Before Update=====);
35 if (user != null)
36 {
37 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
38 }
39 user.setUserName(Devil);
40 session.save(user);
41 session.flush();
42 transaction.commit();
43 user = (User)session.get(User.class, new Integer(id));
44 System.out.println(=====After Update=====);
45 if (user != null)
46 {
47 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
48 }
49 HibernateSessionManager.closeSession();
50 }
51
52 private static void User(int id)
53 {
54 Session session = HibernateSessionManager.currentSession();
55 System.out.println(=====Delete test=====);
56 Transaction transaction = session.beginTransaction();
57 User user = (User)session.get(User.class, new Integer(id));
58 System.out.println(=====Before Delte=====);
59 if (user != null)
60 {
61 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
62 }
63 session.(user);
64 transaction.commit();
65 user = (User)session.get(User.class, new Integer(id));
66 System.out.println(=====After Update=====);
67 if (user != null)
68 {
69 System.out.println(ID: + user.getUserID() + ; Name: + user.getUserName());
70 }
71 else
72 {
73 System.out.println(Delete successfully.);
74 }
75 HibernateSessionManager.closeSession();
76 }
我们遵守如下次序调用测试代码:
1 User();
2 User(6);
3 User(6);
可以看到如下成果:
=====Insert test=====
Hibernate: into test.user (name, id) values (?, ?)
=====Query test=====
Hibernate: user0_.id as id0_, user0_.name as name0_0_ test.user user0_ where user0_.id=?
ID:6; Name:Zhang Fei
=====Update test=====
Hibernate: user0_.id as id0_, user0_.name as name0_0_ test.user user0_ where user0_.id=?
=====Before Update=====
ID:6; Name:Zhang Fei
Hibernate: test.user set name=? where id=?
=====After Update=====
ID:6; Name:Devil
=====Delete test=====
Hibernate: user0_.id as id0_, user0_.name as name0_0_ test.user user0_ where user0_.id=?
=====Before Delte=====
ID:6; Name:Devil
Hibernate: test.user where id=?
Hibernate: user0_.id as id0_, user0_.name as name0_0_ test.user user0_ where user0_.id=?
=====After Delete=====
Delete successfully.
请重视,上方的成果中,输出了每次数据库操纵时的SQL语句,这是因为在设备文件中有如下设备:
<property name=show_sql>true</property>
我们可以在开辟调试阶段将其打开,在安排到客户方时,将其封闭。
基于多表接洽关系的操纵
Hibernate在建树多表接洽关系时,按照主外键的设置,表之间的接洽关系可以分为三种:一对一、一对多和多对多。这些接洽关系会表如今表的设备文件以及VO中。
下面我们来看一个经典的多表接洽关系示例:排课表。数据库中建树如下四张表:Grade/Class/ClassRoom/Schedule。刚发明,应用MySQL自带的经管器导出表定义根蒂根基是一件不成能的任务。。。。
上述各表除ID以及须要外键外,只有Name一列。
然后看各个VO的定义:
1 package sample.orm.hibernate;
2
3 import java.io.Serializable;
4 import java.util.Set;
5
6 public class Grade implements Serializable
7 {
8 private static final long serialVersionUID = 1L;
9 private int gradeID;
10 private String gradeName;
11 private Set classes;
12 public void setGradeID(int gradeID) {
13 this.gradeID = gradeID;
14 }
15 public int getGradeID() {
16 return gradeID;
17 }
18 public void setGradeName(String gradeName) {
19 this.gradeName = gradeName;
20 }
21 public String getGradeName() {
22 return gradeName;
23 }
24 public void setClasses(Set classes) {
25 this.classes = classes;
26 }
27 public Set getClasses() {
28 return classes;
29 }
30 }
1 package sample.orm.hibernate;
2
3 import java.io.Serializable;
4 import java.util.Set;
5
6 public class Class implements Serializable
7 {
8 private static final long serialVersionUID = 1L;
9 private int classID;
10 private Grade grade;
11 private Set classrooms;
12 private String className;
13 public void setClassID(int classID) {
14 this.classID = classID;
15 }
16 public int getClassID() {
17 return classID;
18 }
19 public void setClassName(String className) {
20 this.className = className;
21 }
22 public String getClassName() {
23 return className;
24 }
25 public void setGrade(Grade grade) {
26 this.grade = grade;
27 }
28 public Grade getGrade() {
29 return grade;
30 }
31 public void setClassrooms(Set classrooms) {
32 this.classrooms = classrooms;
33 }
34 public Set getClassrooms() {
35 return classrooms;
36 }
37 }
1 package sample.orm.hibernate;
2
3 import java.io.Serializable;
4 import java.util.Set;
5
6 public class ClassRoom implements Serializable
7 {
8 private static final long serialVersionUID = 1L;
9 private int classRoomID;
10 private String classRoomName;
11 private Set classes;
12 public void setClassRoomID(int classRoomID) {
13 this.classRoomID = classRoomID;
14 }
15 public int getClassRoomID() {
16 return classRoomID;
17 }
18 public void setClassRoomName(String classRoomName) {
19 this.classRoomName = classRoomName;
20 }
21 public String getClassRoomName() {
22 return classRoomName;
23 }
24 public void setClasses(Set classes) {
25 this.classes = classes;
26 }
27 public Set getClasses() {
28 return classes;
29 }
30 }
1 package sample.orm.hibernate;
2
3 import java.io.Serializable;
4 import java.util.Set;
5
6 public class Schedule implements Serializable
7 {
8 private static final long serialVersionUID = 1L;
9 private int scheduleID;
10 private int classRoomID;
11 private int classID;
12 private Set classes;
13 public void setClassRoomID(int classRoomID) {
14 this.classRoomID = classRoomID;
15 }
16 public int getClassRoomID() {
17 return classRoomID;
18 }
19 public void setClassID(int classID) {
20 this.classID = classID;
21 }
22 public int getClassID() {
23 return classID;
24 }
25 public void setClasses(Set classes) {
26 this.classes = classes;
27 }
28 public Set getClasses() {
29 return classes;
30 }
31 public void setScheduleID(int scheduleID) {
32 this.scheduleID = scheduleID;
33 }
34 public int getScheduleID() {
35 return scheduleID;
36 }
37 }
接着是各个表的接洽关系设备文件:
1)Grade.hbm.xml
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.Grade table=grade catalog=test>
7 <id name=gradeID type=java.lang.Integer>
8 <column name=gradeid />
9 <generator class=assigned />
10 </id>
11 <property name=gradeName type=java.lang.String>
12 <column name=gradename />
13 </property>
14
15 <set name=classes lazy=true inverse=true cascade=all--orphan>
16 <key>
17 <column name=gradeid/>
18 </key>
19 <one-to-many class=sample.orm.hibernate.Class/>
20 </set>
21 </class>
22 </hibernate-mapping>
重视上方的<set>设备,里面的<one-to-many>节点说了然Grade和Class之间一对多的关系。
2)Class.hbm.xml
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.Class table=class catalog=test>
7 <id name=classID type=java.lang.Integer>
8 <column name=classid />
9 <generator class=assigned />
10 </id>
11 <property name=className type=java.lang.String>
12 <column name=classname />
13 </property>
14
15 <many-to-one name=grade class=sample.orm.hibernate.Grade lazy=proxy not-null=true>
16 <column name=gradeid/>
17 </many-to-one>
18
19 <set name=classrooms lazy=true inverse=true cascade=all--orphan table=schedule>
20 <key column =classid/>
21 <many-to-many class=sample.orm.hibernate.ClassRoom column=classroomid/>
22 </set>
23 </class>
24 </hibernate-mapping>
重视它定义两个接洽关系:一个是和Grade之间多对一的关系,一个合适ClassRoom之间多对多的关系。
3)ClassRoom.hbm.xml
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.ClassRoom table=classroom catalog=test>
7 <id name=classRoomID type=java.lang.Integer>
8 <column name=classroomid />
9 <generator class=assigned />
10 </id>
11 <property name=classRoomName type=java.lang.String>
12 <column name=classroomname />
13 </property>
14
15 <set name=classes lazy=true inverse=true cascade=all--orphan table=schedule>
16 <key column=classroomid/>
17 <many-to-many class=sample.orm.hibernate.Class column=classid/>
18 </set>
19 </class>
20 </hibernate-mapping>
它只定义了一个接洽关系:和Class之间的多对多接洽关系。
4)Schedule.hbm.xml
1 <?xml version=1.0?>
2 <!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN
3 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
4
5 <hibernate-mapping>
6 <class name=sample.orm.hibernate.Schedule table=schedule catalog=test>
7 <id name=scheduleID type=java.lang.Integer>
8 <column name=scheduleid />
9 <generator class=assigned />
10 </id>
11 <property name=classID type=java.lang.Integer>
12 <column name=classid />
13 </property>
14 <property name=classRoomID type=java.lang.Integer>
15 <column name=classroomid />
16 </property>
17 </class>
18 </hibernate-mapping>
这里就不须要再定义接洽关系了。
我们须要在Hibernate全局设备文件中添加如下内容:
1 <mapping resource=sample/orm/hibernate/Grade.hbm.xml />
2 <mapping resource=sample/orm/hibernate/Class.hbm.xml />
3 <mapping resource=sample/orm/hibernate/ClassRoom.hbm.xml />
4 <mapping resource=sample/orm/hibernate/Schedule.hbm.xml />
下面是各类测试办法,在有接洽关系的景象下,Hibernate供给了下面几个特点:
- 延迟加载
- 级联添加
- 级联批改
- 级联删除
1 private static void getClass(int gradeid)
2 {
3 Session session = HibernateSessionManager.currentSession();
4 System.out.println(=====Get Class info=====);
5 Transaction transaction = session.beginTransaction();
6 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
7
8 Hibernate.initialize(grade);
9 Iterator iterator = grade.getClasses().iterator();
10 System.out.println(年级: + grade.getGradeName() + 包含以放工级:);
11 while(iterator.hasNext())
12 {
13 System.out.println(grade.getGradeName() + ((Class)iterator.next()).getClassName());
14 }
15 HibernateSessionManager.closeSession();
16 }
17
18 private static void getSchedule(int gradeid)
19 {
20 Session session = HibernateSessionManager.currentSession();
21 Transaction transaction = session.beginTransaction();
22 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
23 if (grade != null)
24 {
25 System.out.println(ID: + grade.getGradeID() + ; Name: + grade.getGradeName());
26 }
27
28 Hibernate.initialize(grade.getClasses());
29
30 Iterator iterator = grade.getClasses().iterator();
31 while(iterator.hasNext())
32 {
33 Class c = (Class)iterator.next();
34 System.out.println(grade.getGradeName() + c.getClassName() + 应用以下教室:);
35 Hibernate.initialize(c.getClassrooms());
36 Iterator iterator1 = c.getClassrooms().iterator();
37 while(iterator1.hasNext())
38 {
39 System.out.println(((ClassRoom)iterator1.next()).getClassRoomName());
40 }
41 }
42 HibernateSessionManager.closeSession();
43 }
44
45 private static void Grade()
46 {
47 Session session = HibernateSessionManager.currentSession();
48 Transaction transaction = session.beginTransaction();
49 Grade grade = new Grade();
50 grade.setGradeID(4);
51 grade.setGradeName(四年级);
52
53 Class c1 = new Class();
54 c1.setClassID(7);
55 c1.setGrade(grade);
56 c1.setClassName(一班);
57 Class c2 = new Class();
58 c2.setClassID(8);
59 c2.setGrade(grade);
60 c2.setClassName(二班);
61
62 Set set = new HashSet();
63 set.add(c1);
64 set.add(c2);
65
66 grade.setClasses(set);
67
68 session.save(grade);
69 session.flush();
70 transaction.commit();
71 HibernateSessionManager.closeSession();
72 getClass(4);
73 }
74
75 private static void Grade(int gradeid)
76 {
77 Session session = HibernateSessionManager.currentSession();
78 Transaction transaction = session.beginTransaction();
79 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
80 if (grade != null)
81 {
82 session.(grade);
83 session.flush();
84 }
85
86 transaction.commit();
87
88 grade = (Grade)session.get(Grade.class, new Integer(gradeid));
89 if (grade == null)
90 {
91 System.out.println(删除成功);
92 }
93 HibernateSessionManager.closeSession();
94 }
95
96 private static void Grade1(int gradeid)
97 {
98 Session session = HibernateSessionManager.currentSession();
99 Transaction transaction = session.beginTransaction();
100 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
101 if (grade != null)
102 {
103 System.out.println(ID: + grade.getGradeID() + ; Name: + grade.getGradeName());
104 }
105 grade.setGradeName(Grade + gradeid);
106 session.save(grade);
107 session.flush();
108 transaction.commit();
109 HibernateSessionManager.closeSession();
110 getClass(gradeid);
111 }
112
113 private static void Grade2(int gradeid)
114 {
115 Session session = HibernateSessionManager.currentSession();
116 Transaction transaction = session.beginTransaction();
117 Grade grade = (Grade)session.get(Grade.class, new Integer(gradeid));
118 if (grade != null)
119 {
120 System.out.println(ID: + grade.getGradeID() + ; Name: + grade.getGradeName());
121 }
122
123 Grade newGrade = new Grade();
124 newGrade.setGradeID(10);
125 newGrade.setGradeName(grade.getGradeName());
126 Set set = grade.getClasses();
127 Set newSet = new HashSet();
128 Iterator iterator = set.iterator();
129 while(iterator.hasNext())
130 {
131 Class c = (Class)iterator.next();
132 Class temp = new Class();
133 temp.setClassID(c.getClassID());
134 temp.setClassName(c.getClassName());
135 temp.setGrade(newGrade);
136 newSet.add(temp);
137 }
138 newGrade.setClasses(newSet);
139 session.(grade);
140 session.flush();
141 session.save(newGrade);
142 session.flush();
143 transaction.commit();
144 grade = (Grade)session.get(Grade.class, new Integer(gradeid));
145 if (grade == null)
146 {
147 System.out.println(删除成功);
148 }
149 HibernateSessionManager.closeSession();
150 getClass(10);
151 }
按次序调用上方的办法:
1 getClass(1);
2 getSchedule(1);
3 Grade();
4 Grade1(4);
5 Grade2(4);
6 Grade(10);
履行成果如下:
=====Get Class info=====
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
年级:一年级包含以放工级:
一年级二班
一年级一班
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
ID:1; Name:一年级
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
一年级一班应用以下教室:
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
教室二
教室五
教室一
一年级二班应用以下教室:
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
教室四
教室二
教室六
Hibernate: class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ test.class class_ where class_.classid=?
Hibernate: class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ test.class class_ where class_.classid=?
Hibernate: into test.grade (gradename, gradeid) values (?, ?)
Hibernate: into test.class (classname, gradeid, classid) values (?, ?, ?)
Hibernate: into test.class (classname, gradeid, classid) values (?, ?, ?)
=====Get Class info=====
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
年级:四年级包含以放工级:
四年级二班
四年级一班
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
ID:4; Name:四年级
Hibernate: test.grade set gradename=? where gradeid=?
=====Get Class info=====
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
年级:Grade 4包含以放工级:
Grade 4二班
Grade 4一班
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
ID:4; Name:Grade 4
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
Hibernate: test.class where classid=?
Hibernate: test.class where classid=?
Hibernate: test.grade where gradeid=?
Hibernate: class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ test.class class_ where class_.classid=?
Hibernate: class_.classid, class_.classname as classname2_, class_.gradeid as gradeid2_ test.class class_ where class_.classid=?
Hibernate: into test.grade (gradename, gradeid) values (?, ?)
Hibernate: into test.class (classname, gradeid, classid) values (?, ?, ?)
Hibernate: into test.class (classname, gradeid, classid) values (?, ?, ?)
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
删除成功
=====Get Class info=====
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
年级:Grade 4包含以放工级:
Grade 4一班
Grade 4二班
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
Hibernate: classes0_.gradeid as gradeid1_, classes0_.classid as classid1_, classes0_.classid as classid0_, classes0_.classname as classname2_0_, classes0_.gradeid as gradeid2_0_ test.class classes0_ where classes0_.gradeid=?
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
Hibernate: classrooms0_.classid as classid1_, classrooms0_.classroomid as classroo2_1_, classroom1_.classroomid as classroo1_0_, classroom1_.classroomname as classroo2_4_0_ schedule classrooms0_ inner join test.classroom classroom1_ on classrooms0_.classroomid=classroom1_.classroomid where classrooms0_.classid=?
Hibernate: test.class where classid=?
Hibernate: test.class where classid=?
Hibernate: test.grade where gradeid=?
Hibernate: grade0_.gradeid as gradeid0_, grade0_.gradename as gradename1_0_ test.grade grade0_ where grade0_.gradeid=?
删除成功
同样,履行成果中包含了各个SQL语句。
iBatis
iBatis是别的一种ORM框架,和Hibernate善于操纵单笔记录不合,iBatis是基于SQL模板的,可以说,iBatis每次和数据库进行操纵时,都有明白的SQL语句,而这些SQL语句,就是我们定义在设备文件中的。
我们还是以test数据库中的user表为例,简单申明iBatis的操纵流程:
起首,我们还是须要定义VO对象,这里还是应用和Hibernate讲解时雷同的User:
1 package sample.orm.ibatis;
2
3 import java.io.Serializable;
4
5 public class User implements Serializable
6 {
7 private static final long serialVersionUID = 1L;
8 private int userID;
9 private String userName;
10 public void setUserID(int userID) {
11 this.userID = userID;
12 }
13 public int getUserID() {
14 return userID;
15 }
16 public void setUserName(String userName) {
17 this.userName = userName;
18 }
19 public String getUserName() {
20 return userName;
21 }
22
23 }
然后须要针对这个VO,定义一个自力的设备文件:User.xml
1 <?xml version=1.0 encoding=UTF-8?>
2 <!DOCTYPE sqlMap
3 PUBLIC -//iBATIS.com//DTD SQL Map 2.0//EN
4 http://www.ibatis.com/dtd/sql-map-2.dtd>
5
6 <sqlMap namespace=User>
7
8 <typeAlias alias=user type=sample.orm.ibatis.User />
9
10
11 <cacheModel id=user-cache type=OSCache readOnly=true serialize=true>
12 <flushInterval milliseconds=1 />
13 <flushOnute statement=User />
14 <flushOnute statement=User />
15 <flushOnute statement=getUser />
16 <flushOnute statement=getAllUser />
17 <property value=1 name=size />
18 </cacheModel>
19
20 <!--
21 <resultMap >
22 <result property=userID column=id />
23 <result property=userName column=name />
24 </resultMap>
25 -->
26
27
28 < id=getUser parameterClass=java.lang.Integer resultClass=user cacheModel=user-cache >
29 id as userID,name as userName user where id = #userID#
30 </>
31 < id=getAllUser resultClass=user cacheModel=user-cache>
32 id as userID,name as userName user
33 </>
34 < id=User parameterClass=user>
35 user SET name=#userName# WHERE id = #userID#
36 </>
37 < id=User parameterClass=user>
38 into user ( id, name ) VALUES ( #userID#,#userName#)
39 </>
40 < id=User parameterClass=java.lang.Integer>
41 user where id=#userID#
42 </>
43
44 </sqlMap>
这个设备文件首要包含三项目组:
1)缓存的设备
2)对象属性和表字段之间的接洽关系
3)针对表的各类CRUD操纵
然后是关于iBatis的全局设备文件SqlMapConfig.xml:
1 <?xml version=1.0 encoding=UTF-8?>
2 <!DOCTYPE sqlMapConfig
3 PUBLIC -//iBATIS.com//DTD SQL Map Config 2.0//EN
4 http://www.ibatis.com/dtd/sql-map-config-2.dtd>
5
6 <sqlMapConfig>
7
8 <settings cacheModelsEnabled=true enhancementEnabled=true
9 lazyLoadingEnabled=true errorTracingEnabled=true maxRequests=32
10 maxSessions=10 maxTransactions=5 useStatementNamespaces=false />
11
12 <transactionManager type=JDBC>
13 <dataSource type=SIMPLE>
14 <property name=JDBC.Driver value=com.mysql.jdbc.Driver />
15 <property name=JDBC.ConnectionURL value=jdbc:mysql://localhost/test />
16 <property name=JDBC.Username value=root />
17 <property name=JDBC.Password value=123 />
18 <property name=Pool.MaximumActiveConnections value=10 />
19 <property name=Pool.MaximumIdleConnections value=5 />
20 <property name=Pool.MaximumCheckoutTime value=120000 />
21 <property name=Pool.TimeToWait value=500 />
22 <property name=Pool.PingQuery value= 1 user />
23 <property name=Pool.PingEnabled value=false />
24 </dataSource>
25 </transactionManager>
26
27 <sqlMap resource=sample/orm/ibatis/User.xml />
28
29 </sqlMapConfig>
和Hibernate全局设备文件类似,它也包含了数据库连接的信息、数据库连接池的信息以及我们定义的User.xml。
下面是测试办法:
1 public class Sample {
2
3 private SqlMapClient sqlMap = null;
4
5 private void buildMap() throws IOException
6 {
7 String resource = sample/orm/ibatis/SqlMapConfig.xml;
8 Reader reader = Resources.getResourceAsReader(resource);
9 this.sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
10 }
11
12 private void User() throws IOException, SQLException
13 {
14 System.out.println(=====Insert test=====);
15 if (this.sqlMap == null)
16 {
17 this.buildMap();
18 }
19 this.sqlMap.startTransaction();
20 User user = new User();
21 user.setUserID(10);
22 user.setUserName(Angel);
23
24 this.sqlMap.(User, user);
25 this.sqlMap.commitTransaction();
26
27 user = getUser(10);
28 printUserInfo(user);
29 }
30
31 private void User() throws IOException, SQLException, InterruptedException
32 {
33 System.out.println(=====Update test=====);
34 if (this.sqlMap == null)
35 {
36 this.buildMap();
37 }
38 this.sqlMap.startTransaction();
39 User user = new User();
40 user.setUserID(10);
41 user.setUserName(Devil);
42 this.sqlMap.(User, user);
43 this.sqlMap.commitTransaction();
44 this.sqlMap.flushDataCache();
45 // Thread.sleep(3000);
46 user = getUser(10);
47 printUserInfo(user);
48 }
49
50 private void User() throws IOException, SQLException
51 {
52 System.out.println(=====Delete test=====);
53 if (this.sqlMap == null)
54 {
55 this.buildMap();
56 }
57 sqlMap.flushDataCache();
58 this.sqlMap.startTransaction();
59 this.sqlMap.(User, 10);
60 this.sqlMap.commitTransaction();
61 getAllUser();
62 }
63
64 private User getUser(int id) throws IOException, SQLException
65 {
66 if (this.sqlMap == null)
67 {
68 this.buildMap();
69 }
70 User user = (User)this.sqlMap.openSession().queryForObject(getUser, id);
71
72 return user;
73 }
74
75 private List<User> getAllUser() throws IOException, SQLException
76 {
77 if(this.sqlMap==null)
78 this.buildMap();
79
80 List userList=null;
81 userList=this.sqlMap.openSession().queryForList(getAllUser);
82 printUserInfo(userList);
83 return userList;
84 }
85
86 private void printUserInfo(User user)
87 {
88 System.out.println(=====user info=====);
89 System.out.println(ID: + user.getUserID() + ;Name: + user.getUserName());
90 }
91
92 private void printUserInfo(List<User> users)
93 {
94 System.out.println(=====user info=====);
95 for(User user:users)
96 {
97 System.out.println(ID: + user.getUserID() + ;Name: + user.getUserName());
98 }
99 }
100
101 public static void main(String[] args) throws IOException, SQLException, InterruptedException
102 {
103 Sample sample = new Sample();
104 sample.getAllUser();
105 sample.User();
106 sample.User();
107 sample.User();
108 }
109 }
它的履行成果如下:
=====user info=====
ID:1;Name:Zhang San
ID:2;Name:TEST
=====Insert test=====
=====user info=====
ID:10;Name:Angel
=====Update test=====
=====user info=====
ID:10;Name:Devil
=====Delete test=====
=====user info=====
ID:1;Name:Zhang San
ID:2;Name:TEST
这篇文章只是简单介绍了Hibernate和iBatis的用法,并没有涉及全部,例如Hibernate的事务、阻碍、HQL、iBatis的缓存等等。这里主如果为了描述ORM框架的根蒂根基轮廓,以及在应用体式格式上它和JDBC的差别。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》