Spring Boot 下 MyBatis 的几种使用方式


全篇测试代码 :https://github.com/ptaogege/mybatis_test

MyBatis + XML

使用 mybatis-spring-boot-starter 自动化配置 MyBatis 主要配置。同时,在 XML 中编写相应的 SQL 操作。

1、引入依赖

pom.xml 文件中,引入相关依赖。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- 实现对 MyBatis 的自动化配置 -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.4</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2、配置注解扫描 mapper

@SpringBootApplication
@MapperScan(basePackages = "com.springboot.mapper")  #注解扫描mapper
public class SpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }
}

3、配置 application.yaml

spring:
  # datasource 数据源配置内容
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis-test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root

# mybatis 配置内容
mybatis:
  config-location: classpath:mybatis-config.xml  # 配置 MyBatis 配置文件路径
  mapper-locations: classpath:mapper/*.xml  # 配置 Mapper XML 地址
  type-aliases-package: com.springboot.entity # 配置数据库实体包路径

4、mybatis 配置文件

resources 目录下,创建 mybatis-config.xml 配置文件。配置如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <!-- 使用驼峰命名法转换字段。 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer"/>
        <typeAlias alias="Long" type="java.lang.Long"/>
        <typeAlias alias="HashMap" type="java.util.HashMap"/>
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
        <typeAlias alias="ArrayList" type="java.util.ArrayList"/>
        <typeAlias alias="LinkedList" type="java.util.LinkedList"/>
    </typeAliases>

</configuration>

因为在数据库中的表的字段,我们是使用下划线风格,而数据库实体的字段使用驼峰风格,所以通过 mapUnderscoreToCamelCase = true 来自动转换。

resources/mapper 路径下,创建 UserMapper.xml 配置文件。

<?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.springboot.mapper.UserMapper">
    <sql id="FIELDS">
        id, username, password, create_time
    </sql>
    <insert id="insert" parameterType="UserDo" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO users (
            username, password, create_time
        ) VALUES (
                     #{username}, #{password}, #{createTime}
                 )
    </insert>

    <update id="updateById" parameterType="UserDo">
        UPDATE users
        <set>
            <if test="username != null">
                , username = #{username}
            </if>
            <if test="password != null">
                , password = #{password}
            </if>
        </set>
        WHERE id = #{id}
    </update>

    <delete id="deleteById" parameterType="Integer">
        DELETE FROM users
        WHERE id = #{id}
    </delete>

    <select id="selectById" parameterType="Integer" resultType="UserDo">
        SELECT
        <include refid="FIELDS" />
        FROM users
        WHERE id = #{id}
    </select>

    <select id="selectByUsername" parameterType="String" resultType="UserDo">
        SELECT
        <include refid="FIELDS" />
        FROM users
        WHERE username = #{username}
        LIMIT 1
    </select>

    <select id="selectByIds" resultType="UserDo">
        SELECT
        <include refid="FIELDS" />
        FROM users
        WHERE id IN
        <foreach item="id" collection="ids" separator="," open="(" close=")" index="">
            #{id}
        </foreach>
    </select>
</mapper>

5、代码实现

com.springboot.entity 下创建实体包 UserDo.java

/**
 * 用户id
 */
private Integer id;
/**
 * 账号
 */
private String username;
/**
 * 密码
 */
private String password;
/**
 * 创建时间
 */
private Date createTime;

//省略get/set方法

