maven+springMVC+mybatis+junit+MySQL入门实践延迟加载(含源码)

本文介绍了使用MyBatis框架实现延迟加载的具体方法,包括配置、实体类定义、Mapper文件编写及单元测试等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近想玩玩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对象,他都会将实体类关联的其他实体类信息查询出来。该部分省略,可自行测试。

项目源码:
项目源码下载
maven库包:
maven库包

本项目是用的spring springMVC myBatis框架,前段没用框架,只写了简单的页面效果,做增删查改 这是我系统学习所得,希望能对你有所帮助 项目部署: 1;导包,就是web-inf下lib,让后把这些选中,单击右键build path -->add library 2;web.xml配置文件,这里几乎不需要改,以后要用只需要复制就行 3;具体框架配置文件,都集中在了sourceConfig文件夹下,这个自己琢磨,以后再用这个框架也是几乎不需要改的,之所以说几乎,是因为只需要改包名就可以了 4;写bean,写dao,写service,写controller,这是重点 5;bean下写要操作的数据表,记住这个类药与数据库中的表一致,最好一模一样,避免麻烦 6;dao下写数据库操作内容,那下面有两个文件名一样的,一个是java文件,一个是xml文件,java文件是定义方法名,xml文件是让你写具体的数据操作方法的,格式就是这样,你看看就能懂,你只需要这样写,这个框架就可以识别,吧你在xml中写的数据库操作方法匹配到java文件中的方法,这是mybatis做的事 7;service包中放你的业务逻辑层,具体来说就是,dao中只放数据操作,service引用数据操作,还可以有其他操作 8;controller类的格式你要用心点了,这个是控制器,控制请求的跳转,他和servlet的功能类似, 功能引导: 为了让你更方便了解这个项目,说一下流程 1.把项目部署到tomcat,启动服务, 2.在浏览器中输入http://localhost:8080/AscentSys/user/in.do 3.这个命令的意思是,访问这个项目地址user/in.do,然后这个请求就会发送到controller中,在controller中首先匹配到user,在匹配到in.do就调到具体的方法中去处理这个情求了,这里会跳转到users文件夹下的login.jsp页面中,解释一下,在spring-servlet.xml配置文件中有一句路径解析的,“前缀后缀”那个bean,意思是在返回的东西加前缀后缀,这里写的是啥你琢磨琢磨可以明白的 4.在login.jsp页面中,有个提交地址,是login.do,按上面说的,在controller中首先匹配到user,在匹配到login.do就调到具体的方法中去处理这个情求了,后面的流程我就不说了,自己看 5。再说一点,return的好多字符串,有的是redirect:/user/userlist.do这样的格式,意思是转发,就是转到另一个请求中去,同理,具体意思是,在controller中首先匹配到user,在匹配到userlist.do就调到下面的方法中去处理这个情求了, 6,关于传参数的问题,在表单中写的属性,在controller自动接收,也可以接受user对象,如果是对象,那个表单的格式你要看仔细了和一般表单的不同之处。琢磨琢磨你会明白的, 希望能对你有所帮助
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值