Springboot系列之:创建Springboot项目,Springboot整合MyBatis-plus
- 一、快速创建Spring boot项目
- 二、项目完整目录
- 三、pom.xml
- 四、application.yaml
- 五、实体类
- 六、mapper
- 七、IService接口
- 八、Service实现类
- 九、配置类
- 十、枚举
- 十一、增删改查测试类
- 十二、服务测试类
- 十三、分页测试类
- 十四、枚举测试类
- 十五、乐观锁测试类
一、快速创建Spring boot项目
二、项目完整目录
三、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.7.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.lovejava.boot</groupId><artifactId>learnjava</artifactId><version>0.0.1-SNAPSHOT</version><name>learnjava</name><properties><java.version>8</java.version><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.13</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>8</source><target>8</target></configuration></plugin></plugins></build></project>
四、application.yaml
spring:application:name: learnjavadatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://10.129.88.141:3306/data_entry_test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: datasightpassword: datasight123456!Amybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# log-impl: org.apache.ibatis.logging.log4j.Log4jImpl
# global-config:
# db-config:
# table-prefix: t_
# id-type: AUTOtype-enums-package: com.lovejava.boot.enums
五、实体类
import com.baomidou.mybatisplus.annotation.*;
import com.lovejava.boot.enums.SexEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@TableName("user")
public class User {@TableId(value = "id",type=IdType.AUTO)private Long id;// @TableField("sname")private String name;private Integer age;private SexEnum sex;private String email;@TableField("isDeleted")@TableLogicprivate Integer isDeleted;@Versionprivate Integer version;}
六、mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lovejava.boot.pojo.User;
import org.springframework.stereotype.Repository;@Repository
public interface UserMapper extends BaseMapper<User> {
}
七、IService接口
IService 是 MyBatis-Plus 提供的一个通用 Service 层接口,它封装了常见的 CRUD 操作,包括插入、删除、查询和分页等。通过继承 IService 接口,可以快速实现对数据库的基本操作,同时保持代码的简洁性和可维护性。
IService 接口中的方法命名遵循了一定的规范,如 get 用于查询单行,remove 用于删除,list 用于查询集合,page 用于分页查询,这样可以避免与 Mapper 层的方法混淆。
import com.baomidou.mybatisplus.extension.service.IService;
import com.lovejava.boot.pojo.User;public interface UserService extends IService<User> {
}
八、Service实现类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lovejava.boot.mapper.UserMapper;
import com.lovejava.boot.pojo.User;
import com.lovejava.boot.service.UserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
九、配置类
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@MapperScan("com.lovejava.boot.mapper")
public class MybatisPlusConfig {/*** 添加分页插件*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();//添加乐观锁插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());// 如果配置多个插件, 切记分页最后添加interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbTypereturn interceptor;}
}
十、枚举
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;@Getter
@AllArgsConstructor
public enum SexEnum {MALE(1,"男"),FEMALE(2,"女");@EnumValue //将注解所标识的属性的值存储到数据库中private Integer sex;private String sexName;}
十一、增删改查测试类
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.lovejava.boot.mapper.UserMapper;
import com.lovejava.boot.pojo.User;
import net.minidev.json.JSONUtil;
import org.junit.jupiter.api.Test;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@SpringBootTest
public class MyBatisPlusTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectList(){List<User> users = userMapper.selectList(null);System.out.println(users);users.forEach(System.out::println);}@Testpublic void testInsert(){User user = new User();user.setName("刘备");user.setAge(23);user.setEmail("fy@qq.com");int result = userMapper.insert(user);System.out.println("result:"+result);System.out.println("id:"+user.getId());}@Testpublic void testDelete(){int result = userMapper.deleteById(1860576442045870081L);System.out.println(result);}//DELETE FROM user WHERE name = ? AND age = ?@Testpublic void testDeleteByMap(){Map<String,Object> map = new HashMap<>();map.put("name","刘备");map.put("age",23);int result = userMapper.deleteByMap(map);System.out.println("result:"+result);}//通过多个id实现批量删除@Testpublic void testDeleteBatchIds(){List<Integer> list = Arrays.asList(1, 2, 3);int result = userMapper.deleteBatchIds(list);System.out.println("result:"+result);}@Testpublic void testUpdate(){User user = new User();user.setId(1860579637015023618l);user.setName("刘备");user.setEmail("lb@qq.com");int result = userMapper.updateById(user);System.out.println("result: " + result);}@Testpublic void testSelectById(){List<Long> list = Arrays.asList(1l, 2l, 3l);List<User> users = userMapper.selectBatchIds(list);users.forEach(System.out::println);}@Testpublic void testSelectByMap(){HashMap<String, Object> map = new HashMap<>();map.put("name","诸葛亮");map.put("age",20);List<User> users = userMapper.selectByMap(map);users.forEach(System.out::println);}@Testpublic void testConditionSelect(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.likeRight("name","刘备").between("age",10,50).isNotNull("email");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}@Testpublic void testConditionOrder(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.orderByDesc("age").orderByAsc("id");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}@Testpublic void deleteCondition(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.isNull("email");int result = userMapper.delete(queryWrapper);System.out.println("result:" + result);}@Testpublic void updateCondition(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age",20).like("name","刘备").or().isNull("email");User user = new User();user.setName("诸葛亮");user.setEmail("zhugeliang@qq.com");int result = userMapper.update(user, queryWrapper);System.out.println("result: "+result);}//UPDATE user SET name=?, email=? WHERE isDeleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL))@Testpublic void updateCondition2(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("name","诸葛亮").and(i -> i.gt("age",20).or().isNull("email"));User user = new User();user.setName("张飞");user.setEmail("zhangfei@qq.com");int result = userMapper.update(user, queryWrapper);System.out.println("result:"+result);}//UPDATE user SET name=?,email=? WHERE isDeleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL))@Testpublic void updateCondition3(){UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.like("name","诸葛亮").and(i -> i.gt("age",20).or().isNull("email"));updateWrapper.set("name","孙权").set("email","sunquan@qq.com");int result = userMapper.update(null,updateWrapper);System.out.println("result:" + result);}@Testpublic void selectCondition(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("name","age","email");List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);maps.forEach(System.out::println);}//子查询//SELECT id,name,age,email,isDeleted FROM user WHERE isDeleted=0 AND (id IN (select id from user where id < 10))@Testpublic void selectCondition2(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.inSql("id","select id from user where id < 10");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}//模拟实际条件//SELECT id,name,age,email,isDeleted FROM user WHERE isDeleted=0 AND (age >= ? AND age <= ?)@Testpublic void getCondition(){String username = "";Integer startage = 20;Integer endage = 35;QueryWrapper<User> queryWrapper = new QueryWrapper<>();if(StringUtils.isNotBlank(username)){queryWrapper.like("name",username);}if(startage!=null){queryWrapper.ge("age",startage);}if(endage!=null){queryWrapper.le("age",endage);}List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}//SELECT id,name,age,email,isDeleted FROM user WHERE isDeleted=0 AND (age >= ? AND age <= ?)@Testpublic void getCondition2(){String username = "";Integer startage = 20;Integer endage = 35;QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like(StringUtils.isNotBlank(username),"name","孙权").ge(startage!=null,"age",startage).le(endage!=null,"age",endage);List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}@Testpublic void testSelectLambda(){String username = "";Integer startage = 20;Integer endage = 35;LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.like(StringUtils.isNotBlank(username),User::getName,username).ge(startage!=null,User::getAge,startage).le(endage!=null,User::getAge,endage);List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}//UPDATE user SET name=?,age=?,email=? WHERE isDeleted=0 AND (age >= ? AND age <= ?)@Testpublic void testUpdateLambda(){String username = "";Integer startage = 20;Integer endage = 35;LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();updateWrapper.like(StringUtils.isNotBlank(username),User::getName,username).ge(startage!=null,User::getAge,startage).le(endage!=null,User::getAge,endage);updateWrapper.set(User::getName,"诸葛亮回来了").set(User::getAge,16).set(User::getEmail,"诸葛亮@qq" +".com");int result = userMapper.update(null, updateWrapper);System.out.println("result: "+result);}@Testpublic void testOptimisticLocker2(){// 线程1//1.查询用户信息User user1 = userMapper.selectById(2);//2.修改用户信息user1.setName("马超1");user1.setAge(20);user1.setEmail("machao1@qq.com");//模拟另外一个线程执行了插队操作User user2 = userMapper.selectById(2);//2.修改用户信息user2.setName("马超2");user2.setAge(20);user2.setEmail("machao2@qq.com");userMapper.updateById(user2);//如果没有乐观锁就会覆盖插队线程的值//可以使用自旋锁来多次尝试提交userMapper.updateById(user1);}
}
十二、服务测试类
import java.util.ArrayList;
import java.util.List;@SpringBootTest
public class MyBatisPlusServiceTest {@Autowiredprivate UserService userService;@Testpublic void testGetCount(){int count = userService.count();System.out.println("总记录数: "+count);}@Testpublic void testInsertBatch(){List<User> list = new ArrayList<>();for (int i = 1; i<= 10; i++){User user = new User();user.setName("fy"+i);user.setAge(20+i);user.setEmail("fy"+i+"qq.com");list.add(user);}boolean b = userService.saveBatch(list);System.out.println("操作结果:"+b);}}
十三、分页测试类
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lovejava.boot.mapper.UserMapper;
import com.lovejava.boot.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class MybatisPlusPluginsTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectPage(){Page<User> page = new Page<>(1,1);userMapper.selectPage(page,null);page.getRecords().forEach(System.out::println);System.out.println(page.getTotal());}//SELECT COUNT(*) FROM user WHERE isDeleted = 0 AND (name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)@Testpublic void testSelectConditionPage(){Page<User> page = new Page<>(1,1);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.likeRight("name","刘备").between("age",10,50).isNotNull("email");userMapper.selectPage(page,queryWrapper);System.out.println(page);System.out.println(page.getTotal());System.out.println(page.getRecords());System.out.println(page.getPages());System.out.println(page.hasNext());System.out.println(page.hasPrevious());}
}
十四、枚举测试类
import com.lovejava.boot.enums.SexEnum;
import com.lovejava.boot.mapper.UserMapper;
import com.lovejava.boot.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class MyBatisPlusEnumTest {@Autowiredprivate UserMapper userMapper;@Testpublic void test(){User user = new User();user.setName("admin");user.setAge(23);user.setSex(SexEnum.MALE);user.setEmail("admin@qq.com");int result = userMapper.insert(user);System.out.println("result:" + result);}
}
十五、乐观锁测试类
实体类添加字段:
@Versionprivate Integer version;
添加乐观锁插件
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@MapperScan("com.lovejava.boot.mapper")
public class MybatisPlusConfig {/*** 添加分页插件*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();//添加乐观锁插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());// 如果配置多个插件, 切记分页最后添加interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbTypereturn interceptor;}
}
乐观锁实现
@Testpublic void testOptimisticLocker2(){// 线程1//1.查询用户信息User user1 = userMapper.selectById(2);//2.修改用户信息user1.setName("马超1");user1.setAge(20);user1.setEmail("machao1@qq.com");//模拟另外一个线程执行了插队操作User user2 = userMapper.selectById(2);//2.修改用户信息user2.setName("马超2");user2.setAge(20);user2.setEmail("machao2@qq.com");userMapper.updateById(user2);//如果没有乐观锁就会覆盖插队线程的值//可以使用自旋锁来多次尝试提交userMapper.updateById(user1);}