1. 程式人生 > >基於ssm框架對mybatis對映檔案的多對一返回型別的junit4單元測試

基於ssm框架對mybatis對映檔案的多對一返回型別的junit4單元測試

本專案使用maven搭建的ssm框架,大致的檔案結構如圖

這裡寫圖片描述

1、首先是pom.xml中所依賴的一些jar包

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion
>
<groupId>com.how2java</groupId> <artifactId>ssm</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <spring.version>4.1.3.RELEASE</spring.version> <pagehelper.version>5.1.2-beta</pagehelper.version
>
<mysql.version>5.1.6</mysql.version> <mybatis.spring.version>1.2.3</mybatis.spring.version> <mybatis.version>3.1.1</mybatis.version> <junit.version>4.12</junit.version> <jstl.version>1.2</jstl.version> <jsqlparser.version
>
1.0</jsqlparser.version> <jackson.version>1.2.7</jackson.version> <servlet-api.version>3.1.0</servlet-api.version> <druid.version>1.0.18</druid.version> <log4j.version>1.2.16</log4j.version> <commons-logging.version>1.2</commons-logging.version> <commons-fileupload.version>1.2.1</commons-fileupload.version> <commons-io.version>1.3.2</commons-io.version> <commons-lang.version>2.6</commons-lang.version> <aopalliance.version>1.0</aopalliance.version> <mybatis-generator.version>1.3.5</mybatis-generator.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.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>${mybatis.spring.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</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-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <!-- JSP相關 --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet-api.version}</version> <scope>provided</scope> </dependency> <!-- pageHelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>${pagehelper.version}</version> </dependency> <!--jsqlparser--> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>${jsqlparser.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commons-logging.version}</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons-fileupload.version}</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>${commons-lang.version}</version> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>${aopalliance.version}</version> </dependency> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>${mybatis-generator.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.17</version> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <!-- 資原始檔拷貝外掛 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.7</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- java編譯外掛 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> <pluginManagement> <plugins> <!-- 配置Tomcat外掛 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> </plugin> </plugins> </pluginManagement> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.tld</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build> </project>

2、springMVC配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">



    <context:annotation-config/>

    <context:component-scan base-package="com.how2java.controller">
          <context:include-filter type="annotation" 
          expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <mvc:annotation-driven >
       <mvc:message-converters register-defaults="true">
          <bean class="org.springframework.http.converter.StringHttpMessageConverter">
             <property name="supportedMediaTypes" value="text/plain;charset=UTF-8" />
          </bean>
       </mvc:message-converters>    
    </mvc:annotation-driven>

    <mvc:default-servlet-handler />


    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

3、applicationContext.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">




   <context:annotation-config />
    <context:component-scan base-package="com.how2java.service" />
    <context:component-scan base-package="com.how2java.test" />

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本屬性 url、user、password -->
        <property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />

        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="3" />
        <property name="minIdle" value="3" />
        <property name="maxActive" value="20" />

        <!-- 配置獲取連線等待超時的時間 -->
        <property name="maxWait" value="60000" />

        <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />

        <!-- 配置一個連線在池中最小生存的時間,單位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />

        <property name="validationQuery" value="SELECT 1" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />

        <!-- 開啟PSCache,並且指定每個連線上PSCache的大小 -->
        <property name="poolPreparedStatements" value="true" />
        <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
    </bean>


    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="typeAliasesPackage" value="com.how2java.pojo" />
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:com/how2java/mapper/*.xml"/>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.how2java.mapper"/>
    </bean>
</beans>

4、log4j.properties的配置

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.how2java=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

ssm中基本的配置就是如上內容,在mybatis框架中不需要對對映介面進行實現,而是使用MapperScannerConfigurerl掃描指定路徑下的xml檔案,xml檔名需與介面名保持一致,這樣便可通過xml對介面進行實現。

CategoryMapper中的方法:

public interface CategoryMapper {


    public int add(Category category);  


    public void delete(int id);  


    public Category get(int id);  


    public int update(Category category);   


    public List<Category> list();

    public List<Category> list(Page page);


    public int total();  



}

在CategoryMapper.xml中id與方法名保持一致:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

    <mapper namespace="com.how2java.mapper.CategoryMapper">
        <insert id="add" parameterType="Category" >
            insert into category_ ( name ) values (#{name})    
        </insert>

        <delete id="delete" parameterType="Category" >
            delete from category_ where id= #{id}   
        </delete>

        <select id="get" resultType="Category">
            SELECT 
            a.id,a.name,
            b.id "job.id",
            b.name "job.name"
            FROM category_ a
            INNER JOIN job b ON a.job_id=b.id
            WHERE a.id=#{id};    
        </select>

        <update id="update" parameterType="Category" >
            update category_ set name=#{name} where id=#{id}    
        </update>
        <select id="list" resultType="Category">
            select * from   category_ order by id desc     
            <if test="start!=null and count!=null">
                    limit #{start},#{count}
            </if>

        </select>
        <select id="total" resultType="int">
            select count(*) from   category_      
        </select>               
    </mapper>

這裡測試的便是get方法。

在進行測試之前需要對兩個實體類進行說明:
Category:

package com.how2java.pojo;

public class Category {
    private int id;
    private String name;

    private Job job;


    public Job getJob() {
        return job;
    }
    public void setJob(Job job) {
        this.job = job;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Category [id=" + id + ", name=" + name + "]";
    }
}

Job類:

package com.how2java.pojo;

public class Job {

    private int id;

    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Job [id=" + id + ", name=" + name + "]";
    }
}

這兩個實體類都對tostring進行了重寫,重寫的快捷操作是:
右鍵->source->override/implements methods
這裡寫圖片描述

重寫的內容可根據需要進行修改。這樣最好列印的時候就會出現你所修改的內容。

單元測試類:

package com.how2java.test1;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.how2java.mapper.CategoryMapper;
import com.how2java.pojo.Category;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class CategoryMapperTest {
    @Resource
    private CategoryMapper categoryMapper;

    @Test
    public void Testget(){
        int id=29;
        Category category=categoryMapper.get(id);
        System.out.println(category);
        System.out.println(category.getJob());
        System.out.println(category.getJob().getName());
    }

}

junit中常用的註解:
@RunWith:用於指定junit執行環境,是junit提供給其他框架測試環境介面擴充套件,為了便於使用spring的依賴注入,spring提供了org.springframework.test.context.junit4.SpringJUnit4ClassRunner作為Junit測試環境
@ContextConfiguration({“classpath:applicationContext.xml”,”classpath:spring/buyer/applicationContext-service.xml”})
匯入配置檔案,這裡我的applicationContext配置檔案是根據模組來分類的。如果有多個模組就引入多個“applicationContext-service.xml”檔案。如果所有的都是寫在“applicationContext。xml”中則這樣匯入:
@ContextConfiguration(locations = “classpath:applicationContext.xml”)

@TransactionConfiguration(transactionManager = “transactionManager”, defaultRollback = true)這裡的事務關聯到配置檔案中的事務控制器(transactionManager = “transactionManager”),同時指定自動回滾(defaultRollback = true)。這樣做操作的資料才不會汙染資料庫!

@Transactional:這個非常關鍵,如果不加入這個註解配置,事務控制就會完全失效!

最後的輸出結果:

這裡寫圖片描述

再看get方法所對應的sql語句:

<select id="get" resultType="Category">
            SELECT 
            a.id,a.name,
            b.id "job.id",
            b.name "job.name"
            FROM category_ a
            INNER JOIN job b ON a.job_id=b.id
            WHERE a.id=#{id};    
</select>

這裡返回的型別是Category,而Category中又存放一個Job物件。
而mybatis的方便之處就是可以根據sql自動把屬性存放到job物件中。

最後再提一點,最近在閱讀mybatis官方文件的時候發現,parameterType屬性是可以省略的,因為 MyBatis 可以通過 TypeHandler 推斷出具體傳入語句的引數,預設值為 unset。

而傳入多個為定義的引數的時候,可以使用mybatis中的@param註解,這樣就不會出現引數錯誤的問題。

例:
介面

//介面
int updateByExampleSelective(@Param("record") Authority record, @Param("example") AuthorityExample example);

//sql語句
<update id="updateByExampleSelective" parameterType="map">
    update authority
    <set>
      <if test="record.authorityId != null">
        authority_id = #{record.authorityId,jdbcType=INTEGER},
      </if>
      <if test="record.authorityName != null">
        authority_name = #{record.authorityName,jdbcType=VARCHAR},
      </if>
      <if test="record.authorityLevel != null">
        authority_level = #{record.authorityLevel,jdbcType=INTEGER},
      </if>
    </set>
    <if test="_parameter != null">
      <include refid="Update_By_Example_Where_Clause" />
    </if>
</update>