市面上主流的ORM框架很多,而在国内甚至亚洲地区使用最多的当属Mybatis了,而国外更多使用的是JPA。本文就带大家学习如何通过Spring Boot集成Mybatis。
本篇文章先以集成Mybatis XML版本为例。何谓XML版本?就是对应的SQL语句写在*mapper.xml文件中,而非通过注解的形式实现。
Mybatis简介
MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来配置和映射原始类型、接口和Java POJO(Plain Old Java Objects,普通老式Java对象)为数据库中的记录。
依赖引入
关于Mybatis的集成,我们已经从pom.xml引入的依赖说起,完整的pom依赖文件如下:
<?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 https://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.2.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.secbro</groupId> <artifactId>springboot-mybatis-xml</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-mybatis-xml</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--数据库连接相关--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <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> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
在该文件中,spring-boot-starter-web是针对spring boot在web应用的基础依赖。mysql-connector-java是mysql数据库驱动jar包。lombok是为了方便快速编码的工具类库。spring-boot-starter-test是为了单元测试引入的依赖,注意这里使用的junit5。
其中关于Mybatis集成的核心依赖便是mybatis-spring-boot-starter。通过名字,看起来像是一个spring boot官方提供的starter。其实不然,通过groupId我们可以看出,它属于mybatis官方提供的。
这从侧面也说明,mybatis对官方来说,重要程度与JPA还差一些。这也就是说为什么mybatis只是在亚洲比较流行了。
配置文件
在application.properties文件中添加如下配置:
spring.datasource.url=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=truespring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # 配置Mapper对应的XML文件路径mybatis.mapper-locations=classpath:mappers/*.xml# 配置实体类包路径mybatis.type-aliases-package=com.secbro.model
其中spring.datasource.*部分为配置数据源的,在前面我们已经讲到过。
关于Mybatis的配置有两项:扫描XML配置文件和扫描实体类的配置。
mybatis.mapper-locations,配置Mapper对应的XML文件路径;mybatis.type-aliases-package,配置项目中实体类包路径;
当然,如果针对mybatis还有其他全局性的配置也可以单独创建一个mybatis-config.xml的文件。然后通过下面的形式进行导入:
mybatis.config-location=classpath:mybatis/mybatis-config.xml
这上述配置过程中涉及到两个概念:Mapper的xml配置和Mapper接口。
Mapper的XML配置形式与注解形式相对照,效果一样。在xml文件中主要用来编写SQL语句及相关的结果集映射。
Mapper接口是指自行定义的一个数据操作接口,类似于通常所说的DAO接口。早期的Mapper接口需要自定义去实现,现在 MyBatis会自动为Mapper接口创建动态代理对象。Mapper接口的方法通常与Mapper配置文件中的select、insert、update、delete等XML结点存在一一对应关系。
启动类
完成上述配置之后,启动类上还要添加一个注解,用来开启Mapper的扫描。
@SpringBootApplication@MapperScan("com.secbro.mapper")public class SpringBootMainApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMainApplication.class, args); } }
其中包com.secbro.mapper便是我们前面提到过的Mapper接口所在的路径。
实体类及Mapper
实体类Order:
@Datapublic class Order { private int id; private String orderNo; private int amount;}
其中@Data为Lombok注解,会自动生成getter/setter等方法。
对应实体类的Mapper如下:
public interface OrderMapper { /** * 创建订单 * @param order 订单信息 * @return 记录数 */ int save(Order order); /** * 更新订单 * @param order 订单信息 * @return 记录数 */ int update(Order order); /** * 删除 * @param id id * @return 条数 */ int delete(int id); /** * 根据ID查询 * @param id 订单id * @return 订单详情 */ Order findById(int id); /** * 查询所有用户 * @return 用户列表 */ List<Order> findAll();}
对应Mapper的xml配置文件位于application.properties文件中的配置的classpath:mappers/*.xml目录下。这里我们放在resource目录下的mappers文件夹下。
<?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.secbro.mapper.OrderMapper" > <resultMap id="BaseResultMap" type="com.secbro.model.Order" > <id column="id" property="id" jdbcType="INTEGER" /> <result column="order_no" property="orderNo" jdbcType="VARCHAR" /> <result column="amount" property="amount" jdbcType="INTEGER" /> </resultMap> <sql id="Base_Column_List" > id, order_no, amount </sql> <insert id="save" parameterType="com.secbro.model.Order"> INSERT INTO tb_order (order_no,amount) VALUES (#{orderNo}, #{amount}) </insert> <update id="update" parameterType="com.secbro.model.Order"> UPDATE tb_order <set> <if test="orderNo != null">order_no = #{orderNo},</if> <if test="amount != null">amount = #{amount},</if> </set> WHERE id = #{id} </update> <delete id="delete" parameterType="int"> DELETE FROM tb_order WHERE id =#{id} </delete> <select id="findById" parameterType="int" resultMap="BaseResultMap" > SELECT <include refid="Base_Column_List" /> FROM tb_order WHERE id = #{id} </select> <select id="findAll" resultMap="BaseResultMap" > SELECT <include refid="Base_Column_List" /> FROM tb_order </select> </mapper>
经过上述步骤其实我们就可以直接进行测试了,为了演示Mapper的注入,我们再写一下Service层的代码和实现。
OrderService接口:
public interface OrderService { /** * 创建订单 * * @param order 订单信息 * @return 记录数 */ int save(Order order); /** * 更新订单 * * @param order 订单信息 * @return 记录数 */ int update(Order order); /** * 删除 * * @param id id * @return 条数 */ int delete(int id); /** * 根据ID查询 * * @param id 订单id * @return 订单详情 */ Order findById(int id); /** * 查询所有用户 * * @return 用户列表 */ List<Order> findAll(); }
OrderService实现:
@Service("orderService")public class OrderServiceImpl implements OrderService { @Resource private OrderMapper orderMapper; @Override public int save(Order order) { return orderMapper.save(order); } @Override public int update(Order order) { return orderMapper.update(order); } @Override public int delete(int id) { return orderMapper.delete(id); } @Override public Order findById(int id) { return orderMapper.findById(id); } @Override public List<Order> findAll() { return orderMapper.findAll(); } }
在实现类中,直接通过@Resource注入OrderMapper就可以进行使用了。
单元测试
@Slf4j@SpringBootTestclass OrderServiceTest { @Resource private OrderService orderService; @Test void save() { for (int i = 1; i <= 3; i++) { Order order = new Order(); order.setOrderNo("N00" + i); order.setAmount(10000); orderService.save(order); } } @Test void update() { Order order = new Order(); order.setId(1); order.setOrderNo("N001"); order.setAmount(8888); orderService.update(order); } @Test void delete() { orderService.delete(2); } @Test void findById() { Order order = orderService.findById(3); log.info("订单信息:{}", order); } @Test void findAll() { List<Order> list = orderService.findAll(); log.info("所有订单信息:{}", list); }}
至此,关于SpringBoot2.x集成Mybatis实战部分已经讲解完毕。后面,就可以进行具体业务的开发和扩展了。