前言

如题,今天介绍 SpringBoot 与 Mybatis 的整合以及 Mybatis 的使用,本文通过注解的形式实现。

什么是 Mybatis

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生 Map 使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。

优点:

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个 jar 文件+配置几个 sql 映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis 不会对应用程序或者数据库的现有设计强加任何影响。 sql 写在 xml 里,便于统一管理和优化。通过 sql 基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
  • 解除 sql 与程序代码的耦合:通过提供 DAL 层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql 和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的 orm 字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态 sql。

缺点:

  • 编写 SQL 语句时工作量很大,尤其是字段多、关联表多时,更是如此。
  • SQL 语句依赖于数据库,导致数据库移植性差,不能更换数据库。
  • 框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
  • 二级缓存机制不佳

准备工作

  • IDEA
  • JDK1.8
  • SpringBoot 2.1.3

sql 语句,创建表,插入数据:

CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` double DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `student` VALUES ('1', 'aaa', '21');
INSERT INTO `student` VALUES ('2', 'bbb', '22');
INSERT INTO `student` VALUES ('3', 'ccc', '23');

pom.xml 文件配置依赖

<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.nasus</groupId>
<artifactId>mybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis</name>
<description>mybatis Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<!-- 启动 web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- mysql 连接类 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- druid 数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<!-- lombok 插件 用于简化实体代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

application.yaml 配置文件

spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver

实体类

import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; @Data
@AllArgsConstructor
@NoArgsConstructor
public class Student { @Id
@GeneratedValue
private Integer id; private String name; private Integer age; }

使用了 lombok 简化了代码。

dao 层

import com.nasus.mybatis.domain.Student;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update; @Mapper
public interface StudentMapper { @Insert("insert into student(name, age) values(#{name}, #{age})")
int add(Student student); @Update("update student set name = #{name}, age = #{age} where id = #{id}")
int update(@Param("name") String name, @Param("age") Integer age, @Param("id") Integer id); @Delete("delete from student where id = #{id}")
int delete(int id); @Select("select id, name as name, age as age from student where id = #{id}")
Student findStudentById(@Param("id") Integer id); @Select("select id, name as name, age as age from student")
List<Student> findStudentList();
}

这里有必要解释一下,@Insert 、@Update、@Delete、@Select 这些注解中的每一个代表了执行的真实 SQL。 它们每一个都使用字符串数组 (或单独的字符串)。如果传递的是字符串数组,它们由每个分隔它们的单独空间串联起来。这就当用 Java 代码构建 SQL 时避免了“丢失空间”的问题。 然而,如果你喜欢,也欢迎你串联单独 的字符串。属性:value,这是字符串 数组用来组成单独的 SQL 语句。

@Param 如果你的映射方法的形参有多个,这个注解使用在映射方法的参数上就能为它们取自定义名字。若不给出自定义名字,多参数(不包括 RowBounds 参数)则先以 "param" 作前缀,再加上它们的参数位置作为参数别名。例如 #{param1},#{param2},这个是默认值。如果注解是 @Param("id"),那么参数就会被命名为 #{id}。

service 层

import com.nasus.mybatis.domain.Student;
import java.util.List; public interface StudentService { int add(Student student); int update(String name, Integer age, Integer id); int delete(Integer id); Student findStudentById(Integer id); List<Student> findStudentList(); }

实现类:

import com.nasus.mybatis.dao.StudentMapper;
import com.nasus.mybatis.domain.Student;
import com.nasus.mybatis.service.StudentService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service
public class StudentServiceImpl implements StudentService { @Autowired
private StudentMapper studentMapper; /**
* 添加 Student
* @param name
* @param age
* @return
*/
@Override
public int add(Student student) {
return studentMapper.add(student);
} /**
* 更新 Student
* @param name
* @param age
* @param id
* @return
*/
@Override
public int update(String name, Integer age, Integer id) {
return studentMapper.update(name,age,id);
} /**
* 删除 Student
* @param id
* @return
*/
@Override
public int delete(Integer id) {
return studentMapper.delete(id);
} /**
* 根据 id 查询 Student
* @param id
* @return
*/
@Override
public Student findStudentById(Integer id) {
return studentMapper.findStudentById(id);
} /**
* 查询所有的 Student
* @return
*/
@Override
public List<Student> findStudentList() {
return studentMapper.findStudentList();
}
}

controller 层构建 restful API

import com.nasus.mybatis.domain.Student;
import com.nasus.mybatis.service.StudentService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/Student")
public class StudentController { @Autowired
private StudentService studentService; @PostMapping("")
public int add(@RequestBody Student student){
return studentService.add(student);
} @PutMapping("/{id}")
public int updateStudent(@PathVariable("id") Integer id, @RequestParam(value = "name", required = true) String name,
@RequestParam(value = "age", required = true) Integer age){
return studentService.update(name,age,id);
} @DeleteMapping("/{id}")
public void deleteStudent(@PathVariable("id") Integer id){
studentService.delete(id);
} @GetMapping("/{id}")
public Student findStudentById(@PathVariable("id") Integer id){
return studentService.findStudentById(id);
} @GetMapping("/list")
public List<Student> findStudentList(){
return studentService.findStudentList();
}
}

测试结果

其他接口已通过 postman 测试,无问题。

源码下载:github 地址

后语

以上为 SpringBoot 实战 (九) | 整合 Mybatis 的教程,除了注解方式实现以外,Mybatis 还提供了 XML 方式实现。想了解更多用法请移步官方文档

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「一个优秀的废人」,关注后回复「1024」送你一套完整的 java 教程。



Spring Boot2 系列教程 (九) | SpringBoot 整合 Mybatis的更多相关文章

  1. Spring Boot2 系列教程(十七)SpringBoot 整合 Swagger2

    前后端分离后,维护接口文档基本上是必不可少的工作. 一个理想的状态是设计好后,接口文档发给前端和后端,大伙按照既定的规则各自开发,开发好了对接上了就可以上线了.当然这是一种非常理想的状态,实际开发中却 ...

  2. Spring Boot2 系列教程(二十一)整合 MyBatis

    前面两篇文章和读者聊了 Spring Boot 中最简单的数据持久化方案 JdbcTemplate,JdbcTemplate 虽然简单,但是用的并不多,因为它没有 MyBatis 方便,在 Sprin ...

  3. Spring Boot2 系列教程 (十二) | 整合 thymeleaf

    前言 如题,今天介绍 Thymeleaf ,并整合 Thymeleaf 开发一个简陋版的学生信息管理系统. SpringBoot 提供了大量模板引擎,包含 Freemarker.Groovy.Thym ...

  4. Spring Boot2 系列教程 (十六) | 整合 WebSocket 实现广播

    前言 如题,今天介绍的是 SpringBoot 整合 WebSocket 实现广播消息. 什么是 WebSocket ? WebSocket 为浏览器和服务器提供了双工异步通信的功能,即浏览器可以向服 ...

  5. Spring Boot2 系列教程(九)Spring Boot 整合 Thymeleaf

    虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...

  6. Spring Boot2 系列教程 (十八) | 整合 MongoDB

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 如题,今天介绍下 SpringBoot 是如何整合 MongoDB 的. MongoDB 简介 MongoDB 是由 C++ ...

  7. spring boot 系列之七:SpringBoot整合Mybatis

    springboot已经很流行,但是它仍需要搭配一款ORM框架来实现数据的CRUD,之前已经分享过JdbcTemplete和JPA的整合,本次分享下Mybatis的整合. 对于mybatis的使用,需 ...

  8. Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源

    多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...

  9. Spring Boot2 系列教程(三十)Spring Boot 整合 Ehcache

    用惯了 Redis ,很多人已经忘记了还有另一个缓存方案 Ehcache ,是的,在 Redis 一统江湖的时代,Ehcache 渐渐有点没落了,不过,我们还是有必要了解下 Ehcache ,在有的场 ...

随机推荐

  1. P1002 Hello,World!

    题目描述 输出"Hello Wolrd!". 输入格式 无. 输出格式 输出一行"Hello World!". 样例输入 无. 样例输出 Hello World ...

  2. linux kgdb 补丁

    目前为止我们看到的 2 个交互式调试方法( 使用 gdb 于 /proc/kcore 和 kdb) 都缺乏 应用程序开发者已经熟悉的那种环境. 如果有一个真正的内核调试器支持改变变量, 断点 等特色, ...

  3. H3C 聚合链路负载分担原理

  4. linux获知当前时间

    内核代码能一直获取一个当前时间的表示, 通过查看 jifies 的值. 常常地, 这个值只代 表从最后一次启动以来的时间, 这个事实对驱动来说无关, 因为它的生命周期受限于系统 的 uptime. 如 ...

  5. IDEA + Spring boot 单元测试

    1. 创建测试类 打开IDEA,在任意类名,任意接口名上,按ctrl+shift+t选择Create New Test image 然后根据提示操作(默认即可),点击确认,就在项目的/test/jav ...

  6. 基于koa2操作mysql封装例子

    新建better-mysql.js const mysql = require('mysql'); const config = require('../config/sqlConfig.js') l ...

  7. CDM命令实现MySql数据库文件的导出导入

    1.首先进入MySQL的安装目录,找到Bin文件夹,我这里安装的目录是C:\Program Files\MySQL\MySQL Server 8.0\bin ,进入该文件夹后在空白处按下Shift键+ ...

  8. Java 注解与单元测试

    注解 Java注解是在JDK1.5 之后出现的新特性,用来说明程序的,注解的主要作用体现在以下几个方面: 编译检查,例如 @Override 编写文档,java doc 会根据注解生成对应的文档 代码 ...

  9. django框架(2)

    cookie和session 1.cookie不属于http协议范围, 由于http协议无法保持状态, 但实际情况, 我们却又需要"保持状态",因此cookie就是在这样一个场景下 ...

  10. MySQL性能优化:MySQL中的隐式转换造成的索引失效

    数据库优化是一个任重而道远的任务,想要做优化必须深入理解数据库的各种特性.在开发过程中我们经常会遇到一些原因很简单但造成的后果却很严重的疑难杂症,这类问题往往还不容易定位,排查费时费力最后发现是一个很 ...