• Java Persistence with MyBatis 3(中文版) 第一章 MyBatis入门


    本章将涵盖以下话题:

    • ž  MyBatis是什么?
    • ž  为什么选择MyBatis?
    • ž  MyBatis安装配置
    • ž  域模型样例

    1.1 MyBatis是什么

         MyBatis是一个简化和实现了Java数据持久化层(persistencelayer)的开源框架,它抽象了大量的JDBC冗余代码,并提供了一个简单易用的API和数据库交互。

         MyBatis的前身是iBATIS,iBATIS于2002年由ClintonBegin创建。MyBatis 3 是iBATIS的全新设计,支持注解和Mapper。

         MyBatis 流行的主要原因在于它的简单性和易使用性。在Java应用程序中,数据持久化层涉及到的工作有:将从数据库查询到的数据生成所需要的Java对象;将Java对象中的数据通过SQL持久化到数据库中。

         MyBatis 通过抽象底层的JDBC代码,自动化SQL结果集产生Java对象、Java对象的数据持久化数据库中的过程使得对SQL的使用变得容易。

         如果你正在使用iBATIS,并且想将iBATIS移植到MyBatis上,你可以在MyBatis 的官方网站(https://code.google.com/p/mybatis/wiki/DocUpgrade)上找到详细的指导步骤。

    1.2 为什么选择MyBatis?

    当前有很多Java实现的持久化框架,而MyBatis流行起来有以下原因:

    • l   它消除了大量的JDBC冗余代码
    • l   它有低的学习曲线
    • l   它能很好地与传统数据库协同工作
    • l   它可以接受SQL语句
    • l   它提供了与Spring 和Guice框架的集成支持
    • l   它提供了与第三方缓存类库的集成支持
    • l   它引入了更好的性能

    1.2.1 消除大量的JDBC冗余代码

          Java通过Java数据库连接(Java DataBase Connectivity,JDBC)API来操作关系型数据库,但是JDBC是一个非常底层的API,我们需要书写大量的代码来完成对数据库的操作。

          让我们演示一下我们是怎样使用纯的JDBC来对表STUDENTS实现简单的 select和 insert操作的。

          假设表STUDENTS有STUD_ID,NAME,EMAIL 和DOB字段。对应的Student JavaBean 定义如下:

    [java] view plain copy
     
     print?
    1. package com.mybatis3.domain;  
    2. import java.util.Date;  
    3. public class Student  
    4. {  
    5.     private Integer studId;  
    6.     private String name;  
    7.     private String email;  
    8.     private Date dob;  
    9.     // setters and getters  
    10. }  

    下面的StudentService.java实现了 通过JDBC对表STUDENTS的SELECT 和INSERT操作:

    [java] view plain copy
     
     print?
    1. public Student findStudentById(int studId)  
    2. {  
    3.     Student student = null;  
    4.     Connection conn = null;  
    5.     try  
    6.     {  
    7.         //获得数据库连接  
    8.         conn = getDatabaseConnection();  
    9.         String sql = "SELECT * FROM STUDENTS WHERE STUD_ID=?";  
    10.         //创建  PreparedStatement  
    11.         PreparedStatement pstmt = conn.prepareStatement(sql);  
    12.         //设置输入参数  
    13.         pstmt.setInt(1, studId);  
    14.         ResultSet rs = pstmt.executeQuery();  
    15.         //从数据库中取出结果并生成 Java 对象  
    16.         if(rs.next())  
    17.         {  
    18.             student = new Student();  
    19.             student.setStudId(rs.getInt("stud_id"));  
    20.             student.setName(rs.getString("name"));  
    21.             student.setEmail(rs.getString("email"));  
    22.             student.setDob(rs.getDate("dob"));  
    23.         }  
    24.     }  
    25.     catch (SQLException e)  
    26.     {  
    27.         throw new RuntimeException(e);  
    28.     }  
    29.     finally  
    30.     {  
    31.         //关闭连接  
    32.         if(conn != null)  
    33.         {  
    34.             try  
    35.             {  
    36.                 conn.close();  
    37.             }  
    38.             catch (SQLException e) { }  
    39.         }  
    40.     }  
    41.     return student;  
    42. }  
    43.   
    44. public void createStudent(Student student)  
    45. {  
    46.     Connection conn = null;  
    47.     try  
    48.     {  
    49.         //获得数据库连接  
    50.         conn = getDatabaseConnection();  
    51.         String sql = "INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,DOB)  
    52.                      VALUES(?,?,?,?)";  
    53.         //创建 PreparedStatement  
    54.         PreparedStatement pstmt = conn.prepareStatement(sql);  
    55.         //设置输入参数  
    56.         pstmt.setInt(1, student.getStudId());  
    57.         pstmt.setString(2, student.getName());  
    58.         pstmt.setString(3, student.getEmail());  
    59.         pstmt.setDate(4, new  
    60.                       java.sql.Date(student.getDob().getTime()));  
    61.         pstmt.executeUpdate();  
    62.     }  
    63.     catch (SQLException e)  
    64.     {  
    65.         throw new RuntimeException(e);  
    66.     }  
    67.     finally  
    68.     {  
    69.         //关闭连接  
    70.         if(conn != null)  
    71.         {  
    72.             try  
    73.             {  
    74.                 conn.close();  
    75.             }  
    76.             catch (SQLException e) { }  
    77.         }  
    78.     }  
    79. }  
    80. protected Connection getDatabaseConnection() throws SQLException  
    81. {  
    82.     try  
    83.     {  
    84.         Class.forName("com.mysql.jdbc.Driver");  
    85.         return DriverManager.getConnection  
    86.                ("jdbc:mysql://localhost:3306/test", "root", "admin");  
    87.     }  
    88.     catch (SQLException e)  
    89.     {  
    90.         throw e;  
    91.     }  
    92.     catch (Exception e)  
    93.     {  
    94.         throw new RuntimeException(e);  
    95.     }  
    96. }  

        上述的每个方法中有大量的重复代码:创建一个连接创建一个Statement对象设置输入参数关闭资源(如connection,statement,resultSet)。

        MyBatis抽象了上述的这些相同的任务,如准备需要被执行的SQL statement对象并且将Java对象作为输入数据传递给statement对象的任务,进而开发人员可以专注于真正重要的方面。

        另外,MyBatis 自动化了将从输入的Java对象中的属性设置成查询参数、从SQL结果集上生成Java对象这两个过程。

        现在让我们看看怎样通过MyBatis实现上述的方法:

    1.  在 SQL Mapper 映射配置文件中配置SQL语句,假定为StudentMapper.xml

    [java] view plain copy
     
     print?
    1. <select id="findStudentById" parameterType="int" resultType="Student">  
    2.     SELECT STUD_ID AS studId, NAME, EMAIL, DOB   
    3.         FROM STUDENTS WHERE STUD_ID=#{Id}  
    4. </select>  
    5. <insert id="insertStudent" parameterType="Student">  
    6.     INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,DOB)   
    7.         VALUES(#{studId},#{name},#{email},#{dob})  
    8. </insert>  

    2.  创建一个StudentMapper接口.

    [java] view plain copy
     
     print?
    1. public interface StudentMapper  
    2. {  
    3.     Student findStudentById(Integer id);  
    4.     void insertStudent(Student student);  
    5. }  

    3. 在Java代码中,你可以使用如下代码触发SQL语句:
    [java] view plain copy
     
     print?
    1. SqlSession session = getSqlSessionFactory().openSession();  
    2. StudentMapper mapper = session.getMapper(StudentMapper.class);  
    3. // Select Student by Id  
    4. Student student = mapper.selectStudentById(1);  
    5. //To insert a Student record  
    6. mapper.insertStudent(student);  

    就是这么简单!你不需要创建Connection连接,PreparedStatement,不需要自己对每一次数据库操作进行手动设置参数和关闭连接。只需要配置数据库连接属性和SQL语句,MyBatis会处理这些底层工作。

    现在你不用担心SqlSessionFactory、SqlSession、Mapper XML文件是什么,这些概念我们会在接下来的章节中详细解释。

    另外,MyBatis还提供了其他的一些特性来简化持久化逻辑的实现:

    • l   它支持复杂的SQL结果集数据映射到嵌套对象图结构
    • l   它支持一对一和一对多的结果集和Java对象的映射
    • l   它支持根据输入的数据构建动态的SQL语句

    1.2.2 它有低的学习曲线

        MyBatis能够流行的首要原因之一在于它学习和使用起来非常简单,它取决于你Java和SQL方面的知识。如果开发人员很熟悉Java和SQL,他们会发现MyBatis入门非常简单。

    1.2.3 它能很好地与传统数据库协同工作

        有时我们可能需要用不正规形式与传统数据库协同工作,使用成熟的ORM框架(如Hibernate)有可能、但是很难跟传统数据库很好地协同工作,因为他们尝试将Java对象静态地映射到数据库的表上(译者注:这一类型的框架都尝试将一张表的一条记录映射成一个JavaBean,这种方式一定程度上丧失了SQL语句的灵活性)。

        而MyBatis是将查询的结果与Java对象映射起来,这使得MyBatis可以很好地与传统数据库协同工作。你可以根据面相对象的模型创建Java 域对象,执行传统数据库的查询,然后将结果映射到对应的Java对象上。

    1.2.4 它可以接受SQL语句

        成熟的ORM框架(如Hibernate)鼓励使用实体对象(EntityObjects)和在其底层自动产生SQL语句。由于这种的SQL生成方式,我们有可能不能够利用到数据库的一些特有的特性。Hibernate允许执行本地SQL,但是这样会打破持久层和数据库独立的原则。

        MyBatis框架接受SQL语句,而不是将其对开发人员隐藏起来。由于MyBatis不会产生任何的SQL语句,所以开发人员就要准备SQL语句,这样就可以充分利用数据库特有的特性并且可以准备自定义的查询。另外,MyBatis对存储过程也提供了支持。

    1.2.5 它提供了与Spring 和Guice框架的集成支持

    MyBatis提供了与 流行的依赖注入框架Spring和Guice的开包即用的集成支持,这将进一步简化MyBatis的使用

    1.2.6 它提供了与第三方缓存类库的集成支持

    MyBatis有内建的SqlSession级别的缓存机制,用于缓存Select语句查询出来的结果。除此之外,MyBatis提供了与多种第三方缓存类库的集成支持,如EHCache,OSCache,Hazelcast。

    1.2.7 它引入了更好的性能

        性能问题是关乎软件应用成功与否的关键因素之一。为了达到更好的性能,需要考虑很多事情,而对很多应用而言,数据持久化层是整个系统性能的关键。

        MyBatis支持数据库连接池,消除了为每一个请求创建一个数据库连接的开销

        MyBatis 提供了内建的缓存机制,在SqlSession级别提供了对SQL查询结果的缓存。即:如果你调用了相同的select查询,MyBatis会将放在缓存的结果返回,而不会去再查询数据库。

        MyBatis框架并没有大量地使用代理机制(译者注:一些ORM框架使用了大量的动态代理模式来产生实体对象等,由于动态代理本身有很大的内存消耗,大量使用动态代理,会使整个系统性能变得很差),因此对于其他的过度地使用代理的ORM 框架而言,MyBatis可以获得更好的性能。

    1.3 MyBatis安装和配置

    我们假设你的系统上已经安装了JDK1.6+和MySQL5。JDK和MySQL安装过程不在本书的叙述范围。

    在写本书时,MyBatis最新版是MyBatis 3.2.2。贯穿本书,我们将使用MyBatis3.2.2版本。

    本文并不限定你使用什么类型的IDE(如Eclipse,NetBeans IDE,或者IntelliJ IDEA,它们通过提供自动完成,重构,调试特性来很大程度上简化了开发)来编码,你可以选择你喜欢的IDE。

    本节将(通过以下步骤)说明如何使用MyBatis开发一个简单的Java项目:

    • l   新建表STUDENTS,插入样本数据
    • l   新建一个Java项目,将MyBatis-3.2.2.jar添加到classpath中
    • l   新建mybatis-config.xml 和映射器StudentMapper.xml配置文件
    • l   新建建MyBatisSqlSessionFactory单例模式类
    • l   新建映射器StudentMapper 接口和 StudentService 类
    • l   新建一个JUnit 测试类来测试 StudentService

    1.3.1 新建表STUDENTS,插入样本数据

    使用以下SQL脚本往MySQL数据库中创建STUDENTS表插入样本数据:

    [sql] view plain copy
     
     print?
    1. CREATE TABLE STUDENTS  
    2. (  
    3. stud_id int(11) NOT NULL AUTO_INCREMENT,  
    4. name varchar(50) NOT NULL,  
    5. email varchar(50) NOT NULL,  
    6. dob date DEFAULT NULL,  
    7. PRIMARY KEY (stud_id)  
    8. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;  
    9. /*Sample Data for the students table */  
    10. insert into students(stud_id,name,email,dob)  
    11. values (1,'Student1','student1@gmail.com','1983-06-25');  
    12. insert into students(stud_id,name,email,dob)  
    13. values (2,'Student2','student2@gmail.com','1983-06-25');  

    1.3.2 新建一个Java项目,将MyBatis-3.2.2.jar添加到classpath中

    让我们创建一个Java项目,并被指MyBatis JAR 包依赖:

    1.  创建一个Java项目,名为mybatis-demo.

    2.  如果你没有使用类似于Maven和Gradle之类的依赖管理构建工具,你需要手动下载这些依赖的JAR包,手动添加到classpath中.

    3.  你可以从 http://code.google.com/p/mybatis 上下载MyBatis的发布包mybatis-3.2.2.zip。这个包包含了mybatis-3.2.2.jar文件和它的可选的依赖包如slf4j/log4j 日志jar包.

    4.  我们将使用SLF4J 日志记录框架 和log4j一起记录日志。mybatis-3.2.2.zip包含了slf4j这个依赖jar包。

    5.  解压mybatis-3.2.2.zip文件,将mybatis-3.2.2.jar,lib/slf4j-api-1.7.5.jar,lib/slf-log4j12-1.7.5.jar,和lib/log4j-1.2.17.jar 这些jar包添加到classpath中

    6.  你可以从http://junit.org 上下载JUnit JAR文件,从http://www.mysql.com/downloads/connector/j/ 上下载MySQL数据库驱动

    7.  将 junit-4.11.jar 和 mysql-connector-java-5.1.22.jar 添加到classpath中

    如果你正在使用maven,配置这些jar包依赖就变得简单多了。在你的pom.xml中添加以下依赖即可:
    [html] view plain copy
     
     print?
    1. <dependencies>  
    2.   <dependency>  
    3.     <groupId>org.mybatis</groupId>  
    4.     <artifactId>mybatis</artifactId>  
    5.     <version>3.2.2</version>  
    6.   </dependency>  
    7.   <dependency>  
    8.     <groupId>mysql</groupId>  
    9.     <artifactId>mysql-connector-java</artifactId>  
    10.     <version>5.1.22</version>  
    11.     <scope>runtime</scope>  
    12.   </dependency>  
    13.   <dependency>  
    14.     <groupId>org.slf4j</groupId>  
    15.     <artifactId>slf4j-api</artifactId>  
    16.     <version>1.7.5</version>  
    17.   </dependency>  
    18.   <dependency>  
    19.     <groupId>org.slf4j</groupId>  
    20.     <artifactId>slf4j-log4j12</artifactId>  
    21.     <version>1.7.5</version>  
    22.     <scope>runtime</scope>  
    23.   </dependency>  
    24.   <dependency>  
    25.     <groupId>log4j</groupId>  
    26.     <artifactId>log4j</artifactId>  
    27.     <version>1.2.17</version>  
    28.     <scope>runtime</scope>  
    29.   </dependency>  
    30.   <dependency>  
    31.     <groupId>junit</groupId>  
    32.     <artifactId>junit</artifactId>  
    33.     <version>4.11</version>  
    34.     <scope>test</scope>  
    35.   </dependency>  
    36. </dependencies>  

    9.  新建log4j.properties文件,添加到 classpath中.

    [plain] view plain copy
     
     print?
    1. log4j.rootLogger=DEBUG, stdout  
    2. log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
    3. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
    4. log4j.appender.stdout.layout.ConversionPattern=%d [%-5p] %c - %m%n  

    1.3.3 新建mybatis-config.xml 和映射器StudentMapper.xml配置文件

    让我们来创建MyBatis 的主要配置文件 mybatis-config.xml,其中包括数据库连接信息,类型别名等等;然后创建一个包含了映射的SQL语句的StudentMapper.xml文件。

    1. 创建MyBatis 的主要配置文件 mybatis-config.xml,其中包括数据库连接信息,类型别名等等,然后将其加到classpath中;

    [html] view plain copy
     
     print?
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
    3. "http://mybatis.org/dtd/mybatis-3-config.dtd">  
    4. <configuration>  
    5.   <typeAliases>  
    6.     <typeAlias alias="Student" type="com.mybatis3.domain.Student" />  
    7.   </typeAliases>  
    8.   <environments default="development">  
    9.     <environment id="development">  
    10.       <transactionManager type="JDBC" />  
    11.       <dataSource type="POOLED">  
    12.         <property name="driver" value="com.mysql.jdbc.Driver" />  
    13.         <property name="url" value="jdbc:mysql://localhost:3306/test" />  
    14.         <property name="username" value="root" />  
    15.         <property name="password" value="admin" />  
    16.       </dataSource>  
    17.     </environment>  
    18.   </environments>  
    19.   <mappers>  
    20.     <mapper resource="com/mybatis3/mappers/StudentMapper.xml" />  
    21.   </mappers>  
    22. </configuration>  

    2. 创建SQL 映射器XML配置文件StudentMapper.xml 并且将它放在com.mybatis3.mappers包中;
    [java] view plain copy
     
     print?
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    4. <mapper namespace="com.mybatis3.mappers.StudentMapper">  
    5.   <resultMap type="Student" id="StudentResult">  
    6.     <id property="studId" column="stud_id" />  
    7.     <result property="name" column="name" />  
    8.     <result property="email" column="email" />  
    9.     <result property="dob" column="dob" />  
    10.   </resultMap>  
    11.   <select id="findAllStudents" resultMap="StudentResult">  
    12.      SELECT * FROM STUDENTS  
    13.   </select>  
    14.   <select id="findStudentById" parameterType="int" resultType="Student">  
    15.      SELECT STUD_ID AS STUDID, NAME, EMAIL, DOB   
    16.          FROM STUDENTS WHERE STUD_ID=#{Id}  
    17.   </select>  
    18.   <insert id="insertStudent" parameterType="Student">  
    19.      INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,DOB)   
    20.          VALUES(#{studId },#{name},#{email},#{dob})  
    21.   </insert>  
    22. </mapper>  

    上述的StudentMapper,xml 文件包含的映射的SQL语句可以通过ID加上名空间调用。

    1.3.4 新建建MyBatisSqlSessionFactory单例模式类

    新建 MyBatisSqlSessionFactory.java 类文件,实例化它,使其持有一个SqlSessionFactory单例对象:

    [java] view plain copy
     
     print?
    1. package com.mybatis3.util;  
    2. import java.io.*;  
    3. import org.apache.ibatis.io.Resources;  
    4. import org.apache.ibatis.session.*;  
    5. public class MyBatisSqlSessionFactory  
    6. {  
    7.     private static SqlSessionFactory sqlSessionFactory;  
    8.     public static SqlSessionFactory getSqlSessionFactory()  
    9.     {  
    10.         if(sqlSessionFactory == null)  
    11.         {  
    12.             InputStream inputStream;  
    13.             try  
    14.             {  
    15.                 inputStream = Resources.  
    16.                               getResourceAsStream("mybatis-config.xml");  
    17.                 sqlSessionFactory = new  
    18.                 SqlSessionFactoryBuilder().build(inputStream);  
    19.             }  
    20.             catch (IOException e)  
    21.             {  
    22.                 throw new RuntimeException(e.getCause());  
    23.             }  
    24.         }  
    25.         return sqlSessionFactory;  
    26.     }  
    27.     public static SqlSession openSession()  
    28.     {  
    29.         return getSqlSessionFactory().openSession();  
    30.     }  
    31. }  

    上述的代码段中,我们创建了一个SqlSessionFactory对象,我们将使用它来获得SqlSession对象和执行映射的SQL语句。

    1.3.5 新建映射器StudentMapper 接口和 StudentService 类

    让我们创建一个StudentMapper接口,其定义的方法名和在Mapper XML配置文件定义的SQL映射语句名称相同;在创建一个StudentService.java 类,包含了一些业务操作的实现。

    1. 首先, 创建 JavaBean Student.java:

    [java] view plain copy
     
     print?
    1. package com.mybatis3.domain;  
    2. import java.util.Date;  
    3. public class Student  
    4. {  
    5.     private Integer studId;  
    6.     private String name;  
    7.     private String email;  
    8.     private Date dob;  
    9.     // setters and getters  
    10. }  

    2. 创建映射器Mapper接口StudentMapper.java 其方法签名和StudentMapper.xml中定义的SQL映射定义名相同:
    [java] view plain copy
     
     print?
    1. package com.mybatis3.mappers;  
    2. import java.util.List;  
    3. import com.mybatis3.domain.Student;  
    4. public interface StudentMapper  
    5. {  
    6.     List<Student> findAllStudents();  
    7.     Student findStudentById(Integer id);  
    8.     void insertStudent(Student student);  
    9. }  

    3.  现在创建StudentService.java 实现对表STUDENTS的数据库操作:
    [java] view plain copy
     
     print?
    1. package com.mybatis3.services;  
    2. import java.util.List;  
    3. import org.apache.ibatis.session.SqlSession;  
    4. import org.slf4j.Logger;  
    5. import org.slf4j.LoggerFactory;  
    6. import com.mybatis3.domain.Student;  
    7. import com.mybatis3.mappers.StudentMapper;  
    8. import com.mybatis3.util.MyBatisSqlSessionFactory;  
    9. public class StudentService  
    10. {  
    11.     private Logger logger =  
    12.         LoggerFactory.getLogger(getClass());  
    13.     public List<Student> findAllStudents()  
    14.     {  
    15.         SqlSession sqlSession =  
    16.             MyBatisSqlSessionFactory.openSession();  
    17.         try  
    18.         {  
    19.             StudentMapper studentMapper =  
    20.                 sqlSession.getMapper(StudentMapper.class);  
    21.             return studentMapper.findAllStudents();  
    22.         }  
    23.         finally  
    24.         {  
    25.             //If sqlSession is not closed  
    26.             //then database Connection associated this sqlSession will not be  
    27.             returned to pool  
    28.             //and application may run out of connections.  
    29.             sqlSession.close();  
    30.         }  
    31.     }  
    32.     public Student findStudentById(Integer studId)  
    33.     {  
    34.         logger.debug("Select Student By ID :{}", studId);  
    35.         SqlSession sqlSession =  
    36.             MyBatisSqlSessionFactory.openSession();  
    37.         try  
    38.         {  
    39.             StudentMapper studentMapper =  
    40.                 sqlSession.getMapper(StudentMapper.class);  
    41.             return studentMapper.findStudentById(studId);  
    42.         }  
    43.         finally  
    44.         {  
    45.             sqlSession.close();  
    46.         }  
    47.     }  
    48.     public void createStudent(Student student)  
    49.     {  
    50.         SqlSession sqlSession =  
    51.             MyBatisSqlSessionFactory.openSession();  
    52.         try  
    53.         {  
    54.             StudentMapper studentMapper =  
    55.                 sqlSession.getMapper(StudentMapper.class);  
    56.             studentMapper.insertStudent(student);  
    57.             sqlSession.commit();  
    58.         }  
    59.         finally  
    60.         {  
    61.             sqlSession.close();  
    62.         }  
    63.     }  
    64. }  

    你也可以通过不通过Mapper接口执行映射的SQL语句。
    [java] view plain copy
     
     print?
    1. Student student = (Student)sqlSession.  
    2.                   selectOne("com.mybatis3.mappers.StudentMapper.findStudentById",  
    3.                             studId);  

    然而,使用Mapper接口是最佳实践,我们可以以类型安全的方式调用映射的SQL语句。

    1.3.6 新建一个JUnit 测试类来测试 StudentService

    新建一个JUnit测试类测试StudentSerivce.java中定义的方法。

    [java] view plain copy
     
     print?
    1. package com.mybatis3.services;  
    2. import java.util.*;  
    3. import org.junit.*;  
    4. import com.mybatis3.domain.Student;  
    5. public class StudentServiceTest  
    6. {  
    7.     private static StudentService studentService;  
    8.     @BeforeClass  
    9.     public static void setup()  
    10.     {  
    11.         studentService = new StudentService();  
    12.     }  
    13.     @AfterClass  
    14.     public static void teardown()  
    15.     {  
    16.         studentService = null;  
    17.     }  
    18.     @Test  
    19.     public void testFindAllStudents()  
    20.     {  
    21.         List<Student> students = studentService.findAllStudents();  
    22.         Assert.assertNotNull(students);  
    23.         for (Student student : students)  
    24.         {  
    25.             System.out.println(student);  
    26.         }  
    27.     }  
    28.     @Test  
    29.     public void testFindStudentById()  
    30.     {  
    31.         Student student = studentService.findStudentById(1);  
    32.         Assert.assertNotNull(student);  
    33.         System.out.println(student);  
    34.     }  
    35.     @Test  
    36.     public void testCreateStudent()  
    37.     {  
    38.         Student student = new Student();  
    39.         int id = 3;  
    40.         student.setStudId(id);  
    41.         student.setName("student_" + id);  
    42.         student.setEmail("student_" + id + "gmail.com");  
    43.         student.setDob(new Date());  
    44.         studentService.createStudent(student);  
    45.         Student newStudent = studentService.findStudentById(id);  
    46.         Assert.assertNotNull(newStudent);  
    47.     }  
    48. }  

    1.3.7 它是怎么工作的

        首先,我们配置了MyBatis最主要的配置文件-mybatis-config.xml,里面包含了JDBC连接参数;配置了映射器Mapper XML配置文件文件,里面包含了SQL语句的映射。

        我们使用mybatis-config.xml内的信息创建了SqlSessionFactory对象。每个数据库环境应该就一个SqlSessionFactory对象实例,所以我们使用了单例模式只创建一个SqlSessionFactory实例。

        我们创建了一个映射器Mapper接口-StudentMapper,其定义的方法签名和在StudentMapper.xml中定义的完全一样(即映射器Mapper接口中的方法名跟StudentMapper.xml中的id的值相同)。注意StudentMapper.xml中namespace的值被设置成com.mybatis3.mappers.StudentMapper,是StudentMapper接口的完全限定名。这使我们可以使用接口来调用映射的SQL语句。

        在StudentService.java中,我们在每一个方法中创建了一个新的SqlSession,并在方法功能完成后关闭SqlSession。每一个线程应该有它自己的SqlSession实例。SqlSession对象实例不是线程安全的,并且不被共享。所以SqlSession的作用域最好就是其所在方法的作用域。从Web应用程序角度上看,SqlSession应该存在于request级别作用域上。

    1.4 域模型样例

    在这一节,我们将讨论一个表示在线学习系统应用的域模型样例,该模型的使用会贯穿全书。

    在线学习系统中,学生可以选择课程,并且通过基于Web的传播媒介上课,日虚拟课堂或者是桌面共享系统。

    有兴趣通过在线学习系统上课的导师可以在系统中注册,声明他们要教的课程明细。

    课程明细包括课程名称,课程描述,课程时长。全球的学生都可以注册和选择他们想学的课程。

    下面的图表表示了我们在线学习系统的数据库结构

    《Java Persistence with MyBatis 3(中文版)》导航:

    Java Persistence with MyBatis 3(中文版)

    Java Persistence with MyBatis 3(中文版) 前言

    Java Persistence with MyBatis 3(中文版) 第一章 MyBatis入门

    Java Persistence with MyBatis 3(中文版) 第二章 引导MyBatis

    Java Persistence with MyBatis 3(中文版) 第三章 使用XML配置SQL映射器

    Java Persistence with MyBatis 3(中文版) 第四章 使用注解配置SQL映射器

    Java Persistence with MyBatis 3(中文版) 第五章 与Spring集成 

    -------------------------------------------------------------------------------------------------------------------------------

    作者声明:本文出处是http://blog.csdn.net/luanlouis,如需转载,请注明出处!

  • 相关阅读:
    微信小程序之跨界面传参
    微信小程序简易教程
    css动画与js动画的区别
    不同浏览器兼容性的区别
    Filter学习
    FileDescriptor
    Executor框架
    Struts1的处理流程
    Struts1的实现原理
    [转]TOMCAT原理以及处理HTTP请求的过程、ContextPath ServletPath
  • 原文地址:https://www.cnblogs.com/wlsblog/p/7879281.html
Copyright © 2020-2023  润新知