MyBatis-Flex 是一个轻量级、高效的 MyBatis 增强工具,它在 MyBatis 的基础上增加了一些便捷的功能,帮助开发者更加高效地操作数据库。在这篇博客中,我们将介绍如何安装、配置和使用 MyBatis-Flex。
首先,在你的项目的 pom.xml
文件中添加 MyBatis-Flex 的依赖:
xml<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot3-starter</artifactId>
<version>${mybatisFlexVersion}</version>
</dependency>
在 application.properties
文件中配置数据库连接信息:
propertiesspring.datasource.url=jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8&useSSL=false spring.datasource.username=root spring.datasource.password=your_password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
在 application.properties
文件中添加 MyBatis 配置:
propertiesmybatis.config-location=classpath:mybatis-config.xml mybatis.mapper-locations=classpath:mapper/*.xml
在 Spring Boot 的启动类上添加 @MapperScan
注解,指定 Mapper 接口所在的包:
javaimport org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.project.mapper")
public class MybatisFlexApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisFlexApplication.class, args);
}
}
有些时候,我们会定义实体类的基类,而基类的属性希望自动填充,这时候使用自动填充就能达到想要的效果
javapackage com.yilian.manage.base.entity;
import cn.hutool.core.bean.BeanUtil;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.core.keygen.KeyGenerators;
import com.mybatisflex.core.paginate.Page;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* 实体类基类
*
* @author JACK WEI
* @createDate 2023-02-02 11:59:15
*/
@Data
public abstract class BaseEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 记录编号
*/
@Id(keyType = KeyType.Generator, value = KeyGenerators.snowFlakeId)
private Long id;
/**
* 创建人
*/
@Column
private Long createUser;
/**
* 创建时间
*/
@Column
private LocalDateTime createTime;
/**
* 更新人
*/
@Column
private Long updateUser;
/**
* 更新时间
*/
@Column
private LocalDateTime updateTime;
/**
* 状态:false 停用、true 启用
*/
@Column
private Boolean status;
/**
* 是否删除:false 否、true 是
*/
@Column(isLogicDelete = true)
private Boolean deleted;
/**
* entity转respVO
*
* @param entity 实体类
* @param respClass respVO类class
* @param biConsumer entity和respVO自定义操作
* @param ignoreProperties 忽略字段
* @return 响应体
*/
public static <E, T> T buildOther(E entity, Class<T> respClass, BiConsumer<E, T> biConsumer, String... ignoreProperties) {
T t = BeanUtil.copyProperties(entity, respClass, ignoreProperties);
if (Objects.nonNull(entity)) {
biConsumer.accept(entity, t);
}
return t;
}
/**
* entity集合转respVO集合
*
* @param entityCollection 实体类集合
* @param respClass respVO类class
* @return 集合响应体
*/
public static <E, T> List<T> buildOther(Collection<E> entityCollection, Class<T> respClass) {
return BeanUtil.copyToList(entityCollection, respClass);
}
/**
* entity集合转respVO集合
*
* @param entityCollection 实体类集合
* @param respClass respVO类class
* @param respConsumer respVO自定义操作
* @return 集合响应体
*/
public static <E, T> List<T> buildOther(Collection<E> entityCollection, Class<T> respClass, Consumer<T> respConsumer) {
List<T> rList = BeanUtil.copyToList(entityCollection, respClass);
rList.forEach(respConsumer);
return rList;
}
/**
* entity集合转respVO集合
*
* @param tCollection 实体类集合
* @param rClass respVO类class
* @param biConsumer entity和respVO自定义操作
* @return 集合响应体
*/
public static <E, T> List<T> buildOther(Collection<E> tCollection, Class<T> rClass, BiConsumer<E, T> biConsumer) {
tCollection.forEach(Entity -> biConsumer.accept(Entity, null));
List<T> tList = BeanUtil.copyToList(tCollection, rClass);
tList.forEach(resp -> biConsumer.accept(null, resp));
return tList;
}
/**
* entity分页转respVO分页
*
* @param entityPageResp 实体类分页
* @param respClass respVO类class
* @return 分页响应体
*/
public static <E, T> Page<T> buildOther(Page<E> entityPageResp, Class<T> respClass) {
Page<T> rPageResp = new Page<>();
BeanUtil.copyProperties(entityPageResp, rPageResp);
rPageResp.setRecords(BeanUtil.copyToList(entityPageResp.getRecords(), respClass));
return rPageResp;
}
/**
* entity分页转respVO分页
*
* @param entityPageResp 实体类分页
* @param rClass respVO类class
* @param respConsumer respVO自定义操作
* @return 分页响应体
*/
public static <E, T> Page<T> buildOther(Page<E> entityPageResp, Class<T> rClass, Consumer<T> respConsumer) {
Page<T> rPageResp = new Page<>();
BeanUtil.copyProperties(entityPageResp, rPageResp);
rPageResp.setRecords(BeanUtil.copyToList(entityPageResp.getRecords(), rClass));
rPageResp.getRecords().forEach(respConsumer);
return rPageResp;
}
/**
* entity分页转respVO分页
*
* @param entityPageResp 实体类分页
* @param respClass respVO类class
* @param biConsumer entity和respVO自定义操作
* @return 分页响应体
*/
public static <E, T> Page<T> buildOther(Page<E> entityPageResp, Class<T> respClass, BiConsumer<E, T> biConsumer) {
entityPageResp.getRecords().forEach(entity -> biConsumer.accept(entity, null));
Page<T> rPageResp = new Page<>();
BeanUtil.copyProperties(entityPageResp, rPageResp);
rPageResp.setRecords(BeanUtil.copyToList(entityPageResp.getRecords(), respClass));
rPageResp.getRecords().forEach(resp -> biConsumer.accept(null, resp));
return rPageResp;
}
/**
* entity转respVO
*
* @param rClass 需要转换的类
* @param ignoreProperties 忽略字段
* @return 响应体
*/
public <T> T buildOther(Class<T> rClass, String... ignoreProperties) {
return BeanUtil.copyProperties(this, rClass, ignoreProperties);
}
/**
* entity转respVO
*
* @param respClass respVO类class
* @param respConsumer respVO自定义操作
* @param ignoreProperties 忽略字段
* @return 响应体
*/
public <T> T buildOther(Class<T> respClass, Consumer<T> respConsumer, String... ignoreProperties) {
T t = BeanUtil.copyProperties(this, respClass, ignoreProperties);
respConsumer.accept(t);
return t;
}
}
javapackage com.yilian.manage.config;
import com.mybatisflex.annotation.InsertListener;
import com.mybatisflex.annotation.UpdateListener;
import com.mybatisflex.core.FlexGlobalConfig;
import com.yilian.manage.base.entity.BaseEntity;
import com.yilian.manage.util.UserUtil;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
/**
* 数据持久化时,自动填充的字段
*
* @author JACK WEI
* @createDate 2023-02-02 13:56:24
*/
@Configuration
public class MybatisFlexConfig implements InsertListener, UpdateListener {
public MybatisFlexConfig() {
FlexGlobalConfig defaultConfig = FlexGlobalConfig.getDefaultConfig();
defaultConfig.registerInsertListener(this, BaseEntity.class);
defaultConfig.registerUpdateListener(this, BaseEntity.class);
}
/**
* 被新增时做一些前置操作
*/
@Override
public void onInsert(Object o) {
BaseEntity baseEntity = (BaseEntity) o;
baseEntity.setCreateUser(UserUtil.getCurrentUser().getId());
baseEntity.setCreateTime(LocalDateTime.now());
baseEntity.setUpdateUser(UserUtil.getCurrentUser().getId());
baseEntity.setUpdateTime(LocalDateTime.now());
baseEntity.setStatus(Boolean.TRUE);
baseEntity.setDeleted(Boolean.FALSE);
}
/**
* 被更新时做一些前置操作
*/
@Override
public void onUpdate(Object o) {
BaseEntity baseEntity = (BaseEntity) o;
baseEntity.setUpdateUser(UserUtil.getCurrentUser().getId());
baseEntity.setUpdateTime(LocalDateTime.now());
}
}
在 com.example.project.model
包下创建一个实体类,例如 User
:
javapackage com.example.project.model;
import com.mybatisflex.annotation.Table;
import com.yilian.manage.base.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@Table("user")
@EqualsAndHashCode(callSuper = true)
public class User {
private Long id;
private String name;
private Integer age;
}
在 com.example.project.mapper
包下创建 Mapper 接口,例如 UserMapper
:
javapackage com.example.project.mapper;
import com.example.project.model.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User selectUserById(Long id);
@Select("SELECT * FROM user")
List<User> selectAllUsers();
@Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insertUser(User user);
@Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
void updateUser(User user);
@Delete("DELETE FROM user WHERE id = #{id}")
void deleteUser(Long id);
}
在 src/main/resources/mapper
目录下创建 Mapper XML 文件,例如 UserMapper.xml
:
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.example.project.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.example.project.model.User">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="age" property="age" />
</resultMap>
<sql id="Base_Column_List">
id, name, age
</sql>
<select id="selectUserById" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM user
WHERE id = #{id}
</select>
<select id="selectAllUsers" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM user
</select>
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (name, age)
VALUES (#{name}, #{age})
</insert>
<update id="updateUser">
UPDATE user
SET name = #{name}, age = #{age}
WHERE id = #{id}
</update>
<delete id="deleteUser">
DELETE FROM user
WHERE id = #{id}
</delete>
</mapper>
在 com.example.project.service
包下创建 Service 类,例如 UserService
:
javapackage com.example.project.service;
import com.example.project.mapper.UserMapper;
import com.example.project.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User getUserById(Long id) {
return userMapper.selectUserById(id);
}
public List<User> getAllUsers() {
return userMapper.selectAllUsers();
}
public void createUser(User user) {
userMapper.insertUser(user);
}
public void updateUser(User user) {
userMapper.updateUser(user);
}
public void deleteUser(Long id) {
userMapper.deleteUser(id);
}
}
在 com.example.project.controller
包下创建 Controller 类,例如 UserController
:
javapackage com.example.project.controller;
import com.example.project.model.User;
import com.example.project.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@PostMapping
public void createUser(@RequestBody User user) {
userService.createUser(user);
}
@PutMapping
public void updateUser(@RequestBody User user) {
userService.updateUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}
通过以上步骤,我们成功地在 Spring Boot 项目中集成了 MyBatis-Flex,并实现了基本的增删改查功能。MyBatis-Flex 提供了更高效、更便捷的 MyBatis 操作方式,希望这篇博客能够帮助你更好地理解和使用 MyBatis-Flex。如果你有任何问题或建议,欢迎在评论区留言讨论。