SpringBoot+Mybatis+MybatisPlus整合实现基本的CRUD操作
星空流年 人气:0SpringBoot+Mybatis+MybatisPlus整合实现基本的CRUD操作
1> 数据准备
-- 创建测试表 CREATE TABLE `tb_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `user_name` varchar(20) NOT NULL COMMENT '用户名', `password` varchar(20) NOT NULL COMMENT '密码', `name` varchar(30) DEFAULT NULL COMMENT '姓名', `age` int(11) DEFAULT NULL COMMENT '年龄', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -- 插入测试数据 INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('1', 'zhangsan', '123456', '张三', '18', 'test1@qq.com'); INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('2', 'lisi', '123456', '李四', '20', 'test2@qq.com'); INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('3', 'wangwu', '123456', '王五', '28', 'test3@qq.com'); INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('4', 'zhaoliu', '123456', '赵六', '21', 'test4@qq.com'); INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('5', 'sunqi', '123456', '孙七', '24', 'test5@qq.com');
2> 创建工程,导入依赖
pom.xml文件如下:
<?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.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.darren</groupId> <artifactId>mp</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mp</name> <description>Demo project for Spring Boot<https://img.qb5200.com/download-x/description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> <https://img.qb5200.com/download-x/dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <https://img.qb5200.com/download-x/dependency> <!--简化代码的工具包--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> <https://img.qb5200.com/download-x/dependency> <!--mybatis-plus的springboot支持--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.2.0</version> <https://img.qb5200.com/download-x/dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> <https://img.qb5200.com/download-x/dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <https://img.qb5200.com/download-x/dependency> <https://img.qb5200.com/download-x/dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3> 添加打印Log的配置文件 log4j.properties
log4j.rootLogger=DEBUG,A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n
说明:对于这部分,可以添加,也可以不加,不加会有以下提示信息,建议还是添加
4> 编写 application.yml 配置文件
spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql:///mp?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false username: root password: root
5> 编写 pojo实体类
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @Data @TableName("tb_user") public class User { @TableId(type = IdType.AUTO) //指定id类型为自增长 private Long id; private String userName; private String password; private String name; private Integer age; private String email; }
说明:
@TableId注解 指定数据库id的生成策略,
对于数据库Id的生成策略,MybatisPlus提供有以下策略,当然这部分小伙伴们也可以自行查看源码。
package com.baomidou.mybatisplus.annotation; import lombok.Getter; /** * 生成ID类型枚举类 * * @author hubin * @since 2015-11-10 */ @Getter public enum IdType { /** * 数据库ID自增 */ AUTO(0), /** * 该类型为未设置主键类型(将跟随全局) */ NONE(1), /** * 用户输入ID * <p>该类型可以通过自己注册自动填充插件进行填充</p> */ INPUT(2), /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */ /** * 全局唯一ID (idWorker) */ ID_WORKER(3), /** * 全局唯一ID (UUID) */ UUID(4), /** * 字符串全局唯一ID (idWorker 的字符串表示) */ ID_WORKER_STR(5); private final int key; IdType(int key) { this.key = key; } }
补充:
MybatisPlus实体类中常用的注解,还有一个 @TableField ,此注解主要解决以下两个问题:
1、对象中的属性名和字段名不一致的问题(非驼峰) 2、对象中的属性字段在表中不存在的问题
6> 编写Mapper 映射接口
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.darren.mp.pojo.User; public interface UserMapper extends BaseMapper<User> { }
说明:这里的Mapper接口通过集成 MybatisPlus 提供的 BaseMapper接口来实现对于单表的各种CURD操作,BaseMapper接口中包含的方法有:
/** * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能 * <p>这个 Mapper 支持 id 泛型</p> * * @author hubin * @since 2016-01-23 */ public interface BaseMapper<T> extends Mapper<T> { /** * 插入一条记录 * * @param entity 实体对象 */ int insert(T entity); /** * 根据 ID 删除 * * @param id 主键ID */ int deleteById(Serializable id); /** * 根据 columnMap 条件,删除记录 * * @param columnMap 表字段 map 对象 */ int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); /** * 根据 entity 条件,删除记录 * * @param wrapper 实体对象封装操作类(可以为 null) */ int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); /** * 删除(根据ID 批量删除) * * @param idList 主键ID列表(不能为 null 以及 empty) */ int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); /** * 根据 ID 修改 * * @param entity 实体对象 */ int updateById(@Param(Constants.ENTITY) T entity); /** * 根据 whereEntity 条件,更新记录 * * @param entity 实体对象 (set 条件值,可以为 null) * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) */ int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); /** * 根据 ID 查询 * * @param id 主键ID */ T selectById(Serializable id); /** * 查询(根据ID 批量查询) * * @param idList 主键ID列表(不能为 null 以及 empty) */ List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); /** * 查询(根据 columnMap 条件) * * @param columnMap 表字段 map 对象 */ List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); /** * 根据 entity 条件,查询一条记录 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询总记录数 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 entity 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询全部记录 * <p>注意: 只返回第一个字段的值</p> * * @param queryWrapper 实体对象封装操作类(可以为 null) */ List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 entity 条件,查询全部记录(并翻页) * * @param page 分页查询条件(可以为 RowBounds.DEFAULT) * @param queryWrapper 实体对象封装操作类(可以为 null) */ IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询全部记录(并翻页) * * @param page 分页查询条件 * @param queryWrapper 实体对象封装操作类 */ IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); }
7、编写测试用例
7.1 插入操作
import com.darren.mp.mapper.UserMapper; import com.darren.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @SpringBootTest @RunWith(SpringRunner.class) public class UserMapperTest { @Autowired private UserMapper userMapper; /** * 插入操作: * * 插入一条记录 * entity 实体对象 * int insert(T entity); */ @Test public void testInsert(){ User user = new User(); user.setAge(20); user.setEmail("test8@itcast.cn"); user.setName("lily"); user.setUserName("lily"); user.setPassword("123456"); int result = this.userMapper.insert(user); //返回的result是受影响的行数,并不是自增后的id,下同 System.out.println("result: " + result); System.out.println(user.getId()); //自增后的id会回填到对象中 } }
测试结果:
7.2 更新操作
在MybatisPlus中,更新操作有2种,一种是根据id更新,另一种是根据条件更新。
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.darren.mp.mapper.UserMapper; import com.darren.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @SpringBootTest @RunWith(SpringRunner.class) public class UserMapperTest { @Autowired private UserMapper userMapper; /** * 更新操作 * 1、根据 ID 修改 * * entity 实体对象 * int updateById(@Param(Constants.ENTITY) T entity) */ @Test public void testUpdateById(){ User user = new User(); user.setId(6L); user.setAge(30); int result = userMapper.updateById(user); System.out.println("result: "+result); } /** * 更新操作 * 2、根据 whereEntity 条件,更新记录 * * entity 实体对象 (set 条件值,可以为 null) * updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) * int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); */ @Test public void testUpdate(){ User user = new User(); user.setEmail("zhangsan@qq.com");//更新的字段 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("name","张三");//更新的条件 //执行更新操作 int result = userMapper.update(user, queryWrapper); System.out.println("result: "+result); } }
测试结果:
1、根据Id更新
2、根据条件更新
7.3 删除操作
MybatisPlus提供的删除操作有:根据Id删除、根据Map集合删除、根据条件删除、根据Id集合批量删除
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.darren.mp.mapper.UserMapper; import com.darren.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.HashMap; import java.util.List; @SpringBootTest @RunWith(SpringRunner.class) public class UserMapperTest { @Autowired private UserMapper userMapper; /** * 删除操作 * 1、根据 ID 删除 * * id为主键ID * int deleteById(Serializable id); */ @Test public void testDeleteById(){ int result = userMapper.deleteById(6L); System.out.println("result : "+result); } /** * 删除操作 * 2、根据 columnMap 条件,删除记录 * * columnMap 表字段 map 对象 * int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); */ @Test public void testDeleteByMap(){ HashMap<String, Object> columnMap = new HashMap<>(); columnMap.put("age",21); columnMap.put("name", "张三"); //将columnMap中的元素设置为删除的条件,多个条件之间为 AND 关系 int result = userMapper.deleteByMap(columnMap); System.out.println("result : "+result); } /** * 删除操作 * 3、根据 entity 条件,删除记录 * * wrapper 实体对象封装操作类(可以为 null) * int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); */ @Test public void testDelete(){ //用法一: //QueryWrapper<User> wrapper = new QueryWrapper<>(); //wrapper.eq("user_name", "lisi") //.eq("password", "123456"); //用法二: User user = new User(); user.setUserName("lisi"); user.setPassword("123456"); QueryWrapper<User> wrapper = new QueryWrapper<>(user); // 将实体对象包装为操作条件,根据包装条件执行删除,多个条件之间为 AND 关系 int result = userMapper.delete(wrapper); System.out.println("result: " + result); } /** * 删除操作 * 4、删除(根据ID 批量删除) * * idList 主键ID列表(不能为 null 以及 empty) * int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); */ @Test public void testDeleteBatchIds(){ // 根据id集合批量删除数据 int result = userMapper.deleteBatchIds(Arrays.asList(3L, 4L)); System.out.println("result:" + result); } }
测试结果:
1、根据Id删除
2、根据Map集合删除
3、根据条件删除
4、根据Id集合批量删除
7.4 查询操作
MybatisPlus提供了多种查询操作,包括根据id查询、批量查询、查询单条数据、查询列表、分页查询等操作,这里只列出了常用的操作。
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.darren.mp.mapper.UserMapper; import com.darren.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.List; @SpringBootTest @RunWith(SpringRunner.class) public class UserMapperTest { @Autowired private UserMapper userMapper; /** * 查询操作 * 1、根据 ID 查询 * * id 主键ID * T selectById(Serializable id); */ @Test public void testSelectById(){ User user = userMapper.selectById(5L); System.out.println(user); } /** * 查询操作 * 2、根据 ID集合 批量查询 * * idList 主键ID列表(不能为 null 以及 empty) * List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); */ @Test public void testSelectBatchIds(){ // 根据id集合批量查询数据 List<User> users = userMapper.selectBatchIds(Arrays.asList(5L, 6L, 7L, 100L)); for (User user : users) { System.out.println(user); } } /** * 查询操作 * 3、根据 entity 条件,查询一条记录 * * queryWrapper 实体对象封装操作类(可以为 null) * T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); */ @Test public void testSelectOne(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("user_name","lily"); User user = userMapper.selectOne(wrapper); System.out.println(user); // //查询条件 // wrapper.eq("password", "123456"); // // 查询的数据超过一条时,会抛出异常 // User user = userMapper.selectOne(wrapper); // System.out.println(user); } /** * 查询操作 * 4、根据 Wrapper 条件,查询总记录数 * * queryWrapper 实体对象封装操作类(可以为 null) * Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); */ @Test public void testSelectCount(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.gt("age", 20); // 条件:年龄大于20岁的用户 // 根据条件查询数据条数 Integer count = userMapper.selectCount(wrapper); System.out.println("count => " + count); } /** * 查询操作 * 5、根据 entity 条件,查询全部记录 * * queryWrapper 实体对象封装操作类(可以为 null) * List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); */ @Test public void testSelect(){ // List<User> userList = userMapper.selectList(null); // for (User user : userList) { // System.out.println(user); // } QueryWrapper<User> queryWrapper = new QueryWrapper<>(); //设置查询条件 queryWrapper.like("email", "qq.com"); List<User> users = this.userMapper.selectList(queryWrapper); for (User user : users) { System.out.println(user); } } }
说明:
分页查询操作,需要配置MybatisPlus的分页插件
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @MapperScan("com.darren.mp.mapper") //设置mapper接口的扫描包 public class MybatisPlusConfig { @Bean //配置分页插件 public PaginationInterceptor paginationInterceptor(){ return new PaginationInterceptor(); } }
编写 分页查询测试用例
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.darren.mp.mapper.UserMapper; import com.darren.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @SpringBootTest @RunWith(SpringRunner.class) public class UserMapperTest { @Autowired private UserMapper userMapper; /** * 查询操作 * 6、根据 entity 条件,查询全部记录(并翻页) * * page 分页查询条件(可以为 RowBounds.DEFAULT) * queryWrapper 实体对象封装操作类(可以为 null) * IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); */ @Test public void testSelectPage() { Page<User> page = new Page<>(1, 2); //current为当前页,size为每页显示条数 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); //设置查询条件 queryWrapper.like("email", "qq.com"); IPage<User> iPage = userMapper.selectPage(page, queryWrapper); System.out.println("数据总条数: " + iPage.getTotal()); System.out.println("每页显示条数:"+iPage.getSize()); System.out.println("数据总页数: " + iPage.getPages()); System.out.println("当前页数: " + iPage.getCurrent()); List<User> records = iPage.getRecords(); for (User record : records) { System.out.println(record); } } }
测试结果
加载全部内容