1. Build a development environment
1.1. Create a Web Project with Maven
Execute the following command:
Copy the code as follows: mvn archetype:create -DgroupId=me.gacl -DartifactId=spring4-mybatis3 -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
As shown in the figure below:
The created project is as follows:
Edit pom.xml file
<project xmlns="http://maven.apache.org/POM/.." xmlns:xsi="http://www.w.org//XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/.. http://maven.apache.org/maven-v__.xsd"> <modelVersion>..</modelVersion> <groupId>me.gacl</groupId> <artifactId>spring-mybatis</artifactId> <packaging>war</packaging> <version>.-SNAPSHOT</version> <name>spring-mybatis Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>..</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>spring-mybatis</finalName> </build> </project>
Modify the <name>spring4-mybatis3 Maven Webapp</name> section and remove the content containing spaces in the "Maven Webapp". Otherwise, when Maven compiles the project, some inexplicable errors will occur due to spaces, and modify them to: <name>spring4-mybatis3</name> .
Also, delete the following:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>..</version> <scope>test</scope> </dependency>
This part is the jar package dependency information of junit. This version is too low. We do not use this Junit test version. The modified pom.xml content is as follows:
<project xmlns="http://maven.apache.org/POM/.." xmlns:xsi="http://www.w.org//XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/.. http://maven.apache.org/maven-v__.xsd"> <modelVersion>..</modelVersion> <groupId>me.gacl</groupId> <artifactId>spring-mybatis</artifactId> <packaging>war</packaging> <version>.-SNAPSHOT</version> <name>spring-mybatis</name> <url>http://maven.apache.org</url> <dependencies> </dependencies> <build> <finalName>spring-mybatis</finalName> </build> </project>
1.2. Import the created project into MyEclipse
The specific operation steps are shown in the figure below:
Manually create three source folders: [src/main/java], [src/test/resources], and [src/test/java], as shown in the figure below:
At this point, all the project construction work has been completed.
2. Create databases and tables (for MySQL)
The SQL script is as follows:
Create DATABASE spring4_mybatis3;USE spring4_mybatis3;DROP TABLE IF EXISTS t_user;CREATE TABLE t_user ( user_id char(32) NOT NULL, user_name varchar(30) DEFAULT NULL, user_birthday date DEFAULT NULL, user_salary double DEFAULT NULL, PRIMARY KEY (user_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The created database and table are as follows:
3. Use generator tool to generate code
I found a generator tool online that can generate entity classes, SQL mapping files and dao corresponding to the MyBatis table based on the created database table, and find the generator.xml file in the root directory of the generator tool. This file is used to configure code generation rules, as shown in the figure below:
Edit the generator.xml file, the content is as follows:
<?xml version="." encoding="UTF-"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration .//EN" "http://mybatis.org/dtd/mybatis-generator-config__.dtd"> <generatorConfiguration> <!-- Database Driver Package Location--> <classPathEntry location="E:/repository/mysql/mysql-connector-java/../mysql-connector-java-...jar" /> <!-- <classPathEntry location="C:/oracle/product/../db_/jdbc/lib/ojdbc.jar" />--> <context id="DBTables" targetRuntime="MyBatis"> <commentGenerator> <property name="suppressAllComments" value="true" /> </commentGenerator> <!-- Database Link URL, Username, Password--> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:/spring_mybatis" userId="root" password="XDP"> <!--<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@localhost::orcl" userId="msa" password="msa">--> </jdbcConnection> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- Generate the package name and location of the entity class. Here the generated entity class is placed under the package me.gacl.domain--> <javaModelGenerator targetPackage="me.gacl.domain" targetProject="C:/Users/gacl/spring-mybatis/src/main/java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- The generated SQL map file package name and location. Here, place the generated SQL map file under the package me.gacl.mapping--> <sqlMapGenerator targetPackage="me.gacl.mapping" targetProject="C:/Users/gacl/spring-mybatis/src/main/java"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- Generate the package name and location of the DAO. Here, place the generated dao class under the package me.gacl.dao--> <javaClientGenerator type="XMLMAPPER" targetPackage="me.gacl.dao" targetProject="C:/Users/gacl/spring-mybatis/src/main/java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!-- To generate those tables (change tableName and domainObjectName) --> <table tableName="t_user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" /> </context> </generatorConfiguration>
Open the command line window, switch to the root directory of the generator tool, and execute the following command:
java -jar mybatis-generator-core-1.3.2.jar -configfile generator.xml -overwrite
As shown in the figure below:
Just now, we configured the generated code and SQL mapping file in the generator.xml file to put the generated code and SQL mapping file into the directory "C:/Users/gacl/spring4-mybatis3/src/main/java". This directory is the directory where our spring4-mybatis3 project is located. We refresh the src/main/java directory and you can see the generated code and mapping file, as shown in the figure below:
The generated code and mapping file need not be changed in a line, and can be directly applied to the project. Let's take a look at the code and mapping files generated by the generator tool:
1. Generated dao class
package me.gacl.dao; import me.gacl.domain.User; public interface UserMapper { int deleteByPrimaryKey(String userId); int insert(User record); int insertSelective(User record); User selectByPrimaryKey(String userId); int updateByPrimaryKey(User record); }The generated UserMapper is an interface that defines some methods for adding, deleting, modifying and searching of the t_user table.
2. The generated entity class
package me.gacl.domain; import java.util.Date; public class User { private String userId; private String userName; private Date userBirthday; private Double userSalary; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId == null ? null : userId.trim(); } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName == null ? null : userName.trim(); } public Date getUserBirthday() { return userBirthday; } public void setUserBirthday(Date userBirthday) { this.userBirthday = userBirthday; } public Double getUserSalary() { return userSalary; } public void setUserSalary(Double userSalary) { this.userSalary = userSalary; } }The User class is the corresponding entity class of the t_user table. The attributes defined in the User class correspond to the fields in the t_user table one by one.
3. Generated SQL mapping file
<?xml version="." encoding="UTF-" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper .//EN" "http://mybatis.org/dtd/mybatis--mapper.dtd" > <mapper namespace="me.gacl.dao.UserMapper" > <resultMap id="BaseResultMap" type="me.gacl.domain.User" > <id column="user_id" property="userId" jdbcType="CHAR" /> <result column="user_name" property="userName" jdbcType="VARCHAR" /> <result column="user_birthday" property="userBirthday" jdbcType="DATE" /> <result column="user_salary" property="userSalary" jdbcType="DOUBLE" /> </resultMap> <sql id="Base_Column_List" > user_id, user_name, user_birthday, user_salary </sql> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" > select <include refid="Base_Column_List" /> from t_user where user_id = #{userId,jdbcType=CHAR} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.String" > delete from t_user where user_id = #{userId,jdbcType=CHAR} </delete> <insert id="insert" parameterType="me.gacl.domain.User" > insert into t_user (user_id, user_name, user_birthday, user_salary) values (#{userId,jdbcType=CHAR}, #{userName,jdbcType=VARCHAR}, #{userBirthday,jdbcType=DATE}, #{userSalary,jdbcType=DOUBLE}) </insert> <insert id="insertSelective" parameterType="me.gacl.domain.User" > insert into t_user <trim prefix="(" suffix=")" suffixOverrides="," > <if test="userId != null" > user_id, </if> <if test="userName != null" > user_name, </if> <if test="userBirthday != null" > user_birthday, </if> <if test="userSalary != null" > user_salary, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides="," > <if test="userId != null" > #{userId,jdbcType=CHAR}, </if> <if test="userName != null" > #{userName,jdbcType=VARCHAR}, </if> <if test="userBirthday != null" > #{userBirthday,jdbcType=DATE}, </if> <if test="userSalary != null" > #{userSalary,jdbcType=DOUBLE}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="me.gacl.domain.User" > update t_user <set > <if test="userName != null" > user_name = #{userName,jdbcType=VARCHAR}, </if> <if test="userBirthday != null" > user_birthday = #{userBirthday,jdbcType=DATE}, </if> <if test="userSalary != null" > user_salary = #{userSalary,jdbcType=DOUBLE}, </if> </set> where user_id = #{userId,jdbcType=CHAR} </update> <update id="updateByPrimaryKey" parameterType="me.gacl.domain.User" > update t_user set user_name = #{userName,jdbcType=VARCHAR}, user_birthday = #{userBirthday,jdbcType=DATE}, user_salary = #{userSalary,jdbcType=DOUBLE} where user_id = #{userId,jdbcType=CHAR} </update> </mapper>The content of the UserMapper.xml file is to write SQL statements that operate the t_user table. Let’s focus on a few small details that need to be paid attention to in the UserMapper.xml configuration:
1. The namespace of the <mapper> tag of UserMapper.xml must be the full class name of the UserMapper interface, that is, <mapper namespace="me.gacl.dao.UserMapper" >
2. UserMapper.xml definition The value of the id attribute of the operation database must be consistent with the method name defined by the UserMapper interface, as shown in the figure below:
The reason for the above two requirements is that MyBatis can automatically implement the relevant methods defined in the UserMapper interface based on the UserMapper interface and the UserMapper.xml file, so that we no longer need to write specific implementation code for the UserMapper interface.
4. Integration of Spring and MyBatis
First, we need to add the relevant jar packages we need to the project. We can go to Maven's central repository: http://search.maven.org/ to find the relevant jar packages we want, as shown in the following figure:
We just need to enter the name of the jar package we are looking for in the search box and click the [SEARCH] button to find the jar package we are looking for.
4.1. Add Spring and Mybatis related jar packages
1. Add spring-core, enter spring-core keyword to search, as shown in the figure below:
Find the dependency description information about spring-core, as shown in the following figure:
Will
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.4.RELEASE</version></dependency>
Copy to the project's pom.xml file as follows:
<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>me.gacl</groupId> <artifactId>spring4-mybatis3</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>spring4-mybatis3</name> <url>http://maven.apache.org</url> <dependencies> <!-- Add Spring4.1.4 Core Package--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.4.RELEASE</version> </dependency> </dependencies> <build> <finalName>spring4-mybatis3</finalName> </build></project>
In this way, Maven will automatically help us download the spring-core jar package from Maven's central repository to our local repository, and then add the spring-core jar package and its related dependencies to our project, as shown below:
The related jar packages required by spring4.x and mybatis3.x can be searched in the above method and then added to the project. After adding the related jar packages related to spring4.x and mybatis3.x, the content of the pom.xml file is finally as follows:
<project xmlns="http://maven.apache.org/POM/.." xmlns:xsi="http://www.w.org//XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/.. http://maven.apache.org/maven-v__.xsd"> <modelVersion>..</modelVersion> <groupId>me.gacl</groupId> <artifactId>spring-mybatis</artifactId> <packaging>war</packaging> <version>.-SNAPSHOT</version> <name>spring-mybatis</name> <url>http://maven.apache.org</url> <dependencies> <!-- Add Spring-core package--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>...RELEASE</version> </dependency> <!-- Add spring-context package--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>...RELEASE</version> </dependency> <!-- Add spring-tx package--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>...RELEASE</version> </dependency> <!-- Add spring-jdbc package--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>...RELEASE</version> </dependency> <!-- Add spring-jdbc package--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>...RELEASE</version> </dependency> <!-- To facilitate unit testing, add spring-test package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>...RELEASE</version> </dependency> <!--Add spring-web package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>...RELEASE</version> </dependency> <!--Add aspectjweaver package --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>..</version> </dependency> <!-- Add mybatis core package --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>..</version> </dependency> <!-- Add mybatis core packages integrated with Spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>..</version> </dependency> <!-- Add servlet.core package --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>..</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp</artifactId> <version>..-b</version> </dependency> <!-- jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>.</version> </dependency> <!-- Add mysql driver package --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>..</version> </dependency> <!-- Add druid connection pool package --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>..</version> </dependency> <!-- Add junit unit test package--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>.</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>spring-mybatis</finalName> </build> </project>
4.2. Write relevant configuration files
1. dbconfig.properties
Create a dbconfig.properties file in the src/main/resources directory to write relevant information about connecting to the MySQL database. The content of dbconfig.properties is as follows:
driverClassName=com.mysql.jdbc.DrivervalidationQuery=SELECT 1jdbc_url=jdbc:mysql://localhost:3306/spring4_mybatis3?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNulljdbc_username=rootjdbc_password=XDP
2. spring.xml (configuration file of spring framework)
Create a spring.xml file in the src/main/resources directory. The spring.xml file is the core configuration file written for the Spring framework. The content of spring.xml is as follows:
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- Introduce dbconfig.properties property file--> <context:property-placeholder location="classpath:dbconfig.properties" /> <!-- Introduce dbconfig.properties property file--> <context:property-placeholder location="classpath:dbconfig.properties" /> <!-- Automatically scan (automatic injection), scan the me.gacl.service package and all classes annotated with @Service annotation of the class --> <context:component-scan base-package="me.gacl.service" /></beans>
The configuration of our spring.xml file is very simple, there are only two configurations.
3. spring-mybatis.xml (configuration file integrated with spring and mybatis)
Create a spring-mybatis.xml file in the src/main/resources directory. The spring-mybatis.xml file is a configuration file written for the integration of Spring framework and Mybatis framework. The content of spring-mybatis.xml is as follows:
<?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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- JNDI method configuration data source--> <!-- <bean id="dataSource"> <property name="jndiName" value="${jndiName}"></property> </bean> --> <!-- =========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== name="username" value="${jdbc_username}" /> <property name="password" value="${jdbc_password}" /> <!-- Initialize the connection size --> <property name="initialSize" value="0" /> <!-- Maximum number of connections used by the connection pool--> <property name="maxActive" value="20" /> <!-- Maximum number of connections free --> <property name="maxIdle" value="20" /> <!-- Minimum number of connections free --> <property name="minIdle" value="0" /> <!-- Get the maximum waiting time for connections--> <property name="maxWait" value="60000" /> <!-- <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="33" /> --> <property name="validationQuery" value="${validationQuery}" /> <property name="testOnBorrow" value="false" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <property name="testWhileIdle" value="true" /> <!-- Configure how long it takes to perform a detection interval to detect the idle connection that needs to be closed, in milliseconds --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- Configure the minimum time for a connection to survive in the pool, in milliseconds --> <property name="minEvictableIdleTimeMillis" value="25200000" /> <!-- Turn on removeAbandoned function-> <property name="removeAbandoned" value="true" /> <!-- 1800 seconds, that is, 30 minutes --> <property name="removeAbandonedTimeout" value="1800" /> <!-- Output error log when closing the abandoned connection --> <property name="logAbandoned" value="true" /> <!-- Monitoring database --> <!-- <property name="filters" value="stat" /> --> <property name="filters" value="mergeStat" /> </bean> <!-- ======================================================================================================================================================================================================================================================================================================================================================================================================================================= =============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== Save the manual configuration value="classpath:me/gacl/mapping/*.xml" in Configuration.xml refers to all xml files in the me.gacl.mapping package under classpath (classpath) in the userMapper.xml is located under the me.gacl.mapping package, so that UserMapper.xml can be automatically scanned --> <property name="mapperLocations" value="classpath:me/gacl/mapping/*.xml" /> </bean> <!-- Configuration scanner--> <bean> <!-- Scan the me.gacl.dao package and all mapping interface classes under its subpackage --> <property name="basePackage" value="me.gacl.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> <!-- ========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================= transaction-manager="transactionManager" /> --> <!-- Interceptor configuration --> <tx:advice id="transactionAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="append*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="modify*" propagation="REQUIRED" /> <tx:method name="edit*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="remove*" propagation="REQUIRED" /> <tx:method name="repair" propagation="REQUIRED" /> <tx:method name="delAndRepair" propagation="REQUIRED" /> <tx:method name="delAndRepair" propagation="REQUIRED" /> <tx:method name="get*" propagation="SUPPORTS" /> <tx:method name="find*" propagation="SUPPORTS" /> <tx:method name="load*" propagation="SUPPORTS" /> <tx:method name="search*" propagation="SUPPORTS" /> <tx:method name="datagrid*" propagation="SUPPORTS" /> <tx:method name="*" propagation="SUPPORTS" /> <tx:method name="*" propagation="SUPPORTS" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="transactionPointcut" expression="execution(* me.gacl.service..*Impl.*(..))" /> <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" /> </aop:config> <!-- Configure druid monitoring spring jdbc --> <bean id="druid-stat-interceptor"> </bean> <bean id="druid-stat-pointcut" scope="prototype"> <property name="patterns"> <list> <value>me.gacl.service.*</value> </list> </property> </bean> <aop:config> <aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" /> </aop:config></beans>At this point, the relevant configuration files have been written, as shown in the figure below:
4.3. Conduct unit tests
After the above two steps, the integration of spring 4 and mybatis3 has been completed. The next task we need to do is to conduct unit testing to test whether the integration of spring4 and mybatis3 is successful.
1. Create a me.gacl.service package in the src/main/java directory, and then create a UserServiceI interface in the me.gacl.service package, as shown below:
package me.gacl.service; import me.gacl.domain.User; public interface UserServiceI { /** * Add user* @param user */ void addUser(User user); /** * Get user based on user id* @param userId * @return */ User getUserById(String userId); }2. Create a me.gacl.service.impl package in the src/main/java directory, and then create an implementation class for the UserServiceI interface in the me.gacl.service.impl package: UserServiceImpl, as shown below:
package me.gacl.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import me.gacl.dao.UserMapper; import me.gacl.domain.User; import me.gacl.service.UserServiceI; /** * @author gacl * Use @Service annotation to annotate the UserServiceImpl class as a service * The service id is userService */ @Service("userService") public class UserServiceImpl implements UserServiceI { /** * Use @Autowired annotation to annotate the userMapper variable * When you need to use UserMapper, Spring will automatically inject UserMapper */ @Autowired private UserMapper userMapper;//Inject dao @Override public void addUser(User user) { userMapper.insert(user); } @Override public User getUserById(String userId) { return userMapper.selectByPrimaryKey(userId); } }The two created classes are as follows:
3. Write a unit test class in the src/test/java directory, create a new me.gacl.test package, and then create a MyBatisTest class under this package. The code is as follows:
package me.gacl.test; import java.util.Date; import java.util.UUID; import me.gacl.domain.User; import me.gacl.service.UserServiceI; //import me.gacl.service.UserServiceI; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyBatisTest { private UserServiceI userService; /** * This before method is executed before all test methods and is only executed once* All initialization work during Junit unit testing can be performed in this method* For example, initializing ApplicationContext and userService in the before method */ @Before public void before(){ //Create Spring context using the two configuration files "spring.xml" and "spring-mybatis.xml" ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring.xml","spring-mybatis.xml"}); //Fetch the userService object we want to use based on the bean's id from the Spring container userService = (UserServiceI) ac.getBean("userService"); } @Test public void testAddUser(){ //ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring.xml","spring-mybatis.xml"}); //UserServiceI userService = (UserServiceI) ac.getBean("userService"); User user = new User(); user.setUserId(UUID.randomUUID().toString().replaceAll("-", "")); user.setUserName("White Tiger God Emperor xdp"); user.setUserBirthday(new Date()); user.setUserSalary(D); userService.addUser(user); } }When executing unit test code, the following error will be reported:
The error message is that the class "me.gacl.test.MyBatisTest" was not found, because we did not use maven to compile the class in the project.
Next, we use Maven to compile the project, select the project's pom.xml file →【Debug As】→【maven install】, as shown below:
The compilation results are as follows:
Here I will talk about the problems I encountered after executing Maven install. When I first executed the Maven install command, I saw the following messy errors:
Later I deleted the project, re-imported the project, and then executed the Clean project operation, as shown in the following figure:
I can compile and pass it normally after executing the Maven install operation, which made me depressed for a long time. This should not be the reason for my project configuration, but the reason for Maven. I don’t know why this is the case. Anyway, this is a solution. If you encounter a situation where the Maven install operation cannot be compiled normally: you can try to use the three steps: Maven clean → Clean project → Maven install to solve the problem.
In addition to unit testing with regular Junit, we can also use the Junit testing framework provided by Spring for unit testing, and create a new MyBatisTestBySpringTestFramework class under me.gacl.test, with the code as follows:
package me.gacl.test; import java.util.Date; import java.util.UUID; import me.gacl.domain.User; import me.gacl.service.UserServiceI; 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.junit.SpringJUnitClassRunner; @RunWith(SpringJUnitClassRunner.class) //After the @ContextConfiguration annotation is configured and the locations attribute of the annotation is specified with the spring and configuration file, @ContextConfiguration(locations = {"classpath:spring.xml", "classpath:spring-mybatis.xml" }) public class MyBatisTestBySpringTestFramework { //Inject userService @Autowired private UserServiceI userService; @Test public void testAddUser(){ User user = new User(); user.setUserId(UUID.randomUUID().toString().replaceAll("-", "")); user.setUserName("xdp_gacl_White Tiger God Emperor"); user.setUserBirthday(new Date()); user.setUserSalary(D); userService.addUser(user); } @Test public void testGetUserById(){ String userId = "fbcebfdada"; User user = userService.getUserById(userId); System.out.println(user.getUserName()); } }Perform these two test methods and pass the normal test, as shown below:
At this point, even if all the integration tests of our framework have been passed, the integration has been successful.
4.4. Test in web server
1. Edit the web.xml file and add the spring listener configuration item, the content is as follows:
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <description>Spring listener</description> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- ContextLoaderListener to use contextConfigLocation parameters that need to be used when initializing Spring context--> <context-param> <param-name>contextConfigLocation</param-name> <!-- Configure the location of spring.xml and spring-mybatis.xml, fixed writing method--> <param-value>classpath:spring.xml,classpath:spring-mybatis.xml</param-value> </context-param></web-app>
2. Add a getAllUser() method to obtain all user information in the UserMapper interface, as shown below:
package me.gacl.dao; import java.util.List; import me.gacl.domain.User; public interface UserMapper { int deleteByPrimaryKey(String userId); int insert(User record); int insertSelective(User record); User selectByPrimaryKey(String userId); int updateByPrimaryKeySelective(User record); int updateByPrimaryKey(User record); /**Get all user information* @return List<User> */ List<User> getAllUser(); }3. Write the SQL statement to execute the getAllUser() method in the UserMapper.xml file, as shown below:
<?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="me.gacl.dao.UserMapper" > <resultMap id="BaseResultMap" type="me.gacl.domain.User" > <id column="user_id" property="userId" jdbcType="CHAR" /> <result column="user_name" property="userName" jdbcType="VARCHAR" /> <result column="user_birthday" property="userBirthday" jdbcType="DATE" /> <result column="user_salary" property="userSalary" jdbcType="DOUBLE" /> </resultMap> <sql id="Base_Column_List" > user_id, user_name, user_birthday, user_salary </sql> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" > select <include refid="Base_Column_List" /> from t_user where user_id = #{userId,jdbcType=CHAR} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.String" > delete from t_user where user_id = #{userId,jdbcType=CHAR} </delete> <insert id="insert" parameterType="me.gacl.domain.User" > insert into t_user (user_id, user_name, user_birthday, user_salary) values (#{userId,jdbcType=CHAR}, #{userName,jdbcType=VARCHAR}, #{userBirthday,jdbcType=DATE}, #{userSalary,jdbcType=DOUBLE}) </insert> <insert id="insertSelective" parameterType="me.gacl.domain.User" > insert into t_user <trim prefix="(" suffix=")" suffixOverrides="," > <if test="userId != null" > user_id, </if> <if test="userName != null" > user_name, </if> <if test="userBirthday != null" > user_birthday, </if> <if test="userSalary != null" > user_salary, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides="," > <if test="userId != null" > #{userId,jdbcType=CHAR}, </if> <if test="userName != null" > #{userName,jdbcType=VARCHAR}, </if> <if test="userBirthday != null" > #{userBirthday,jdbcType=DATE}, </if> <if test="userSalary != null" > #{userSalary,jdbcType=DOUBLE}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="me.gacl.domain.User" > update t_user <set > <if test="userName != null" > user_name = #{userName,jdbcType=VARCHAR}, </if> <if test="userBirthday != null" > user_birthday = #{userBirthday,jdbcType=DATE}, </if> <if test="userSalary != null" > user_salary = #{userSalary,jdbcType=DOUBLE}, </if> </set> where user_id = #{userId,jdbcType=CHAR} </update> <update id="updateByPrimaryKey" parameterType="me.gacl.domain.User" > update t_user set user_name = #{userName,jdbcType=VARCHAR}, user_birthday = #{userBirthday,jdbcType=DATE}, user_salary = #{userSalary,jdbcType=DOUBLE} where user_id = #{userId,jdbcType=CHAR} </update> <!-- ==============以下内容是根据自身业务扩展的内容======================= --> <!-- select标签的id属性与UserMapper接口中定义的getAllUser方法要一模一样--> <select id="getAllUser" resultMap="BaseResultMap"> select user_id, user_name, user_birthday, user_salary from t_user </select></mapper>4、在UserServiceI接口中也添加一个getAllUser()方法,如下:
package me.gacl.service; import java.util.List; import me.gacl.domain.User; public interface UserServiceI { /** * 添加用户* @param user */ void addUser(User user); /** * 根据用户id获取用户* @param userId * @return */ User getUserById(String userId); /**获取所有用户信息* @return List<User> */ List<User> getAllUser(); }5、在UserServiceImpl类中实现getAllUser方法,如下:
package me.gacl.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import me.gacl.dao.UserMapper; import me.gacl.domain.User; import me.gacl.service.UserServiceI; /** * @author gacl * 使用@Service注解将UserServiceImpl类标注为一个service * service的id是userService */ @Service("userService") public class UserServiceImpl implements UserServiceI { /** * 使用@Autowired注解标注userMapper变量, * 当需要使用UserMapper时,Spring就会自动注入UserMapper */ @Autowired private UserMapper userMapper;//注入dao @Override public void addUser(User user) { userMapper.insert(user); } @Override public User getUserById(String userId) { return userMapper.selectByPrimaryKey(userId); } @Override public List<User> getAllUser() { return userMapper.getAllUser(); } }6、在src/main/java目录下创建一个me.gacl.web.controller包,然后在me.gacl.web.controller下创建一个UserServlet,如下:
package me.gacl.web.controller; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import me.gacl.domain.User; import me.gacl.service.UserServiceI; /** * @author gacl * @WebServlet是Servlet.提供的注解,目的是将一个继承了HttpServlet类的普通java类标注为一个Servlet * UserServlet使用了@WebServlet标注之后,就不需要在web.xml中配置了*/ @WebServlet("/UserServlet") public class UserServlet extends HttpServlet { //处理业务逻辑的userService private UserServiceI userService; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取所有的用户信息List<User> lstUsers = userService.getAllUser(); request.setAttribute("lstUsers", lstUsers); request.getRequestDispatcher("/index.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } public void init() throws ServletException { //在Servlet初始化时获取Spring上下文对象(ApplicationContext) ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); //从ApplicationContext中获取userService userService = (UserServiceI) ac.getBean("userService"); } }7、编辑index.jsp页面,用于展示查询到的用户信息,内容如下:
<%@ page language="java" pageEncoding="UTF-8"%><%--引入JSTL核心标签库--%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><!DOCTYPE html><html> <head> <title>显示用户信息</title> <style type="text/css"> table,td{ border: 1px solid; border-collapse: collapse; } </style> </head> <body> <table> <tr> <td>用户ID</td> <td>用户名</td> <td>用户生日</td> <td>工资</td> </tr> <%--遍历lstUsers集合中的User对象--%> <c:forEach var="user" items="${lstUsers}"> <tr> <td>${user.userId}</td> <td>${user.userName}</td> <td>${user.userBirthday}</td> <td>${user.userSalary}</td> </tr> </c:forEach> </table> </body></html>8、执行maven install命令编译项目,然后将项目部署到tomcat服务器中运行,注意,由于要使用Servlet3.0,所以必须将项目部署到tomcat7.x以上的服务器中去运行,如下所示:
输入地址:http://localhost:8080/spring4-mybatis3/UserServlet访问UserServlet,访问结果如下:
可以看到,t_user表中的用户信息全部查询出来显示到页面上了。这样在web服务器中的测试也正常通过了。
以上就是Spring4.x与MyBatis3.x整合的全部内容了。编写这个整合例子花了不少时间,使用Maven编译时总是出现莫名其妙的问题,有时候成功,有时候失败,反正很莫名其妙。如果遇到执行Maven install操作不能正常编译通过的情况:可以尝试采用:Maven clean→Clean项目→Maven install这三个步骤去解决问题