SpringBoot整合MyBatis实现增删改查
1.前言☕
大家好,我是Leo哥🫣🫣🫣,今天给大家带来关于精品SpringBoot专栏,暂且就给他起名为 循序渐进学SpringBoot,这里我参考了我上一个专栏:循序渐进学SpringSecurity6。有需要的朋友可以抓紧学习来哈,带你从SpringSecurity从零到实战项目。好了,我们进入正题,为什么会有SpringBoot这个专栏呢,是这样的,今年Leo哥也是正在重塑知识体系,从基础到框架,而SpringBoot又是我们框架中的核心,我觉得很有必要通过以博客的形式将我的知识系列进行输出,同时也锻炼一下自己的写作能力,如果能帮到大家那就更好啦!!!本地系列教程会从SpringBoot基础讲起,会以知识点+实例+项目的学习模式由浅入深对Spring Boot框架进行学习&使用。好了,话不多说让我们开始吧😎😎😎。
2.MyBatis概述
MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由Apache Software Foundation迁移到了Google Code,并且改名为MyBatis,也就是从3.0版本开始 iBatis改名为MyBatis。并且于2013年11月迁移到Github,地址:github.com/mybatis/myb… Maps和Data Access Objects(DAOs)
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
用一句话来形容什么Mybatis:MyBatis 是一个可以自定义 SQL、存储过程和高级映射的持久层框架。
3.整合MyBatis(XML方式)
3.1 创建项目
我们这里还是采用Maven的方式创建SpringBoot项目,这里就不做过多赘述了。
3.2 引入POM依赖
在项目的pom.xml
中引入MyBatis的Starter以及MySQL Connector依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--引入jdbc stater 目的是使用JDBC模板接口-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
</dependencies>
注意:
关于 mybatis-spring-boot-starter 包项目版本兼容有以下三点需要注意:
- Spring Boot 2.1+ 版本适用于:【MyBatis 3.5+】 && 【Java 8+ 】
- Spring Boot 2.0/2.1 版本适用于:【MyBatis 3.5+】 && 【Java 8+】
- Spring Boot 1.5 版本适用于:【MyBatis 3.4+】 && 【Java 6+】
所以这里同学们注意自己的项目版本是否跟Mybatis版本是否兼容,不兼容及时做出对于版本组合即可。
Leo哥测试了以下版本为最佳,且不会报错。
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency>
3.3 添加配置信息
server:
port: 8203
spring:
datasource:
url: jdbc:mysql://localhost:3306/leo-springboot-tutorial?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
username: root
password: root #数据库名、用户名和密码改为自己的
driver-class-name: com.mysql.cj.jdbc.Driver
# 开启驼峰映射
mybatis:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 添加日志SQL打印
3.4 创建其他类
1. 实体类
package org.javatop.mybatis.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author : Leo
* @date 2024-03-03 21:58
* @version 1.0
* @description : 实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
/**
* 主键id
*/
private Integer id;
/**
* 用户名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 性别
*/
private String sex;
/**
* 住址
*/
private String address;
/**
* 头像
*/
private String avatar;
}
2. mapper
package org.javatop.mybatis.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.javatop.mybatis.domain.User;
/**
* @author : Leo
* @date 2024-03-03 21:58
* @version 1.0
* @description :
*/
@Mapper
public interface UserMapper {
int deleteByPrimaryKey(Integer id);
int insert(User record);
int insertSelective(User record);
User selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(User record);
int updateByPrimaryKey(User record);
}
3. mapperxml
<?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="org.javatop.mybatis.mapper.UserMapper">
<resultMap id="BaseResultMap" type="org.javatop.mybatis.domain.User">
<!--@mbg.generated-->
<!--@Table `user`-->
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="age" jdbcType="INTEGER" property="age"/>
<result column="sex" jdbcType="VARCHAR" property="sex"/>
<result column="address" jdbcType="VARCHAR" property="address"/>
<result column="avatar" jdbcType="VARCHAR" property="avatar"/>
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id,
`name`,
age,
sex,
address,
avatar
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<!--@mbg.generated-->
select
<include refid="Base_Column_List"/>
from `user`
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--@mbg.generated-->
delete
from `user`
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="org.javatop.mybatis.domain.User"
useGeneratedKeys="true">
<!--@mbg.generated-->
insert into `user` (`name`, age, sex,
address, avatar)
values (#{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{sex,jdbcType=VARCHAR},
#{address,jdbcType=VARCHAR}, #{avatar,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="org.javatop.mybatis.domain.User"
useGeneratedKeys="true">
<!--@mbg.generated-->
insert into `user`
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">
`name`,
</if>
<if test="age != null">
age,
</if>
<if test="sex != null">
sex,
</if>
<if test="address != null">
address,
</if>
<if test="avatar != null">
avatar,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="age != null">
#{age,jdbcType=INTEGER},
</if>
<if test="sex != null">
#{sex,jdbcType=VARCHAR},
</if>
<if test="address != null">
#{address,jdbcType=VARCHAR},
</if>
<if test="avatar != null">
#{avatar,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="org.javatop.mybatis.domain.User">
<!--@mbg.generated-->
update `user`
<set>
<if test="name != null">
`name` = #{name,jdbcType=VARCHAR},
</if>
<if test="age != null">
age = #{age,jdbcType=INTEGER},
</if>
<if test="sex != null">
sex = #{sex,jdbcType=VARCHAR},
</if>
<if test="address != null">
address = #{address,jdbcType=VARCHAR},
</if>
<if test="avatar != null">
avatar = #{avatar,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="org.javatop.mybatis.domain.User">
<!--@mbg.generated-->
update `user`
set `name` = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
sex = #{sex,jdbcType=VARCHAR},
address = #{address,jdbcType=VARCHAR},
avatar = #{avatar,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
4. service
package org.javatop.mybatis.service;
import org.javatop.mybatis.mapper.UserMapper;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.javatop.mybatis.domain.User;
/**
* @author : Leo
* @date 2024-03-03 21:58
* @version 1.0
* @description : 业务层
*/
@Service
public class UserService{
@Autowired
private UserMapper userMapper;
public int deleteByPrimaryKey(Integer id) {
return userMapper.deleteByPrimaryKey(id);
}
public int insert(User record) {
return userMapper.insert(record);
}
public int insertSelective(User record) {
return userMapper.insertSelective(record);
}
public User selectByPrimaryKey(Integer id) {
return userMapper.selectByPrimaryKey(id);
}
public int updateByPrimaryKeySelective(User record) {
return userMapper.updateByPrimaryKeySelective(record);
}
public int updateByPrimaryKey(User record) {
return userMapper.updateByPrimaryKey(record);
}
}
5. controller
package org.javatop.mybatis.controller;
import org.javatop.mybatis.domain.User;
import org.javatop.mybatis.service.UserService;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
/**
* (user)表控制层
*
* @author Leo
*/
@RestController
@RequestMapping("/user")
public class UserController {
/**
* 服务对象
*/
@Autowired
private UserService userService;
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping("selectOne")
public User selectOne(Integer id) {
return userService.selectByPrimaryKey(id);
}
}
3.5 进行测试
启动项目之后,打开浏览器进行测试。
http://localhost:8203/user/selectOne?id=1
至此我们的SpringBoot整合MyBatis环境就已经通了。
4.注解方式
上面我们使用了xml配置文件的方式实现了。接下来我们来了解下如果通过注解的方式代替MyBatis简单的增删改查。
注意:简单的CRUD可以通过注解的方式,但是复杂的多表查询还是通过我们的XML进行编写。
我们重新创建一个名为UserMapper2的mapper通过注解的方式进行实现。
package org.javatop.mybatis.mapper;
import org.apache.ibatis.annotations.*;
import org.javatop.mybatis.domain.User;
import org.springframework.stereotype.Repository;
/**
* @author : Leo
* @date 2024-03-03 21:58
* @version 1.0
* @description :
*/
@Repository
public interface UserMapper2 {
@Delete("delete from user where id = #{id}")
int deleteByPrimaryKey(Integer id);
@Insert("insert into user (id, name, age) values (#{id}, #{name}, #{age})")
int insert(User record);
@Insert("insert into user (id, name, age) values (#{user.id}, #{user.name}, #{user.age})")
int insertSelective(@Param("user") User record);
@Select("select * from user where id = #{id}")
User selectByPrimaryKey(Integer id);
@Update("update user set name = #{name} where id = #{id}")
int updateByPrimaryKeySelective(User record);
@Update("update user set name = #{user.name}, age = #{user.age} where id = #{user.id}")
int updateByPrimaryKey(@Param("user") User record);
}
进行测试。
/**
* 用于测试: 注解方式测试
*/
@Test
public void test02() {
User user = userMapper2.selectByPrimaryKey(1);
System.out.println("user = " + user);
}
一样可以查出来。
提示:当 mapper 接口较多时,我们可以在 Spring Boot 主启动类上使用 @MapperScan 注解扫描指定包下的 mapper 接口,而不再需要在每个 mapper 接口上都标注 @Mapper 注解。代码演示如下:
/**
* @author : Leo
* @version 1.0
* @date 2024-03-03 21:48
* @description : 启动类
*/
@SpringBootApplication
@MapperScan(value = "org.javatop.mybatis.mapper")
public class MyBatisApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MyBatisApplication.class, args);
Environment environment = context.getBean(Environment.class);
System.out.println("访问链接:http://localhost:" + environment.getProperty("server.port"));
System.out.println("(♥◠‿◠)ノ゙ 项目启动成功 ლ(´ڡ`ლ)゙ \n");
}
}
5.注解配置说明
面通过几种不同传参方式来实现上文中实现的新增操作,来学习一下MyBatis中常用的一些注解。
5.1 传递参数使用@param
在上面的示例整合中我们已经用了这种最简单的传参方式,如下:
@Insert("insert into user (id, name, age) values (#{id}, #{name}, #{age})")
int insert(User record);
这种方式很好理解,@Param中定义的 id 对应了SQL中的#{id}参数,
@Param中定义的 name 对应了SQL中的#{name}参数等
。
5.2 传递参数使用Map
如下代码,通过Map<String,Object>对象来作为传递参数的容器:
//通过map进行用户插入
@Insert("INSERT INTO user(id,name, age) VALUES( #{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER})")
int insertByMap(Map<String, Object> map);
对于Insert语句中需要的参数,我们只需要在map中填入同名的内容即可,具体如下面代码所示:
Map<String, Object> map = new HashMap<>();
map.put("id", 2);
map.put("name", "黎明");
map.put("age", 20);
userMapper.insertByMap(map);
5.3 传递参数使用对象
@Insert("insert into user (id, name, age) values (#{user.id}, #{user.name}, #{user.age})")
int insertSelective(@Param("user") User record);
5.4 基本增删改查注解
MyBatis针对不同的数据库操作分别提供了不同的注解来进行配置,在之前的示例中演示了@Insert,下面针对DbUser表做一组最基本的增删改查作为示例:
@Delete("delete from user where id = #{id}")
int deleteByPrimaryKey(Integer id);
@Insert("insert into user (id, name, age) values (#{id}, #{name}, #{age})")
int insert(User record);
@Select("select * from user where id = #{id}")
User selectByPrimaryKey(Integer id);
@Update("update user set name = #{name} where id = #{id}")
int updateByPrimaryKeySelective(User record);
6.Mybatis的特点及优缺点
特点:
- MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。
- MyBatis 封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean 对象,大大简化了 Java 数据库编程的重复工作。
- MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
- MyBatis 可以使用简单的XML或注解用于配置和原始映射,将接口和Java的实体映射成数据库中的记录。
- MyBatis 把 SQL语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的维护带来了很大便利。
- MyBatis 需要程序员自己去编写 SQL语句,程序员可以结合数据库自身的特点灵活控制 SQL语句,因此能够实现比 Hibernate 等全自动 ORM框架更高的查询效率,能够完成复杂查询。
优点:
- 简单易学,Mybatis本身就很小且简单,整个源代码大概5MB左右。并且没有任何第三方依赖,简单实用只要几个Jar包+配置几个SQL映射文件,而且有官方中文文档,可以通过官方文档轻松学习。
- 使用灵活,易于上手和掌握。相比于JDBC需要编写的代码更少,减少了50%以上的代码量。
- 提供XML标签,支持编写动态SQL,满足不同的业务需求。
- SQL写在XML里,便于统一管理和优化,同时也解除SQL与程序代码的耦合。使系统的设计更清晰,更易维护,更易单元测试。SQL和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的ORM字段关系映射。
- 提供对象关系映射标签,支持对象关系组建维护。
缺点:
- SQL语句的编写工作量较大,尤其在表、字段比较多的情况下,对开发人员编写SQL的能力有一定的要求。
- SQL语句依赖于数据库,导致数据库不具有好的移植性,不可以随便更换数据库。
总体来说,MyBatis 是一个非常优秀和灵活的数据持久化框架,适用于需求多变的互联网项目,也是当前主流的 ORM 框架。
7.源码仓库
springboot-mybatis:github.com/gaoziman/Le…
以上便是本文的全部内容,本人才疏学浅,文章有什么错误的地方,欢迎大佬们批评指正!我是Leo,一个在互联网行业的小白,立志成为更好的自己。
如果你想了解更多关于Leo,可以关注公众号-程序员Leo,后面文章会首先同步至公众号。
本文由博客一文多发平台 OpenWrite 发布!
原文链接:https://juejin.cn/post/7349189143799021595 作者:程序员Leo说