Spring Maven 项目集成Mybatis

项目结构

环境配置

配置 pom.xml

修改JDK版本

pom.xml
1
2
3
4
5
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

添加依赖包

  • junit 单元测试
  • spring-context spring核心包
  • spring-test spring测试
  • spring-jdbc spring 数据库连接
  • spring-tx spring事务
  • aspectjweaver Aop
  • c3p0 c3p0 数据源
  • mybatis mybatis
  • mybatis-spring spring与mybatis整合的核心包
  • mysql-connector-java mysql 驱动
  • slf4j-api 日志包
  • slf4j-log4j12 日志打印相关的包,版本尽量和slf4j-api相同
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>

设置资源目录和插件

maven项目,如果源代码目录 src/main/java 存在 xm、properties、tld 等文件,maven默认不会自动编译该文件到输出目录,需要显示的配置 resources 标签。

pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
完整的pom.xml
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?xml version="1.0" encoding="UTF-8"?>

<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>org.example</groupId>
<artifactId>shsxt-spring-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>

<name>shsxt-spring-mybatis</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>

配置spring

配置 db.properties

db.properties
1
2
3
4
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
jdbc.username=root
jdbc.password=root

配置 mybatis.xml

mybatis.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
<settings>
<!-- 是否开启自动驼峰命名规则(camel case)映射,即从数据库列名 A_COLUMN 到属性名 aColumn 的类似映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 定义实体类别名 -->
<typeAliases>
<package name="org.example.po"/>
</typeAliases>
</configuration>

配置 log4j.properties

log4j.properties
1
2
3
4
5
6
7
8
9
10
11
log4j.rootLogger=DEBUG, Console

# Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

配置spring.xml

spring.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- 扫描基本包 -->
<context:component-scan base-package="org.example" />

<!-- 配置数据库基本信息 -->
<context:property-placeholder location="classpath:db.properties" />

<!-- 开启Aop -->
<ap:aspectj-autoproxy />

<!-- 配置 c3p0 数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}"/>
</bean>

<!-- 配置数据源的事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 设置事务通知 -->
<!-- add inert update delete 开头的方法都启用事务管理 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

<!-- aop 切面配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut id="servicePointcut" expression="execution(* org.example.service..*.*(..))"/>
<!-- 配置通知 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut" />
</aop:config>

<!-- 配置 mybatis 的 sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis.xml"/>
<property name="mapperLocations" value="classpath:org/example/mapper/*.xml"/>
</bean>

<!-- 配置dao/mapper接口扫描器 -->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.example.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
</beans>

添加源代码

数据表结构

创建 po 层实体类

用户实体类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package org.example.po;

import java.util.Date;

/**
* 用户实体类
*/
public class User {
private Integer userId;
private String userName;
private String userPwd;
private String userEmail;
private Date createDate;
private Date updateDate;

public User() {
}

public User(String userName, String userPwd, String userEmail) {
this.userName = userName;
this.userPwd = userPwd;
this.userEmail = userEmail;
this.createDate = new Date();
}

public Integer getUserId() {
return userId;
}

public void setUserId(Integer userId) {
this.userId = userId;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getUserPwd() {
return userPwd;
}

public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}

public String getUserEmail() {
return userEmail;
}

public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}

public Date getCreateDate() {
return createDate;
}

public void setCreateDate(Date createDate) {
this.createDate = createDate;
}

public Date getUpdateDate() {
return updateDate;
}

public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}

@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", userPwd='" + userPwd + '\'' +
", userEmail='" + userEmail + '\'' +
", createDate=" + createDate +
", updateDate=" + updateDate +
'}';
}
}

创建 dao 层接口

用户接口类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package org.example.dao;

import org.apache.ibatis.annotations.Param;
import org.example.po.User;

import java.util.Collection;
import java.util.Map;

/**
* 用户接口类
*/
public interface UserDao {
/**
* 通过用户名查询用户信息
* @param name 用户名
* @return
*/
User findByName(@Param("name") String name);

/**
* 查询 所有用户
* @return
*/
Collection<User> findAll();

/**
* 新增用户
* @param user
* @return
*/
Integer addUser(User user);

/**
* 更新用户信息
* @param user
*/
Integer updateUser(User user);

/**
* 删除用户
* @param id 用户id
* @return
*/
Integer deleteUser(@Param("id") Integer id);
}