对应的SQL语句,数据库名为 mybatis-test

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
  `password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

com.springboot.mapper 下创建 UserMapper.java 接口

@Repository
public interface UserMapper {

    int insert(UserDo user);

    int updateById(UserDo user);

    int deleteById(@Param("id") Integer id);

    UserDo selectById(@Param("id") Integer id);

    UserDo selectByUsername(@Param("username") String username);

    List<UserDo> selectByIds(@Param("ids") Collection<Integer> ids);
}

@Repository 注解,用于标记是数据访问 Bean 对象。

@Param 注解,声明变量名。

6、测试

在测试类 SpringbootApplicationTests.java 中进行测试

@SpringBootTest
class SpringbootApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        UserDo userDo = new UserDo();
        userDo.setUsername(UUID.randomUUID().toString());
        userDo.setPassword("niubi");
        userDo.setCreateTime(new Date());
        userMapper.insert(userDo);
    }

    @Test
    public void testUpdateById() {
        UserDo userDo = new UserDo();
        userDo.setId(1);
        userDo.setPassword("niubi666");
        userMapper.updateById(userDo);
    }

    @Test
    public void testDeleteById() {
        userMapper.deleteById(5);
    }

    @Test
    public void testSelectById() {
        System.out.println(userMapper.selectById(1));
    }

    @Test
    public void testSelectByUsername() {
        userMapper.selectByUsername("penguin");
    }

    @Test
    public void testSelectByIds() {
        List<UserDo> users = userMapper.selectByIds(Arrays.asList(1, 3));
        System.out.println("users:" + users.size());
    }
}

MyBatis + 注解

注解方式与 xml 方式相差不多,如果使用注解,在 application.yaml 配置文件中,我们可以删除 mapper-locations 配置项。当然,如果想 XML 和注解一起使用,可以保留该配置项。

可以删除 UserMapper.xml 配置文件,在 UserMapper 接口上声明 SQL,注解的使用方式是在接口上通过注解声明 SQL 操作。

其他配置与 xml 相同。

UserMapper.java 接口上声明SQL:

@Repository
public interface UserMapper {

    @Insert("INSERT INTO users(username, password, create_time) VALUES(#{username}, #{password}, #{createTime})")
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    int insert(UserDO user);

    @Update(value = {
            "<script>",
            "UPDATE users",
            "<set>",
            "<if test='username != null'>, username = #{username}</if>",
            "<if test='password != null'>, password = #{password}</if>",
            "</set>",
            "</script>"
    })
    int updateById(UserDO user);

    @Insert("DELETE FROM users WHERE id = #{id}")
    int deleteById(@Param("id") Integer id); 
    
    @Select("SELECT username, password, create_time FROM users WHERE id = #{id}")
    UserDO selectById(@Param("id") Integer id);

    @Select("SELECT username, password, create_time FROM users WHERE username = #{username}")
    UserDO selectByUsername(@Param("username") String username);

    @Select(value = {
            "<script>",
            "SELECT username, password, create_time FROM users",
            "WHERE id IN",
            "<foreach item='id' collection='ids' separator=',' open='(' close=')' index=''>",
            "#{id}",
            "</foreach>",
            "</script>"
    })
    List<UserDO> selectByIds(@Param("ids") Collection<Integer> ids);
}

测试方法还是上面的测试类方法。

MyBatis-Plus

我们使用 mybatis-plus-boot-starter 自动化配置 MyBatis-Plus 的配置。

1、引入依赖

pom.xml 文件中,引入相关依赖。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>

<!-- 实现对 MyBatis Plus 的自动化配置 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.2</version>
</dependency>

2、配置 application.yaml

spring:
  # datasource 数据源配置内容
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis-test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root

# mybatis-plus 配置内容
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
  global-config:
    db-config:
      id-type: auto  # ID 主键自增
      logic-delete-value: 1  # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0  # 逻辑未删除值(默认为 0)
  mapper-locations: classpath:mapper/*.xml  # 配置 Mapper XML 地址
  type-aliases-package: com.springboot.entity  # 配置数据库实体包路径

logging:
  level:
    com:
      springboot:
        mapper: debug
        

相比 mybatis 配置项来说,mybatis-plus 增加了更多配置项,也因此我们无需在配置 mybatis-config.xml 配置文件。

配置 logging ,方便我们看到 MyBatis-Plus 自动生成的 SQL 。

3、代码实现

com.springboot.entity 下创建实体包 UserDo.java

@TableName(value = "users")
public class UserDo {
    
    private Integer id;
    
    private String username;
    
    private String password;
    
    private Date createTime;
    /**
     * 是否删除
     */
    @TableLogic
    private Integer deleted;
    
    //省略get/set方法
}
  • @TableName 注解,设置了 UserDo 对应的表名是 users

  • 增加了 deleted 字段,并添加了 @TableLogic 注解,设置该字段为逻辑删除的标记。

  • application.yaml 配置文件中,我们配置了删除(logic-delete-value = 1)和未删除(logic-not-delete-value = 0)。当然,也可以通过注解的 valuedelval 来定义未删除和删除。

对应的创建表的 SQL 如下:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
  `password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `deleted` bit(1) DEFAULT NULL COMMENT '是否删除。0-未删除;1-删除',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

com.springboot.mapper 下创建 UserMapper.java 接口

@Repository
public interface UserMapper extends BaseMapper<UserDo> {

    default UserDo selectByUsername(@Param("username") String username) {
        return selectOne(new QueryWrapper<UserDo>().eq("username", username));
    }

    List<UserDo> selectByIds(@Param("ids") Collection<Integer> ids);

    default IPage<UserDo> selectPageByCreateTime(IPage<UserDo> page, @Param("createTime") Date createTime) {
        return selectPage(page, new QueryWrapper<UserDo>().gt("create_time", createTime));
    }
}
  • 继承了 com.baomidou.mybatisplus.core.mapper.BaseMapper<T> 接口,这样常规的 CRUD 操作,MyBatis-Plus 就可以替我们自动生成。更多 BaseMapper 已经提供好的接口方法,可以看看《MyBatis-Plus 文档 —— CRUD 接口》
  • 对于 #selectByUsername() 方法,我们使用了 MyBatis-Plus 提供的QueryWrapper<T> 构造相对灵活的条件,这样一些动态 SQL 我们就无需在 XML 中编写。更多 QueryWrapper 已经提供好的拼接方法,可以看看 《MyBatis-Plus 文档 —— 条件构造器》
  • 对于 #selectByIds() 方法,实际也可以使用 MyBatis-Plus 的 QueryWrapper 很方便的实现,这里仅仅是为了演示在 MyBatis-Plus 混合使用 XML 。
  • 对于 #selectPageByCreateTime(IPage<UserDO> page, @Param("createTime") Date createTime) 方法,是用于演示 MyBatis-Plus 提供的分页插件。更多 IPage 的内容,可以看看 《MyBatis-Plus 文档 —— 分页插件》

resources/mapper 路径下,创建 UserMapper.xml 配置文件。代码如下:

<?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.springboot.mapper.UserMapper">
    <sql id="FIELDS">
        id, username, password, create_time
    </sql>

    <select id="selectByIds" resultType="UserDo">
        SELECT
        <include refid="FIELDS" />
        FROM users
        WHERE id IN
        <foreach item="id" collection="ids" separator="," open="(" close=")" index="">
            #{id}
        </foreach>
    </select>
</mapper>

4、测试

测试方法跟上面 XML 一样,多一个分页的单元测试方法,如下:

@Test
public void testSelectPageByCreateTime() {
    IPage<UserDo> page = new Page<>(1, 10);
    Date createTime = new Date(2021 - 1990, Calendar.FEBRUARY, 24);
    page = userMapper.selectPageByCreateTime(page, createTime);
    System.out.println("users:" + page.getRecords().size());
}

MyBatis-Plus 简化了 SQL 代码的编写工作,为编码提供了很多的方便。

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值