最近想玩玩mybatis框架,参考该篇文章搭了个框架:
http://wenku.baidu.com/view/4503d560c77da26924c5b0a1
所以,搭建框架过程就不废话了,搭建完成之后,就不断的测试,所有的测试用例,包含很多Mybatis官方文档例子基本使用和和一对一、一对多等等多种关联关系都包含在其中。
之后,就测了测延迟加载这东东,简单的写写东西,源代码也可以提供给刚入门的童鞋>-<
<1>项目的目录结构:
pom.xml文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eyas.springmvc</groupId>
<artifactId>springmvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>3.2.4.RELEASE</spring.version>
<mybatis.version>3.2.4</mybatis.version>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.9</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>5.0.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ant/ant-launcher -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-launcher</artifactId>
<version>1.9.4</version>
</dependency>
<!-- log end -->
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
<2>涉及到的JAVA POJO:
public class Classes {
// 定义实体类的属性,与class表中的字段对应
private int id; // id===>c_id
private String name; // name===>c_name
/**
* class表中有一个teacher_id字段,所以在Classes类中定义一个teacher属性,
* 用于维护teacher和class之间的一对一关系,通过这个teacher属性就可以知道这个班级是由哪个老师负责的
*/
private Teacher teacher;
//一个班级下面而已有多个学生
private List<Student> students;
//setter getter...
@Override
public String toString() {
return "Classes [id=" + id + ", name=" + name + ", teacher=" + teacher
+ ", students=" + students + "]";
}
}
public class Teacher {
// 定义实体类的属性,与teacher表中的字段对应
private int id; // id===>t_id
private String name; // name===>t_name
//setter getter...
@Override
public String toString() {
return "Teacher [id=" + id + ", name=" + name + "]";
}
}
public class Student {
// 定义属性,和student表中的字段对应
private int id; // id===>s_id
private String name; // name===>s_name
//setter getter...
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}
<3>mapper文件:ClassesMapper.xml(部分)
<!-- 嵌套查询处理:通常是多条sql进行关联查询 -->
<select id="getClassesWithStudentNestedSelect" parameterType="int" resultMap="ClassResultMap4">
select * from class where c_id=#{id}
</select>
<resultMap type="Classes" id="ClassResultMap4">
<id property="id" column="c_id" />
<result property="name" column="c_name" />
<association property="teacher" column="teacher_id"
select="getTeacherById" />
<collection property="students" ofType="Student" column="c_id" select="getStudentsByClassId"/>
</resultMap>
<4>Junit测试:
ps:要使用延迟加载,需要在mybatis-config.xml配置文件中加上:
<!-- 全局映射器启用缓存 -->
<setting name="cacheEnabled" value="true" />
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false" />
public class ClassAndTeacherTest {
private SqlSessionFactory factory;
@Before
public void init() throws IOException{
String resource = "conf/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
/*
* 延迟加载测试
*/
@Test
public void getClassesWithAssociation(){
SqlSession session = factory.openSession();
try{
// Classes clazz = session.selectOne("cn.springmvc.dao.ClassesDao.getClassesWithNestedResultMap",1);
// System.out.println(clazz);
ClassesDao mapper = session.getMapper(ClassesDao.class);
// Classes clazz2 = mapper.getClassesWithNestedSelect(1);
Classes clazz2 = mapper.getClassesWithStudentNestedSelect(1);
System.out.println(clazz2.getName());
System.out.println(clazz2.getTeacher().getName());
System.out.println(clazz2.getStudents());
}finally{
session.close();
}
}
}
<5>说明:
在上述方法getClassesWithAssociation中,重点就是关注那几句输出:
- 仅仅查询classes内容,不显示访问classes班级中的老师或者学生属性。
ClassesDao mapper = session.getMapper(ClassesDao.class);
// Classes clazz2 = mapper.getClassesWithNestedSelect(1);
Classes clazz2 = mapper.getClassesWithStudentNestedSelect(1);
System.out.println(clazz2.getName());
// System.out.println(clazz2.getTeacher().getName());
// System.out.println(clazz2.getStudents());
----------
output:(仅仅查询了一次sql)
2016-11-29 10:44:13,606 [main] DEBUG [cn.springmvc.dao.ClassesDao.getClassesWithStudentNestedSelect] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@16e8722a]
2016-11-29 10:44:13,606 [main] DEBUG [cn.springmvc.dao.ClassesDao.getClassesWithStudentNestedSelect] - ==> Preparing: ***select * from class where c_id=?***
2016-11-29 10:44:13,637 [main] DEBUG [cn.springmvc.dao.ClassesDao.getClassesWithStudentNestedSelect] - ==> Parameters: 1(Integer)
2016-11-29 10:44:13,700 [main] DEBUG [cn.springmvc.dao.ClassesDao.getClassesWithStudentNestedSelect] - <== Total: 1
class_a
当显式访问classes班级中的老师或者学生属性时候,会再次发出sql查询 数据库:
ClassesDao mapper = session.getMapper(ClassesDao.class);
// Classes clazz2 = mapper.getClassesWithNestedSelect(1);
Classes clazz2 = mapper.getClassesWithStudentNestedSelect(1);
System.out.println(clazz2.getName());
System.out.println(clazz2.getTeacher().getName());
System.out.println(clazz2.getStudents());
----------
output:(发出三次sql数据库查询)
2016-11-29 10:48:57,996 [main] DEBUG [cn.springmvc.dao.ClassesDao.getClassesWithStudentNestedSelect] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@512327c]
2016-11-29 10:48:57,996 [main] DEBUG [cn.springmvc.dao.ClassesDao.getClassesWithStudentNestedSelect] - ==> Preparing: ***select * from class where c_id=?***
2016-11-29 10:48:58,028 [main] DEBUG [cn.springmvc.dao.ClassesDao.getClassesWithStudentNestedSelect] - ==> Parameters: 1(Integer)
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getClassesWithStudentNestedSelect] - <== Total: 1
class_a
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getTeacherById] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@512327c]
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getTeacherById] - ==> Preparing: ***select t_id as id, t_name as name from teacher where t_id = ?***
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getTeacherById] - ==> Parameters: 1(Integer)
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getTeacherById] - <== Total: 1
teacher1
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getStudentsByClassId] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@512327c]
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getStudentsByClassId] - ==> Preparing: ***SELECT s_id id, s_name name FROM student WHERE class_id=?***
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getStudentsByClassId] - ==> Parameters: 1(Integer)
2016-11-29 10:48:58,090 [main] DEBUG [cn.springmvc.dao.ClassesDao.getStudentsByClassId] - <== Total: 3
[Student [id=1, name=student_A], Student [id=2, name=student_B], Student [id=3, name=student_C]]
当关闭延迟加载功能,即在mybatis-config.xml配置中注释掉:
<!-- <setting name="lazyLoadingEnabled" value="true" /> -->
<!-- <setting name="aggressiveLazyLoading" value="false" /> -->
再测试时候,无论显式或者隐式访问classes对象,他都会将实体类关联的其他实体类信息查询出来。该部分省略,可自行测试。