Spring Boot 整合 MyBatis

MyBatis 是一个半自动化的 ORM 框架,所谓半自动化是指 MyBatis 只支持将数据库查出的数据映射到 POJO 实体类上,而实体到数据库的映射则需要我们自己编写 SQL 语句实现,相较于 Hibernate 这种完全自动化的框架,Mybatis 更加灵活,我们可以根据自身的需求编写 sql 语句来实现复杂的数据库操作。

随着 Spring Boot 越来越流行,越来越多的被厂商及开发者所认可,MyBatis 也开发了一套基于 Spring Boot 模式的 starter:mybatis-spring-boot-starter。本篇文章就介绍下如何在 Spring Boot 项目中整合 MyBatis。

引入依赖

Spring Boot 整合 MyBatis 的第一步,就是在项目的 pom.xml 中引入 mybatis-spring-boot-starter 的依赖,示例代码如下。

<!--引入 mybatis-spring-boot-starter 的依赖-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

配置 MyBatis

在 Spring Boot 的配置文件(application.properties/yml)中对 MyBatis 进行配置,例如指定 mapper.xml 的位置、实体类的位置、是否开启驼峰命名法等等,示例代码如下。

mybatis:
  # 指定 mapper.xml 的位置
  mapper-locations: classpath:mappings/*.xml
  # 扫描实体类的位置,在此处指明扫描实体类的包,在 mapper.xml 中就可以不写实体类的全路径名
  type-aliases-package: com.example.hellospringboot
  configuration:
    # 默认开启驼峰命名法,可以不用设置该属性
    map-underscore-to-camel-case: true

注意:使用 MyBatis 时,必须配置数据源信息,例如数据库 URL、数据库用户型、数据库密码和数据库驱动等。

创建实体类

在指定的数据库内创建一个 person 表,并插入一些数据,如下表。

 

根据数据库 person 表,创建相应的实体类 Person,代码如下。

其中使用注解代替部分方法:

        @Data 会为类的所有属性自动生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法;

        @NoArgsConstructor:无参构造;

        @AllArgsConstructor:有参构造。

package com.example.hellospringboot.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    private Integer id;

    private String name;

    private String sex;

    private String idCardNum;
}

 

创建 Mapper 接口

在 com.example.hellospringboot.mapper 中创建一个 PersonMapper 接口,并在该类上使用 @Mapper 注解,代码如下。

package com.example.hellospringboot.mapper;

import com.example.hellospringboot.entity.Person;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
 * @author admin
 */
@Mapper
public interface PersonMapper {
    /**
     * 通过查询条件获取人员数据
     * @param person 查询条件
     * @return 人员数据
     */
    Person getByNameAndSex(@Param("person") Person person);
}

当 mapper 接口较多时,我们可以在 Spring Boot 主启动类上使用 @MapperScan 扫描指定包下的 mapper 接口,而不在需要在每个 mapper 接口上都标注 @Mapper 注解。

创建 Mapper 映射文件