创建接口对应的 mapper 层的数据库映射

mapper/UserMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?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="org.example.dao.UserDao">
<!-- 通过用户名查询用户信息 -->
<select id="findByName" parameterType="string" resultType="user">
select * from tb_user where user_name = #{name}
</select>

<!-- 查询所有用户 -->
<select id="findAll" resultType="user">
select * from tb_user;
</select>

<!-- 新增用户 -->
<insert id="addUser" parameterType="user" useGeneratedKeys="true" keyProperty="userId" keyColumn="user_id">
insert into tb_user(user_name, user_pwd, user_email, create_date)
values (#{userName}, #{userPwd}, #{userEmail}, #{createDate})
</insert>

<!-- 更新用户 -->
<update id="updateUser" parameterType="user">
update tb_user
<trim prefix="set" suffixOverrides=",">
<if test="userName != null">user_name=#{userName}</if>
<if test="userPwd != null">user_pwd=#{userPwd}</if>
<if test="userEmail != null">user_email=#{userEmail}</if>
<if test="updateDate != null">update_date=#{updateDate}</if>
</trim>
where user_id = #{userId}
</update>

<!-- 删除用户 -->
<delete id="deleteUser" parameterType="_int">
delete from tb_user where user_id=#{id}
</delete>
</mapper>

创建 service 层的业务类

用户业务逻辑类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package org.example.service;

import org.example.dao.UserDao;
import org.example.po.User;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;

/**
* 用户业务逻辑类
*/
@Service
public class UserService {
@Resource
private UserDao userDao;
/**
* 通过用户名查询用户信息
* @param name 用户名
* @return
*/
public User findByName(String name){
User user = userDao.findByName(name);
return user;
}

/**
* 查询 所有用户
* @return
*/
public Collection<User> findAll(){
return userDao.findAll();
}

/**
* 新增用户
* @param user
* @return
*/
public Integer addUser(User user){
return this.userDao.addUser(user);
}

/**
* 更新用户信息
* @param user
*/
public Integer updateUser(User user){
return this.userDao.updateUser(user);
}

/**
* 删除用户
* @param id 用户id
* @return
*/
public Integer deleteUser(Integer id){
return this.userDao.deleteUser(id);
}
}

创建 controller 层的控制器

用户控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package org.example.controller;

import org.example.po.User;
import org.example.service.UserService;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import java.util.Collection;

/**
* 用户控制器
*/
@Controller
public class UserController {
@Resource
private UserService userService;

/**
* 通过用户名查询用户信息
* @param name 用户名
* @return
*/
public User findByName(String name){
User user = userService.findByName(name);
return user;
}

/**
* 查询 所有用户
* @return
*/
public Collection<User> findAll(){
return userService.findAll();
}

/**
* 新增用户
* @param user
* @return
*/
public void addUser(User user){
this.userService.addUser(user);
}

/**
* 更新用户信息
* @param user
*/
public void updateUser(User user){
this.userService.updateUser(user);
}

/**
* 删除用户
* @param id 用户id
* @return
*/
public Integer deleteUser(Integer id){
return this.userService.deleteUser(id);
}
}

执行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package org.example;

import org.example.controller.UserController;
import org.example.po.User;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Collection;

public class UserTest {
/**
* 测试根据用户名查询用户
*/
@Test
public void testFindByName(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = ac.getBean("userController",UserController.class);
User user = userController.findByName("admin");
System.out.println(user);
Assert.assertTrue(user !=null);
}

/**
* 测试查询所有用户
*/
@Test
public void testFindAll(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = ac.getBean("userController",UserController.class);
Collection<User> users = userController.findAll();
System.out.println(users);
Assert.assertTrue(users != null && users.size() == 2);
}

/**
* 测试新增用户
*/
@Test
public void testAddUser(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = ac.getBean("userController",UserController.class);

User user = new User("test1","123456","test1@qq.com");

userController.addUser(user);
System.out.println(user);
Assert.assertTrue(user.getUserId() != null);
}

/**
* 测试更新用户
*/
@Test
public void testUpdateUser(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = ac.getBean("userController",UserController.class);

User user = new User();
user.setUserId(4);
user.setUserName("test4");

userController.updateUser(user);
System.out.println(user);
}

/**
* 测试删除用户
*/
@Test
public void testDeleteUser(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = ac.getBean("userController",UserController.class);

userController.deleteUser(4);
}
}