摘要
本文详细介绍了MyBatis开发的完整步骤。首先在pom.xml文件中添加MyBatis及MySQL依赖,接着在application.properties或application.yml中配置数据源,包括数据库连接信息、连接池设置等。然后配置MyBatis Mapper,定义接口关联数据库操作方法,并可使用XML文件配置SQL。还需创建Domain实体类、Service层、Controller层,最后启动应用即可完成开发。请严格按照如下步骤进行操作,可以减少项目开发错时间和和同时提高开发效率。同时当springboot项目出现问题,也请参考如下步骤进行排除问题。
参考代码:Hera-Mybatis: 主要介绍的Mybatis的相关的原理和实践方案。 - Gitee.com
添加 MyBatis 依赖
在 pom.xml
文件中添加 MyBatis 和 MySQL 的依赖。如下文件提供一个参考:
java
<?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>
<groupId>com.zhuangxiaoyan</groupId>
<artifactId>springboot_mybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot_mybatis</name>
<description>springboot_mybatis</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
<springboot-mybatis-version>2.2.2</springboot-mybatis-version>
<lombok-version>1.18.30</lombok-version>
<druid-version>1.2.22</druid-version>
<mysql-connector-verison>5.1.49</mysql-connector-verison>
<junit4-version>4.12</junit4-version>
</properties>
<dependencies>
<!-- springboot-web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot-test依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- MyBatis依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${springboot-mybatis-version}</version>
</dependency>
<!--MySQL JDBC依赖,用来连接数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-verison}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Lombok注解 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok-version}</version>
<scope>provided</scope>
</dependency>
<!-- JUnit 4 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit4-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.zhuangxiaoyan.springboot.mybatis.SpringbootMybatisApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
领域Domain模型设计
plsql
CREATE
DATABASE springboot_mybatis CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
use
springboot_mybatis;
-- springboot_mybatis.address definition
CREATE TABLE `address`
(
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`street` varchar(128) NOT NULL COMMENT '街道',
`city` varchar(128) NOT NULL COMMENT '城市',
`country` varchar(128) NOT NULL COMMENT '国家',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modify` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`version` varchar(50) DEFAULT NULL COMMENT '版本号',
`extra_info` text COMMENT '扩展信息',
`customer_id` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Address 表';
-- springboot_mybatis.customer definition
CREATE TABLE `customer`
(
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '客户名称',
`phone` varchar(20) DEFAULT NULL COMMENT '客户电话',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modify` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`version` varchar(50) DEFAULT NULL COMMENT '版本号',
`extra_info` text COMMENT '扩展信息',
`order_id` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Customer 表';
-- springboot_mybatis.`order` definition
CREATE TABLE `order`
(
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`customer_id` varchar(100) NOT NULL COMMENT '客户ID',
`delivery_address_id` varchar(100) NOT NULL COMMENT '收货地址ID',
`total_price` decimal(10, 2) DEFAULT NULL COMMENT '订单总价',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modify` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`version` varchar(50) DEFAULT NULL COMMENT '版本号',
`extra_info` text COMMENT '扩展信息',
`order_item_id` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
-- springboot_mybatis.order_item definition
CREATE TABLE `order_item`
(
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`product_id` bigint(20) unsigned NOT NULL COMMENT '商品ID',
`amount` int(11) DEFAULT NULL COMMENT '数量',
`price` decimal(10, 2) DEFAULT NULL COMMENT '单价',
`order_id` bigint(20) unsigned NOT NULL COMMENT '订单ID',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modify` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`version` varchar(50) DEFAULT NULL COMMENT '版本号',
`extra_info` text COMMENT '扩展信息',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='订单项表';
-- springboot_mybatis.product definition
CREATE TABLE `product`
(
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '商品ID',
`name` varchar(255) NOT NULL COMMENT '商品名称',
`description` text COMMENT '商品描述',
`price` decimal(10, 2) NOT NULL COMMENT '商品价格',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modify` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`version` varchar(50) DEFAULT NULL COMMENT '版本号',
`extra_info` text COMMENT '扩展信息',
`order_item_id` bigint(20) unsigned NOT NULL COMMENT '关联order_item_id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
创建Java实体类
java
package com.zhuangxiaoyan.springboot.mybatis.domain;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* Product
*
* @author xjl
* @version 2025/01/11 16:58
**/
@Data
@EqualsAndHashCode
public class Product {
private long id;
/**
* 名称
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 价格
*/
private BigDecimal price;
/**
* 创建时间
*/
private Date gmtCreate;
/**
* 修改时间
*/
private Date gmtModify;
/**
* 版本号
*/
private String version;
/**
* 扩展信息
*/
private String extraInfo;
/**
* 订单项id
*/
private long OrderItemId;
@Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
", description='" + description + '\'' +
", price=" + price +
", gmtCreate=" + gmtCreate +
", gmtModify=" + gmtModify +
", version='" + version + '\'' +
", extraInfo='" + extraInfo + '\'' +
'}';
}
}
配置数据库连接配置
在 application.properties
或 application.yml
中配置数据源。
java
server:
port: 8080 # 设置应用程序运行端口
servlet:
context-path: /api # 设置应用程序的上下文路径
spring:
application:
name: springboot-mybatis-app # 设置 Spring Boot 应用程序的名称
datasource:
driver-class-name: com.mysql.jdbc.Driver # MySQL数据库驱动
url: jdbc:mysql://192.168.3.13:3306/springboot_mybatis?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&connectTimeout=10000&socketTimeout=10000 # 数据库连接URL
username: root # 数据库用户名
password: root # 数据库密码
hikari: # 配置 Hikari 数据源连接池(Spring Boot 2 默认使用 HikariCP)
minimum-idle: 5 # 最小空闲连接数
maximum-pool-size: 10 # 最大连接池大小
idle-timeout: 30000 # 空闲连接的最大生命周期(毫秒)
connection-timeout: 30000 # 连接超时时间(毫秒)
pool-name: HikariCP # 连接池名称
jackson:
serialization:
fail-on-empty-beans: false # 禁用 Jackson 序列化空 JavaBean 错误
thymeleaf:
cache: false # 开启/关闭 Thymeleaf 模板缓存
messages:
basename: messages # 配置国际化消息文件路径(messages.properties)
logging:
level:
root: INFO # 设置根日志级别
org.apache.ibatis: DEBUG # 设置根mybatis的日志级别
org.springframework.web: DEBUG # 设置 Spring Web 的日志级别
com.zhuangxiaoyan.springboot: DEBUG # 设置自定义包的日志级别
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n" # 设置日志输出格式
创建MyBatis Mapper接口类
Mapper 接口 :定义接口并与数据库操作方法关联。 注意检查@Mapper是否有
java
package com.zhuangxiaoyan.springboot.mybatis.dao;
import com.zhuangxiaoyan.springboot.mybatis.domain.Product;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* ProductDAO
*
* @author xjl
* @version 2025/01/11 21:22
**/
@Mapper
public interface ProductMapper {
/**
* 插入商品
*
* @param product
* @return
*/
int insertProduct(Product product);
/**
* 更新商品
*
* @param product
* @return
*/
int updateProduct(Product product);
/**
* 删除商品
*
* @param id
* @return
*/
int removeProduct(long id);
/**
* 根据id查询商品
*
* @param id
* @return
*/
Product getProductById(long id);
/**
* 查询所有商品
*
* @return
*/
List<Product> getAllProducts();
}
配置Mapper XML文件
可选,如果你不使用注解,可以使用 XML 进行 SQL 配置:
java
<?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.zhuangxiaoyan.springboot.mybatis.dao.ProductMapper">
<!-- 定义映射关系 -->
<resultMap id="BaseResultMap" type="com.zhuangxiaoyan.springboot.mybatis.domain.Product">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="description" column="description" jdbcType="VARCHAR"/>
<result property="price" column="price" jdbcType="DECIMAL"/>
<result property="gmtCreate" column="gmt_create" jdbcType="TIMESTAMP"/>
<result property="gmtModify" column="gmt_modify" jdbcType="TIMESTAMP"/>
<result property="version" column="version" jdbcType="VARCHAR"/>
<result property="extraInfo" column="extra_info" jdbcType="VARCHAR"/>
<result property="orderItemId" column="order_item_id" jdbcType="VARCHAR"/>
</resultMap>
<!-- 数据表全列名 -->
<sql id="Base_Column_List">
id
,name,description,price,gmt_create,gmt_modify,version,extra_info,order_item_id
</sql>
<!-- 添加product -->
<insert id="insertProduct" useGeneratedKeys="true" keyProperty="id"
parameterType="com.zhuangxiaoyan.springboot.mybatis.domain.Product">
<if test="OrderItemId == 0">
<!-- 抛出异常 保障product 必须有相关关系 -->
THROW EXCEPTION 'order_item_id cannot be 0';
</if>
insert into product (name, description, price, gmt_create, gmt_modify, version, extra_info, order_item_id)
values (#{name}, #{description}, #{price}, now(), now(), 1, #{extraInfo}, #{OrderItemId})
</insert>
<!-- 更新product -->
<update id="updateProduct" parameterType="com.zhuangxiaoyan.springboot.mybatis.domain.Product">
update product
<set>
gmt_modify = now(),
<if test="name != null">
name = #{name},
</if>
<if test="description != null">
description = #{description},
</if>
<if test="orderItemId != null">
order_item_id = #{OrderItemId},
</if>
<if test="price != null">
price = #{price}
</if>
</set>
where id = #{id}
</update>
<!-- 删除product -->
<delete id="removeProduct">
delete
from product
where id = #{id}
</delete>
<!-- 通过id查询product -->
<select id="getProductById" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from product
where id = #{id}
</select>
<!-- 获取所有product -->
<select id="getAllProducts" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from product
</select>
</mapper>
创建Mapper单元测试类
java
package com.zhuangxiaoyan.springboot.mybatis.service;
import com.zhuangxiaoyan.springboot.mybatis.SpringbootMybatisApplication;
import com.zhuangxiaoyan.springboot.mybatis.dao.ProductMapper;
import com.zhuangxiaoyan.springboot.mybatis.domain.Product;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* ProductServiceTest
*
* @author xjl
* @version 2025/01/11 19:15
**/
@SpringBootTest(classes = SpringbootMybatisApplication.class)
public class ProductServiceTest {
@Autowired
private ProductMapper productMapper;
private Product product;
@Test
public void testAddProduct() {
// 初始化 Product 对象
product = new Product();
product.setId(1L);
product.setName("Product A");
product.setDescription("Description of Product A");
product.setPrice(new BigDecimal("99.99"));
product.setVersion("v1.0");
product.setExtraInfo("Extra info for Product A");
product.setOrderItemId(10L);
int addProductId = productMapper.insertProduct(product);
System.out.println("Add product success, product id is " + addProductId);
}
@Test
public void testUpdateProduct() {
product = new Product();
product.setId(1L);
product.setPrice(new BigDecimal("101.99"));
product.setDescription("update test");
product.setOrderItemId(10L);
int result = productMapper.updateProduct(product);
assertEquals(1, result);
System.out.println(result);
}
@Test
public void testRemoveProduct() {
product = new Product();
product.setId(8L);
int result = productMapper.removeProduct(product.getId());
assertEquals(1, result);
System.out.println(result);
}
@Test
public void testGetProductById() {
Product queryProduct = productMapper.getProductById(1L);
assertNotNull(queryProduct);
System.out.println(queryProduct);
}
@Test
public void testGetAllProducts() {
List<Product> allProducts = productMapper.getAllProducts();
allProducts.stream().forEach(System.out::println);
}
}
创建Repository类
java
package com.zhuangxiaoyan.springboot.mybatis.Repository;
import com.zhuangxiaoyan.springboot.mybatis.dao.ProductMapper;
import com.zhuangxiaoyan.springboot.mybatis.domain.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author xjl
* @description ProductDAO类
* @createDate 2025-01-11 18:22:55
* @Entity mybatis.domain.Product
*/
@Repository
public class ProductRepository {
@Autowired
private ProductMapper productMapper;
public int addProduct(Product product) {
return productMapper.insertProduct(product);
}
public int updateProduct(Product product) {
return productMapper.updateProduct(product);
}
public int removeProduct(long id) {
return productMapper.removeProduct(id);
}
public Product getProductById(long id) {
return productMapper.getProductById(id);
}
public List<Product> getAllProducts() {
return productMapper.getAllProducts();
}
}
创建Service层
Service 层通常用来处理业务逻辑,可以通过 @Service
注解标记,并在其中调用 Mapper 接口。
java
package com.zhuangxiaoyan.springboot.mybatis.service;
import com.zhuangxiaoyan.springboot.mybatis.domain.Product;
import java.util.List;
/**
* @author xjl
* @description 针对表【Product(商品表)】的数据库操作Service
* @createDate 2025-01-11 18:22:55
*/
public interface ProductService {
int addProduct(Product product);
int updateProduct(Product product);
int removeProduct(long id);
Product getProductById(long id);
List<Product> getAllProducts();
}
java
package com.zhuangxiaoyan.springboot.mybatis.service.impl;
import com.zhuangxiaoyan.springboot.mybatis.Repository.ProductRepository;
import com.zhuangxiaoyan.springboot.mybatis.domain.Product;
import com.zhuangxiaoyan.springboot.mybatis.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author xjl
* @description ProductServiceImpl实现类
* @createDate 2025-01-11 18:22:55
*/
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductRepository productRepository;
@Override
public int addProduct(Product product) {
return productRepository.addProduct(product);
}
@Override
public int updateProduct(Product product) {
return productRepository.updateProduct(product);
}
@Override
public int removeProduct(long id) {
return productRepository.removeProduct(id);
}
@Override
public Product getProductById(long id) {
return productRepository.getProductById(id);
}
@Override
public List<Product> getAllProducts() {
return productRepository.getAllProducts();
}
}
创建Controller层
Controller 层用来接收请求并返回响应。通过 @RestController
或 @Controller
注解定义。
java
package com.zhuangxiaoyan.springboot.mybatis.controller;
import com.zhuangxiaoyan.springboot.mybatis.domain.Product;
import com.zhuangxiaoyan.springboot.mybatis.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* ProductController
*
* @author xjl
* @version 2025/01/11 19:47
**/
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
// 添加产品
@PostMapping
public int addProduct(@RequestBody Product product) {
return productService.addProduct(product);
}
// 更新产品
@PutMapping("/{id}")
public int updateProduct(@PathVariable long id, @RequestBody Product product) {
product.setId(id);
return productService.updateProduct(product);
}
// 删除产品
@DeleteMapping("/{id}")
public int deleteProduct(@PathVariable long id) {
return productService.removeProduct(id);
}
// 获取产品 by ID
@GetMapping("/{id}")
public Product getProductById(@PathVariable long id) {
return productService.getProductById(id);
}
// 获取所有产品
@GetMapping
public List<Product> getAllProducts() {
return productService.getAllProducts();
}
}
启动应用
java
package com.zhuangxiaoyan.springboot.mybatis;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.zhuangxiaoyan.springboot.mybatis.dao")
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}
12. 参考代码
Hera-Mybatis: 主要介绍的Mybatis的相关的原理和实践方案。 - Gitee.com
博文参考
- 《mybtis开发实战》
- 以上项目代码:gitee.com/xjl24626125...