前言
在项目的数据库开发中,不可避免地会使用到持久层框架。 当前主流的持久层框架有Spring Data、Hibernate、MyBatis等,这里使用MyBatis。
本文,集成MyBatis并实现了简单的增删改查。在使用过程中,指出MyBatis和项目的不足,并思考解决方案。
如果对MyBaits的使用很熟悉的,可以直接跳到总结。
具体实现
Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
参数配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://xxxxxxxx:3306/framework?useUnicode=true&characterEncoding=utf-8
username: xxxxxxxx
password: xxxxxxxx
mybatis:
mapper-locations: classpath:sql-mappers/*.xml
configuration:
map-underscore-to-camel-case: true
-
mybatis.mapper-locations 用于指定mapper文件的位置
-
mybatis.configuration.map-underscore-to-camel-case 用于开启驼峰功能
数据库列名:create_time 实体类属性:createTime
数据库表
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`id` INT (11) NOT NULL AUTO_INCREMENT,
`account` VARCHAR (40) NOT NULL COMMENT '用户名',
`password` VARCHAR (255) NOT NULL COMMENT '密码',
`nickname` VARCHAR (60) DEFAULT NULL COMMENT '昵称',
`email` VARCHAR (40) DEFAULT NULL COMMENT '邮箱',
`phone` VARCHAR (11) DEFAULT NULL COMMENT '电话',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`create_user` VARCHAR (11) DEFAULT NULL COMMENT '创建人',
`modify_time` datetime DEFAULT NULL COMMENT '修改时间',
`modify_user` VARCHAR (11) DEFAULT NULL COMMENT '修改人',
PRIMARY KEY (`id`)
) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4;
保存路径:classpath:resources/sqls/sys.sql
实体类
@Getter
@Setter
public class User extends Common {
private Long id;
@NotNull(message = "用户账号不能为空")
@Size(min = 6, max = 11, message = "账号长度必须是6-11个字符")
private String account;
@NotNull(message = "用户密码不能为空")
@Size(min = 6, max = 11, message = "密码长度必须是6-16个字符")
private String password;
@Size(max = 40, message = "用户昵称不能超过40个字符")
private String nickname;
@Email(message = "邮箱格式不正确")
private String email;
@Phone(message = "手机号格式不正确")
private String phone;
}
Mapper文件
<?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.zhuqc.framework.dao.UserDao">
<select id="getUser" resultType="com.zhuqc.framework.entity.User">
select * from sys_user where id = #{id, jdbcType = NUMERIC}
</select>
<insert id="addUser" parameterType="com.zhuqc.framework.entity.User">
insert into sys_user
(account,
password,
nickname,
email,
phone,
create_user,
create_time,
modify_user,
modify_time)
values
(#{account, jdbcType = VARCHAR},
#{password, jdbcType = VARCHAR},
#{nickname, jdbcType = VARCHAR},
#{email, jdbcType = VARCHAR},
#{phone, jdbcType = VARCHAR},
#{createUser, jdbcType = VARCHAR},
#{createTime, jdbcType = TIMESTAMP},
#{modifyUser, jdbcType = VARCHAR},
#{modifyTime, jdbcType = TIMESTAMP})
</insert>
<delete id="deleteUser">
delete from sys_user
where id = #{id, jdbcType = NUMERIC}
</delete>
<update id="updateUser" parameterType="com.zhuqc.framework.entity.User">
update sys_user
set nickname = #{nickname, jdbcType = VARCHAR},
email = #{email, jdbcType = VARCHAR},
phone = #{phone, jdbcType = VARCHAR},
modify_user = #{modifyUser, jdbcType = VARCHAR},
modify_time = #{modifyTime, jdbcType = TIMESTAMP}
where id = #{id, jdbcType = NUMERIC}
</update>
</mapper>
持久层UserDao
@Mapper
public interface UserDao {
User getUser(@Param("id") Long id);
int addUser(User user);
int deleteUser(@Param("id") Long id);
int updateUser(User user);
}
Mapper文件与Dao类需要一一对应
- Mapper文件中的namespace对应DAO接口的全路径
- Mapper文件中statement的id对应DAO接口中的方法名
- Mapper文件中statement的parameterType对应DAO接口中方法的输入参数类型
- Mapper文件中statement的resultType对应DAO接口中方法的返回类型
服务层 UserService
public interface UserService {
User getUser(Long id);
int addUser(User user);
int deleteUser(Long id);
int updateUser(User user);
}
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public User getUser(Long id) {
return userDao.getUser(id);
}
@Override
public int addUser(User user) {
return userDao.addUser(user);
}
@Override
public int deleteUser(Long id) {
return userDao.deleteUser(id);
}
@Override
public int updateUser(User user) {
return userDao.updateUser(user);
}
}
控制层 UserController
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ApiResult getUser(@PathVariable("id") Long id) {
return ApiResult.success(userService.getUser(id));
}
@PostMapping("/add")
public ApiResult addUser(@RequestBody @Valid User user) {
setCreateInfo(user);
return ApiResult.success(userService.addUser(user));
}
@DeleteMapping("/{id}")
public ApiResult deleteUser(@PathVariable("id") Long id) {
return ApiResult.success(userService.deleteUser(id));
}
@PutMapping("/{id}")
public ApiResult updateUser(@RequestBody @Valid User user) {
setModifyInfo(user);
return ApiResult.success(userService.updateUser(user));
}
}
编写完成后,访问Swagger地址对接口进行测试,如下:
总结
至此,成功的集成了MyBatis并实现了简单的增删改查。
但是在使用过程中我们很容易发现一些问题:
- 每个实体都需要写增删改查SQL,感觉重复劳动
- 没有SQL监控,不能统计SQL的运行情况
- 没有分页插件,分页查询比较麻烦
- 没有单元测试,接口测试比较麻烦
以上问题的解决方案:
- 使用代码生成器、集成MyBatis-plus。
- 使用阿里数据源Druid
- 集成分页插件PageHelper
- 单元测试通过MockMvc类调用Controller接口
解决方案均会在后面的文章中实现。
以上,感谢阅读。如果感觉有帮助的话,不妨随手点个赞!