前言
MyBatis官网:http://www.mybatis.org/mybatis-3/zh/index.html
本文记录springboot与mybatis的整合实例;1、以注解方式;2、手写XML配置、逆向工程生成XML配置
maven依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-devtools
runtime
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.1
mysql
mysql-connector-java
runtime
application.yml
#注意:在yml文件中添加value值时,value前面需要加一个空格
#2.0.0的配置切换为servlet.path而不是"-"
server:
port: 10086 #端口号
servlet:
context-path: /springboot
spring:
thymeleaf:
cache: false #关闭页面缓存
prefix: classpath:/view/ #thymeleaf访问根路径
mode: LEGACYHTML5
datasource: #数据库相关
url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
mvc:
date-format: yyyy-MM-dd HH:mm:ss #mvc接收参数时对日期进行格式化
jackson:
date-format: yyyy-MM-dd HH:mm:ss #jackson对响应回去的日期参数进行格式化
time-zone: GMT+8
mybatis:
configuration:
map-underscore-to-camel-case: true #开启驼峰映射
result,通用响应数据格式
注:不想自己写set、get方法的用lombok插件
public class Result {
private String message;
private Integer status;
private Object data;
public Result() {
}
public Result(String message, Integer status, Object data) {
this.message = message;
this.status = status;
this.data = data;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "Result{" +
"message='" + message + '\'' +
", status=" + status +
", data=" + data +
'}';
}
public static Result build(Integer status,String message,Object data){
return new Result(message,status,data);
}
}
user,实体类
注:不想自己写set、get方法的用lombok插件
public class User {
private Integer id;
private String username;
private String password;
private Date created;
public User(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", created=" + created +
'}';
}
}
表SQL
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '表id',
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
`created` datetime NULL DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 45 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户信息表' ROW_FORMAT = Compact;
controller
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/insert")
public Result insert(User user) {
return userService.insert(user);
}
@RequestMapping("/delete")
public Result delete(User user) {
return userService.delete(user);
}
@RequestMapping("/update")
public Result update(User user) {
return userService.update(user);
}
@RequestMapping("/select")
public Result select(User user) {
return userService.select(user);
}
}
service
public interface UserService {
/**
* 增
*/
Result insert(User user);
/**
* 删
*/
Result delete(User user);
/**
* 改
*/
Result update(User user);
/**
* 查
*/
Result select(User user);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public Result insert(User user) {
int i = userMapper.insert(user);
if (i > 0) {
return Result.build(200, "操作成功!", user);
} else {
return Result.build(400, "操作失败!", null);
}
}
@Override
public Result delete(User user) {
int i = userMapper.delete(user);
if (i > 0) {
return Result.build(200, "操作成功!", user);
} else {
return Result.build(400, "操作失败!", null);
}
}
@Override
public Result update(User user) {
int i = userMapper.update(user);
if (i > 0) {
return select(user);
} else {
return Result.build(400, "操作失败!", null);
}
}
@Override
public Result select(User user) {
User user1 = userMapper.select(user);
if (user1 != null) {
return Result.build(200, "操作成功!", user1);
} else {
return Result.build(400, "操作失败!", user1);
}
}
}
接下来不同就是mapper映射了
注解方式
工程结构
mapper.java
直接使用注解,@Insert、@Delete、@Update、@Select,前三个事务自动提交,不用我们管理;增、删、改返回的是影响的行数,当设置了主键自动递增,需要返回自增主键时添加@Options(useGeneratedKeys = true),设置是否获取主键并设置到模型实体属性中;注意:insert接口返回的依旧是受影响的行数,但自增主键已经设置到了模型实体属性中。
这里介绍以下占位符跟拼接符的区别:
占位符 #{param}
占位符在拼接sql的过程中,会给指定的占位符,加上引号
简单类型传参:
1、会忽略占位符的名字
2、会忽略占位符的数据类型
3、会忽略占位符的顺序,将传进去的参加,依次赋给所有的占位符
适用场景:
单一占位符传参查询
拼接符 ${param}
拼接符相当于连接符合,把左右两边、自己拼接在一起
1、不接受简单类型传参,只接收对象类型或者Map集合类型传参
2、动态指定表名,列名,排序的方式(升序or降序)
@Mapper
@Component(value = "UserMapper")
public interface UserMapper {
/**
* 增
*/
@Insert(value = "insert into tb_user(username,password,created) value(#{username},#{password},#{created})")
@Options(useGeneratedKeys = true)
int insert(User user);
/**
* 删
*/
@Delete("delete from tb_user where id = #{id}")
int delete(User user);
/**
* 改
*/
@Update(value = "update tb_user set username = #{username} where id = #{id}")
int update(User user);
/**
* 查
*/
@Select(value = "select * from tb_user where id = #{id}")
User select(User user);
}
配置XML
工程目录
加多了mybatis相关的XML配置文件
其他部分都没有变,变的只有以下部分:
application.yml的mybatis部分改成,
mybatis:
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath:conf/mybatis/mapper/*.xml
# 加载全局的配置文件
configLocation: classpath:conf/mybatis/mybatis.cfg.xml
mapper.java
不再使用注解,将SQL写到XML里面
@Mapper
@Component(value = "UserMapper")
public interface UserMapper {
/**
* 增
*/
int insert(User user);
/**
* 删
*/
int delete(User user);
/**
* 改
*/
int update(User user);
/**
* 查
*/
User select(User user);
}
mybatis.cgf.xml
这里配置全局设置,但我这里没什么要配的
UserMapper.xml
因为我们的表主键是自动递增,insert标签使用useGeneratedKeys="true" keyProperty="id",模型实体属性就会设置递增后的值
insert into tb_user(username,password,created) value(#{username},#{password},#{created})
delete from tb_user where id = #{id}
update tb_user set username = #{username} where id = #{id}
效果展示
经测试,注解方式跟配置XML方式效果一致,传参、调用方式、返回结果都一致,接口均能正常调用。
insert接口
update接口
select接口
delete接口
后记
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
当我们一说起mybatis就会默默滴跟hibernate进行对比:
Hibernate DAO层开发比较简单,sql语句都封装好了,mybatis需要维护sql,手动写
Hibernate可移植性高,更改数据库方言即可,mybatis可移植性差,不同的数据库sql不同
Mybatis可以进行更细致的sql优化,减少没必要的查询字段,而hibernate封装太过彻底
代码开源
代码已经开源、托管到我的GitHub、码云:
GitHub:https://github.com/huanzi-qch/springBoot
码云:https://gitee.com/huanzi-qch/springBoot
版权声明
作者:huanzi-qch
出处:
https://www.cnblogs.com/huanzi-qch
若标题中有“转载”字样,则本文版权归原作者所有。若无转载字样,本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.