1. 引言
在项目开发中, 我们经常需要使用数据库操作, 而针对Java开发中的数据库持久化技术和框架包括:基础JDBC、JPA、MyBatis、Hibernate等。 近期接手一个项目开发工作, 使用Spring Boot + Mybatis技术进行开发, 现就Spring Boot与Mybatis集成的相关配置与操作记录做一下记录。
1.1 开发环境
JDK 1.8
Intellij IDEA 2017
MySQL 5.1.7
Spring Boot 2.0.0.RELEASE
MyBatis 3
2. Spring Boot 与 MyBatis 集成配置
1. 创建Spring Boot 项目
使用Intellij Idea中的Spring Initializr创建Spring Boot项目
配置项目元数据: 项目包信息、项目名、项目编译打包工具(Maven、Gradle,此处选择Maven)、JDK版本、打包方式(Jar或War)等
配置项目所依赖的组件信息,根据项目需要选择相关的项目依赖包, 选择的项目组件包括: Web、JDBC、MySQL和MyBatis等
项目创建完成后, Intellij Idea生成相关的项目文件, 查看生成的Maven依赖文件Pom.xml:
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.garyond.hurricane
info-manager
0.0.1-SNAPSHOT
jar
info-manager
Information Manager project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.2.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
mysql
mysql-connector-java
runtime
com.alibaba
druid
1.1.9
com.alibaba
druid-spring-boot-starter
1.1.9
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
2. 配置项目application.yml配置文件
Spring Boot支持application.properties和application.yml两种配置文件, 从配置文件的可读性考虑, 项目采用了application.yml配置文件方式, 配置文件中添加数据源连接、MyBatis配置等,如下所示:
# Server Port and Encoding
server:
port: 9969
servlet:
context-path: /infoMgr
# Spring Datasource Settings
spring:
datasource:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.202.17:3306/auth_service?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
filters: stat
max-active: 100
initial-size: 1
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
# Mybatis config
mybatis:
mapper-locations: classpath:mapping/*.xml
type-aliases-package: com.garyond.hurricane.infomanager.model
3. 创建项目数据库
配置完项目开发环境后,根据项目整体设计, 创建项目数据库, 如下示例代码:
create database infoMgr;
create table base_user
(
user_id varchar(64) not null,
dept_id int,
user_name varchar(50),
password varchar(64),
real_name varchar(50),
phone varchar(30),
mobile varchar(30),
email varchar(50),
create_time timestamp,
user_status int,
primary key (user_id)
);
... ...
4. 使用 MyBatis Generator自动生成相关的代码
我们在项目pom.xml文件中可以添加MyBatis Generator插件, 并配置Generator插件对应的配置文件${basedir}/src/main/resources/generator/generator.config.xml, 该配置文件用于指定MyBatis下模型、DAO生成的映射包名和位置等信息:
配置完MyBatis自动代码生成配置文件后,需要在Pom.xml中添加MyBatis Generator相应的依赖包,用于对MyBatis Generator进行自动代码生成。
org.springframework.boot
spring-boot-maven-plugin
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.6
${basedir}/src/main/resources/generator/generator.config.xml
true
true
下一步, 在Intellij Idea开发工具中配置Maven运行命令, 如下操作:
上图中点Edit Configuration按钮, 进入运行配置界面, 选择左上角的“+”号按钮, 选择Maven插件:
在弹出的Maven运行配置界面中添加名称和命令行参数mybatis-generator:generate -e:
完成上述配置后, IntelliJ Idea工具下会生成运行名称, 如下所示:
点击刚配置完成的Table-Generator右边的运行按钮即可执行生成相关的Entity和Dao代码包。
5. 查看生成的代码包
User.java
import java.util.Date;
public class User{
private String userId ;
private Integer unitId;
private String unitName;
private String userName;
private String password;
private String realName;
private String phone;
private String mobile;
private String email;
private Date createTime;
private Integer userStatus;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Integer getUnitId() {
return unitId;
}
public void setUnitId(Integer unitId) {
this.unitId = unitId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName == null ? null : userName.trim();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName == null ? null : realName.trim();
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone == null ? null : phone.trim();
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile == null ? null : mobile.trim();
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email == null ? null : email.trim();
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getUserStatus() {
return userStatus;
}
public void setUserStatus(Integer userStatus) {
this.userStatus = userStatus;
}
public String getUnitName() {
return unitName;
}
public void setUnitName(String unitName) {
this.unitName = unitName;
}
}
UserMapper.java
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);
}
UserMapper.xml
user_id, unit_id, user_name, password, real_name, phone, mobile, email,
create_time, user_status
select
from base_user
where user_id = #{userId,jdbcType=VARCHAR}
delete from base_user
where user_id = #{userId,jdbcType=VARCHAR}
insert into base_user (user_id, unit_id, user_name,
password, real_name, phone,
mobile, email,
create_time, user_status)
values (#{userId,jdbcType=VARCHAR}, #{unitId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR},
#{password,jdbcType=VARCHAR}, #{realName,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR},
#{mobile,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR},
#{createTime,jdbcType=TIMESTAMP}, #{userStatus,jdbcType=INTEGER})
insert into base_user
user_id,
unit_id,
user_name,
password,
real_name,
phone,
mobile,
email,
create_time,
user_status,
#{userId,jdbcType=VARCHAR},
#{unitId,jdbcType=INTEGER},
#{userName,jdbcType=VARCHAR},
#{password,jdbcType=VARCHAR},
#{realName,jdbcType=VARCHAR},
#{phone,jdbcType=VARCHAR},
#{mobile,jdbcType=VARCHAR},
#{email,jdbcType=VARCHAR},
#{createTime,jdbcType=TIMESTAMP},
#{userStatus,jdbcType=INTEGER},
update base_user
unit_id = #{unitId,jdbcType=INTEGER},
user_name = #{userName,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR},
real_name = #{realName,jdbcType=VARCHAR},
phone = #{phone,jdbcType=VARCHAR},
mobile = #{mobile,jdbcType=VARCHAR},
email = #{email,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=TIMESTAMP},
user_status = #{userStatus,jdbcType=INTEGER},
where user_id = #{userId,jdbcType=VARCHAR}
update base_user
set unit_id = #{unitId,jdbcType=INTEGER},
user_name = #{userName,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR},
real_name = #{realName,jdbcType=VARCHAR},
phone = #{phone,jdbcType=VARCHAR},
mobile = #{mobile,jdbcType=VARCHAR},
email = #{email,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=TIMESTAMP},
user_status = #{userStatus,jdbcType=INTEGER}
where user_id = #{userId,jdbcType=VARCHAR}
6. 编写业务逻辑代码及业务展现层
根据业务模型实现各个业务的业务逻辑和业务展现层, 以用户管理为例, 实现用户管理相关的操作逻辑。
用户业务服务接口: UserService.java
public interface UserService {
public int save(User user);
public int update(User user);
public int remove(User user);
public User getUserById(String userId);
}
用户业务服务实现:UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService{
@Resource
private UserMapper userMapper;
@Resource
private DepartmentMapper departmentMapper;
@Override
public int save(User user) {
return userMapper.insert(user);
}
@Override
public int update(User user) {
return userMapper.updateByPrimaryKeySelective(user);
}
@Override
public int remove(User user) {
return userMapper.deleteByPrimaryKey(user.getUserId());
}
@Override
public User getUserById(String userId) {
return userMapper.selectByPrimaryKey(userId);
}
}
用户业务展示:UserController.java
@RestController
@RequestMapping("/user")
public class UserPageController extends BaseController {
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.GET)
public String toPage(Model model) {
return "userPage";
}
/*
* 删除用户
*/
@RequestMapping("/create")
public @ResponseBody JsonResult saveUser(User user) {
User checkedUser = userService.getUserByUsername(user.getUserName());
if (null != checkedUser) {
return this.renderError("用户名:" + user.getUserName() + "已存在");
}
checkedUser = userService.getUserByEmail(user.getEmail());
if (null != checkedUser) {
return this.renderError("电子邮件:" + user.getEmail() + "已存在");
}
checkedUser = userService.getUserByMobile(user.getMobile());
if (null != checkedUser) {
return this.renderError("手机号码:" + user.getMobile() + "已存在");
}
String passwordDigest = new MD5().getTwiceMD5ofString(user.getPassword());
user.setPassword(passwordDigest);
userService.save(user);
return this.renderSuccess();
}
/*
* 更新用户
*/
@RequestMapping("/update")
public @ResponseBody JsonResult updateUser(User user) {
User checkedUser = userService.getUserById(user.getUserId());
if (null == checkedUser) {
return this.renderError("该用户不存在");
}
userService.update(user);
return this.renderSuccess();
}
/*
* 删除用户
*/
@RequestMapping("/remove")
public @ResponseBody JsonResult delete(String[] ids) {
for(String id: ids) {
userService.removeByUserId(id);
}
return this.renderSuccess();
}
}
7. 在Spring Boot应用启动类中启用MyBatis配置
在启动Spring Boot应用过程中, 需要在启动类中添加@Mapper注解,将MyBatis中的Mapper类路径进行启动加载, 否则MyBatis无法加载相应的数据持久化操作。
package com.garyond.hurricane.infomanager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.garyond.hurricane.infomanager.dao")
public class InfoManagerApplication {
public static void main(String[] args) {
SpringApplication.run(InfoManagerApplication.class, args);
}
}
8. 应用测试
完成上述步骤后, 启动Spring Boot应用, 我们可以编写jUnit对相应的业务API接口进行测试, 并且可以通过Postman等工具对应用接口进行测试。 具体测试方法和代码就不在这里一一讲述了。