Mybatis简介
Mybatis简介
什么是MyBatis
- MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
- MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
- MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
什么是持久化
- 持久化是将程序数据在持久状态和瞬时状态间转换的机制。
- 简单理解就是,把在内存中的数据保存到本地文件上。
- 为什么需要持久化服务?因为如果只放在内存里,当内存断电后数据会丢失。
Mybatis能做什么
- 对JDBC进一步封装,使数据进行持久化。
- JDBC做什么,Mybatis就做什么。
- 有了JDBC为什么还使用Mybatis?因为MyBatis 封装了大量的接口和方法。方便使用。
- 优点:简单易学,能快速上手。可以动态编写SQL …
Springboot+MyBatis开发接口
创建数据库和表
CREATE DATABASE `test`;
USE `test`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user`(`id`,`name`,`pwd`) values
(1,'小明','123456'),
(2,'张三','321321'),
(3,'李四','321123');
创建项目


导入MyBatis相关 jar 包
在pom.xml文件中直接通过配置导入依赖
<!--配置mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--配置mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
配置datasource
有了上述的starter和mysql驱动之后,做一个小小的改变,将resources/application.properties文件删除。然后在此位置新建application.yml,然后写入数据库连接配置项:
server:
port: 8082
servlet:
context-path: /api
#####################上面三行在第一节已经解释
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
其中datasource各个字段含义:
url:
含义:数据库地址
格式:jdbc:mysql://数据库ip:数据库端口号/数据库名字?用户编码&字符编码&服务器时区
username:
- 含义:数据库账户名称
password:
- 含义:数据库账户密码
driver-class-name:
- 含义:数据库驱动类名
使用mybatis
通常来说有两种方式来使用mybatis:
- 使用注解
- 使用mapper 接下来通过基本的数据库操作-查询数据库来分别实践两种方式,然后再把增删改查四种方式都实现一遍。
几个约定
我是约定大于配置的拥趸,同样的,在springboot开发中也有一套约定,目前我觉得有两个好约定:代码结构和书写顺序:
代码结构最好是如下的组织结构:

以上代码结构也是良好的分层结构-三层controller dao service,其中对于service层通常习惯面向接口**(interface)编程,具体的实现在impl**中写实现类,提高了不同业务中针对同一接口的不同实现。
书写顺序 通常在web开发中,按照如下的四个顺序写代码,比较快、也比较容易组织代码
使用注解完成数据库查询
1、把数据库中要用到的表用实体类映射出来
entity文件夹下的User
package com.imooc.entity;
import java.util.Objects;
public class User {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id.equals(user.id) &&
name.equals(user.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
对于以上的属性,直接利用IDEA的快捷键alt+insert进行getter setter equals hashCode的快速实现,也可以借助lombok的注解快速实现。
package com.imooc.entity;
import lombok.Data;
@Data
public class User {
private Integer id;
private String name;
}
2、面向顶层来写代码,也就是对接的前端展示层,即controller层,可以认为是接口层。
controller文件夹下的UserController文件,下面有些文件爆红,暂时不用管继续写下一步
package com.imooc.controller;
import com.imooc.entity.User;
import com.imooc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping(value = "users")
public class UserController {
@Autowired
UserService userService;
@GetMapping(value = "", produces = {"application/json;charset=UTF-8"})
public List<User> getAllUsers() {
return userService.listUsers();
}
@PostMapping(value = "/getUsers", produces = {"application/json;charset=UTF-8"})
public List<User> getUsersByCondition(@RequestBody User user) {
return userService.listUsersByCondition(user);
}
}
对于controller层来说
首先要打上**@RestController的注解,告诉容器我是一个restful**风格的api层
其次使用**@RequestMapping注解标识接口的根路径为/users**
使用**@Autowired自动注入Service**层的逻辑接口。
使用**@GetMapping @PostMapping @PutMapping @DeleteMapping四种注解完成Restful**接口
3、在service中完成业务
这一层是后端实现逻辑的主要业务层,通常来说,这一层的代码结构采用两层来进行细化(详见上图的目录结构)
- 外层是接口定义
service文件夹下UserService文件
package com.imooc.service;
import com.imooc.entity.User;
import java.util.List;
public interface UserService {
List<User> listUsers();
List<User> listUsersByCondition(User user);
}
内层impl/去实现上面的interface
package com.imooc.service.impl;
import com.imooc.dao.UserDao;
import com.imooc.entity.User;
import com.imooc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
@Override
public List<User> listUsers() {
return userDao.findAll();
}
@Override
public List<User> listUsersByCondition(User user) {
return userDao.findUsersByCondition(user);
}
}
对于Service层来说,使用Spring框架的注解**@Service告诉容器我是Spring的一个Bean**

4、service中调用dao层相关sql去操作数据库
最后一步重要操作是通过mybatis的注解**@Select操作数据库查询数据,mybatis是它后来改的名字,也就是说必须先引入了mybatis的依赖,才能使用@Select**。
在dao文件夹UserDao文件加入如下代码
对于Dao层来说,使用Spring框架的注解**@Repository告诉容器我是Spring的一个Bean**
package com.imooc.dao;
import com.imooc.entity.User;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserDao {
@Select("select * from test.user;")
List<User> findAll();
//这个是使用mapper方式完成模糊查询
List<User> findUsersByCondition(User user);
}
上述的两个注解可以帮助开发人员在Bean类与容器入口类之间直接进行跳转。(点击UserDao接口右边的小球)
@Select注解后面的就是sql语句,@Select("select * from test_spring.user;"), 查询test_spring库的user表完成查询数据库的操作。
5、在入口文件中添加@MapperScan注解指向dao
@MapperScan
package com.imooc;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.imooc.dao")
public class MybaisSdutyApplication {
public static void main(String[] args) {
SpringApplication.run(MybaisSdutyApplication.class, args);
}
}
6、测试

使用mapper的方式完成模糊查询
要想使用mapper方式:
1、首先需要在配置文件application.yml中写入mapper的扫描路径
# 上面的基础配置
mybatis:
mapper-locations: classpath:mapper/*.xml
2、在resources/mapper目录下建立对应的user-mapper.xml,一张表一个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.imooc.dao.UserDao">
<select id="findUsersByCondition" resultType="com.imooc.entity.User" parameterType="com.imooc.entity.User">
-- SELECT * FROM test_spring.user WHERE name LIKE '%${name}%'
SELECT * FROM test.user WHERE name LIKE "%"#{name}"%"
</select>
</mapper>
上面的xml中
- mapper标签的namespace是dao层目录
- select标签表示这是查询数据库的操作,它的id是dao层的方法名字
- resultType是实体类的路径,也是返回结果类型
- parameterType的参数的类型,也是实体类。如果在dao使用下面的写法可以不用这个参数:
在dao文件夹UserDao文件加入如下代码
//这个是使用mapper方式完成模糊查询
List<User> findUsersByCondition(User user);
对于具体的sql语句,有如下两种模糊查询的写法
SELECT * FROM test_spring.user WHERE name LIKE '%${name}%'
SELECT * FROM test_spring.user WHERE name LIKE "%"#{name}"%"
3、结果