在配置文件 application.properties/yml 通过 mybatis.mappe-locations 指定的位置中创建 PersonMapper.xml,代码如下。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mapper.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.hellospringboot.mapper.PersonMapper">
    <select id="getByNameAndSex" resultType="com.example.hellospringboot.entity.Person">
        select *
        from person
        <where>
            <if test="person.name != null and person.name != ''">
                and name like concat('%', #{person.name}, '%')
            </if>
            <if test="person.sex != null and person.sex != ''">
                and sex = #{person.sex}
            </if>
        </where>
    </select>
</mapper>

 使用 Mapper 进行开发时,需要遵循以下规则:

  • mapper 映射文件中 namespace 必须与对应的 mapper 接口的完全限定名一致。
  • mapper 映射文件中 statement 的 id 必须与 mapper 接口中的方法的方法名一致
  • mapper 映射文件中 statement 的 parameterType 指定的类型必须与 mapper 接口中方法的参数类型一致
  • mapper 映射文件中 statement 的 resultType 指定的类型必须与 mapper 接口中方法的返回值类型一致

创建 Service 接口

在 com.example.hellospringboot.service 包中创建一个名为 PersonService 的接口,代码如下。

package com.example.hellospringboot.service;

import com.example.hellospringboot.entity.Person;

public interface PersonService {
    /**
     * 通过查询条件获取人员数据
     * @param person 查询条件
     * @return 人员数据
     */
    Person getByNameAndSex(Person person);
}

创建 Service 接口的实现类

在 com.example.hellospringboot.service.impl 包中创建 PersonService 接口的实现类,并使用 @Service 注解将其以组件的形式添加到容器中,代码如下。

package com.example.hellospringboot.service.impl;

import com.example.hellospringboot.entity.Person;
import com.example.hellospringboot.mapper.PersonMapper;
import com.example.hellospringboot.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author admin
 */
@Service("personService")
public class PersonServiceImpl implements PersonService {

    @Autowired
    PersonMapper personMapper;

    @Override
    public Person getByNameAndSex(Person person) {
        return personMapper.getByNameAndSex(person);
    }
}

测试

在测试包中,创建一个测试类,输出查询结果。

package com.example.hellospringboot;

import com.example.hellospringboot.entity.Person;
import com.example.hellospringboot.service.PersonService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class MybatisTests {

    @Autowired
    PersonService personService;

    @Test
    void testMybatis() {
        System.out.println(personService.getByNameAndSex(new Person()));
    }

}

输出结果

Person(id=1, name=Bob, sex=1, idCardNum=220882199610104225)

注解方式

通过上面的学习,我们知道 mapper 映射文件其实就是一个 XML 配置文件,它存在 XML 配置文件的通病,即编写繁琐,容易出错。即使是一个十分简单项目,涉及的 SQL 语句也都十分简单,我们仍然需要花费一定的时间在 mapper 映射文件的配置上。

为了解决这个问题,MyBatis 针对实际业务中的使用最多的 “增删改查” 操作,分别提供了以下注解来替换 mapper 映射文件,简化配置:

  • @Select
  • @Insert
  • @Update
  • @Delete

通过以上注解,基本可以满足我们对数据库的增删改查操作,示例代码如下。

package com.example.hellospringboot.mapper;

import com.example.hellospringboot.entity.Person;
import org.apache.ibatis.annotations.*;

/**
 * @author admin
 */
@Mapper
public interface PersonMapper {
    /**
     * 通过查询条件获取人员数据
     * @param person 查询条件
     * @return 人员数据
     */
    @Select("select * from person where name = #{person.name,jdbcType=VARCHAR} and sex = #{person.sex,jdbcType=VARCHAR}")
    Person getByNameAndSex(@Param("person") Person person);

    /**
     * 根据id删除人员数据
     * @param id id
     * @return 删除条数
     */
    @Delete("delete from person where id = #{id}")
    int deleteById(Integer id);

    /**
     * 添加人员数据
     * @param person 人员数据
     * @return 添加条数
     */
    @Insert("insert into person (id, name, sex, id_card_num)" +
             "values (#{person.id}, #{person.name}, #{person.sex}, #{person.idCardNum})")
    int insert(@Param("person") Person person);

    /**
     * 根据id修改人员数据
     * @param person 人员数据
     * @return 修改条数
     */
    @Update("update person " +
            "  set name = #{person.name}, \n" +
            "      sex = #{person.sex}, \n" +
            "      id_card_num = #{person.idCardNum} \n" +
            "  where id = #{person.id}")
    int updateById(@Param("person") Person person);
}

注意事项

mapper 接口中的任何一个方法,都只能使用一种配置方式,即 注解和 mapper 映射文件二选一,但不同方法之间,这两种方式则可以混合使用,例如方法1使用注解方式,方法2使用 mapper 映射文件方式。

我们可以根据 SQL 的复杂程序,选择不同的方式来提高开发效率。

  • 如果没有复杂的连接查询,我们可以使用注解的方式来简化配置;
  • 如果涉及的 sql 较为复杂时,则使用 XML (mapper 映射文件) 的方式更好一些。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值