mybatis-plus的入门学习

it2023-02-10  56

环境

IDEAspringbootmavenmysql5.7

开始

1.首先需要准备一张表user

CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) ); INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@baomidou.com'), (2, 'Jack', 20, 'test2@baomidou.com'), (3, 'Tom', 28, 'test3@baomidou.com'), (4, 'Sandy', 21, 'test4@baomidou.com'), (5, 'Billie', 24, 'test5@baomidou.com');

2.创建一个springboot初始化工程 根据需要选择 完整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.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.king</groupId> <artifactId>mybatis_plus</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mybatis_plus</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.1.tmp</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </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>

3.在application.yml中配置mysql数据源

spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC

4.编写表对应的实体类User

@Data @NoArgsConstructor @AllArgsConstructor public class User { private Long Id; private String name; private Integer age; private String email; }

5.编写操作实体类的 Mapper 类,直接继承 BaseMapper,这是 mybatis-plus 封装好的类。 6.先得在启动类里扫描 Mapper 类,即添加 @MapperScan 注解

@SpringBootApplication //mapper类所在的目录路径 @MapperScan("com.king.mybatis_plus.mapper") public class MybatisPlusApplication { public static void main(String[] args) { SpringApplication.run(MybatisPlusApplication.class, args); } }

7.编写测试类

@SpringBootTest class MybatisPlusApplicationTests { @Autowired(required = false) private UserMapper userMapper; /** * 查询 */ @Test public void testSelect(){ /*查询所有的数据UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper, 所以不填写就是无任何条件*/ List<User> list=userMapper.selectList(null); for (User user:list){ System.out.println(user); } //根据主键查询 System.out.println("记录:"); System.out.println(userMapper.selectById(1)); } /** * 添加 */ @Test public void testInsert(){ //主键会自动生成 User user=new User(); user.setName("king"); user.setAge(20); user.setEmail("123456@qq.com"); System.out.println("插入结果:"+userMapper.insert(user)); } /** * 删除 */ @Test public void testDelete(){ System.out.println("删除结果:"+userMapper.deleteById(1)); } /** * 修改 */ @Test public void testUpdate(){ User user=new User(); user.setId(2L); user.setName("ting"); user.setAge(30); user.setEmail("2345@qq.com"); System.out.println("修改结果:"+userMapper.updateById(user)); } }

好的,到这里简单的CRUD就好了


注解

下面来看一下mybatis-plus的一些注解吧 @TableName 描述:表名注解

属性类型必须指定默认值描述valueString否“”表名schemaString否“”schemakeepGlobalPrefixboolean否false是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)resultMapString否“”xml 中 resultMap 的 idautoResultMapboolean否false是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)

关于autoResultMap的说明:

mp会自动构建一个ResultMap并注入到mybatis里(一般用不上).下面讲两句: 因为mp底层是mybatis,所以一些mybatis的常识你要知道,mp只是帮你注入了常用crud到mybatis里 注入之前可以说是动态的(根据你entity的字段以及注解变化而变化),但是注入之后是静态的(等于你写在xml的东西) 而对于直接指定typeHandler,mybatis只支持你写在2个地方:

定义在resultMap里,只作用于select查询的返回结果封装定义在insert和updatesql的#{property}里的property后面(例:#{property,typehandler=xxx.xxx.xxx}),只作用于设置值 而除了这两种直接指定typeHandler,mybatis有一个全局的扫描你自己的typeHandler包的配置,这是根据你的property的类型去找typeHandler并使用.

@TableId

描述:主键注解 属性类型必须指定默认值描述valueString否“”主键字段名typeEnum否IdType.NONE主键类型

#IdType

值描述AUTO数据库ID自增NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)INPUTinsert前自行set主键值ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)ID_WORKER分布式全局唯一ID 长整型类型(please use ASSIGN_ID)UUID32位UUID字符串(please use ASSIGN_UUID)ID_WORKER_STR分布式全局唯一ID 字符串类型(please use ASSIGN_ID)

#@TableField

描述:字段注解(非主键) 属性类型必须指定默认值描述valueString否“”数据库字段名elString否“”映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分existboolean否true是否为数据库表字段conditionString否“”字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考updateString否“”字段 update set 部分注入, 例如:update="%s+1":表示更新时会set version=version+1(该属性优先级高于 el 属性)insertStrategyEnumNDEFAULT举例:NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)updateStrategyEnumNDEFAULT举例:IGNORED: update table_a set column=#{columnProperty}whereStrategyEnumNDEFAULT举例:NOT_EMPTY: where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>fillEnum否FieldFill.DEFAULT字段自动填充策略selectboolean否true是否进行 select 查询keepGlobalFormatboolean否false是否保持使用全局的 format 进行处理jdbcTypeJdbcType否JdbcType.UNDEFINEDJDBC类型 (该默认值不代表会按照该值生效)typeHandlerClass<? extends TypeHandler>否UnknownTypeHandler.class类型处理器 (该默认值不代表会按照该值生效)numericScaleString否“”指定小数点后保留的位数

关于jdbcType和typeHandler以及numericScale的说明:

numericScale只生效于 update 的sql. jdbcType和typeHandler如果不配合@TableName#autoResultMap = true一起使用,也只生效于 update 的sql. 对于typeHandler如果你的字段类型和set进去的类型为equals关系,则只需要让你的typeHandler让Mybatis加载到即可,不需要使用注解

FieldStrategy

值描述IGNORED忽略判断NOT_NULL非NULL判断NOT_EMPTY非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)DEFAULT追随全局配置

FieldFill

值描述DEFAULT默认不处理INSERT插入时填充字段UPDATE更新时填充字段INSERT_UPDATE插入和更新时填充字段

更多注解可以看官方文档:https://baomidou.com/guide/annotation.html

代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。与 mybatis 中的 mybatis-generator-core 类似。

1、创建一个新的springboot工程: 目录结构:

2、完整的pom依赖: 【大家可以使用我的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.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.king</groupId> <artifactId>mybatis_plus_generator</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mybatis_plus_generator</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.1.tmp</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <!-- mybatisPlus 核心库 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.0</version> </dependency> <!-- mybatis plus 代码生成器 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.0.6</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.20</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </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>

3、运行配置文件

配置文件(大家根据自己的工程进行修改相应的东西):

/** * 代码生成器类 * * @author king * @version 1.0 * @date 2020/10/29 15:53 */ public class CodeGenerator { /** * <p> * 读取控制台内容 * </p> */ public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("请输入" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotEmpty(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); final String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("king"); gc.setBaseResultMap(true); gc.setBaseColumnList(true); // 是否打开输出目录 默认为true gc.setOpen(false); mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC"); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); mpg.setDataSource(dsc); // 包配置 final PackageConfig pc = new PackageConfig(); // pc.setModuleName(scanner("模块名")); pc.setParent("com.king"); mpg.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker String templatePath = "/templates/mapper.xml.ftl"; // 如果模板引擎是 velocity // String templatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List<FileOutConfig> focList = new ArrayList<FileOutConfig>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 配置自定义输出模板 // 指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别 // templateConfig.setEntity("templates/entity2.java"); // templateConfig.setService(); // templateConfig.setController(); templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); // strategy.setSuperEntityClass("com.fame.common.BaseEntity"); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); // strategy.setSuperControllerClass("com.fame.common.BaseController"); strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); //strategy.setSuperEntityColumns("id"); // strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix("sys"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); } }

4、自动生成了这些实体类,业务类,控制层类,xml文件等等 5、在启动类上需要加@MapperScanner,用来扫描mapper类

@SpringBootApplication @MapperScan("com.king.mapper") public class MybatisPlusGeneratorApplication { public static void main(String[] args) { SpringApplication.run(MybatisPlusGeneratorApplication.class, args); } }

6、yml文件配置

server: port: 8089 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC username: root password: 123456 # mybatis-plus相关配置 mybatis-plus: # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置) mapper-locations: classpath:mapper/*.xml # 以下配置均有默认值,可以不设置 global-config: db-config: #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; id-type: ID_WORKER #字段策略 IGNORED:"忽略判断" NOT_NULL:"非 NULL 判断") NOT_EMPTY:"非空判断" field-strategy: IGNORED #数据库类型 db-type: MYSQL # 指定实体类的包 type-aliases-package: com.king.entity configuration: # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射 map-underscore-to-camel-case: true # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段 call-setters-on-nulls: true # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

7、写测试类

@Autowired private IUserService iUserService; @Autowired(required = false) private UserMapper userMapper; /** * 查询 */ @Test public void testSelect(){ //查询所有 System.out.println(userMapper.selectList(null)); System.out.println(iUserService.list()); //查询单个 System.out.println(userMapper.selectById(2)); System.out.println(iUserService.getById(2)); } /** * 添加数据 */ @Test public void insert(){ User user=new User(); user.setAge(20); user.setName("ting"); user.setEmail("234242@qq.com"); User user2=new User(); user2.setAge(22); user2.setName("ting2"); user2.setEmail("234242@qq.com"); //单条添加 //System.out.println("添加结果:"+userMapper.insert(user)); //System.out.println("添加结果:"+iUserService.save(user2)); //批量添加 List<User> list=new ArrayList<>(); list.add(user); list.add(user2); System.out.println("批量添加结果:"+iUserService.saveBatch(list)); } /** * 删除 */ @Test public void delete(){ //通过id删除 System.out.println("删除结果:"+userMapper.deleteById(2)); System.out.println("删除结果:"+iUserService.removeById(3)); //批量删除 List<Integer> list1=new ArrayList<>(); List<Long> list2=new ArrayList<>(); list1.add(1); list1.add(5); list2.add(1321747562349043714L); list2.add(1321747562349043715L); System.out.println("批量删除1:"+userMapper.deleteBatchIds(list1)); boolean flag=iUserService.removeByIds(list2); System.out.println("批量删除2:"+flag); } /** * 修改 */ @Test public void update(){ User user1=new User(1321972874844389378L,"aa",10,"2929292@qq.com"); User user2=new User(1321973036350185473L,"bb",20,"34242342@qq.com"); List<User> list=new ArrayList<>(); list.add(user1); list.add(user2); //单条修改 System.out.println("修改结果2:"+userMapper.updateById(user1)); System.out.println("修改结果2:"+iUserService.updateById(user2)); //批量修改 System.out.println("修改结果3:"+iUserService.updateBatchById(list)); }

用代码生成器生成的实体类、业务类、控制层就测试完了

源码

既然他这么方便,那么我们需要知道他是怎么实现的,来看看源码吧

1)mapper 他继承了BaseMapper

public interface UserMapper extends BaseMapper<User> { }

BaseMapper: 可以发现他实现了很多功能

public interface BaseMapper<T> { int insert(T var1); int deleteById(Serializable var1); int deleteByMap(@Param("cm") Map<String, Object> var1); int delete(@Param("ew") Wrapper<T> var1); int deleteBatchIds(@Param("coll") Collection<? extends Serializable> var1); int updateById(@Param("et") T var1); int update(@Param("et") T var1, @Param("ew") Wrapper<T> var2); T selectById(Serializable var1); List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1); List<T> selectByMap(@Param("cm") Map<String, Object> var1); T selectOne(@Param("ew") Wrapper<T> var1); Integer selectCount(@Param("ew") Wrapper<T> var1); List<T> selectList(@Param("ew") Wrapper<T> var1); List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1); List<Object> selectObjs(@Param("ew") Wrapper<T> var1); IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2); IPage<Map<String, Object>> selectMapsPage(IPage<T> var1, @Param("ew") Wrapper<T> var2); }

业务类:

@Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService { }

ServiceImpl源码: 他实现的功能更加多

public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> { @Autowired protected M baseMapper; public ServiceImpl() { } protected boolean retBool(Integer result) { return SqlHelper.retBool(result); } protected Class<T> currentModelClass() { return ReflectionKit.getSuperClassGenericType(this.getClass(), 1); } protected SqlSession sqlSessionBatch() { return SqlHelper.sqlSessionBatch(this.currentModelClass()); } protected void closeSqlSession(SqlSession sqlSession) { SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(this.currentModelClass())); } protected String sqlStatement(SqlMethod sqlMethod) { return SqlHelper.table(this.currentModelClass()).getSqlStatement(sqlMethod.getMethod()); } @Transactional( rollbackFor = {Exception.class} ) public boolean save(T entity) { return this.retBool(this.baseMapper.insert(entity)); } @Transactional( rollbackFor = {Exception.class} ) public boolean saveBatch(Collection<T> entityList, int batchSize) { int i = 0; String sqlStatement = this.sqlStatement(SqlMethod.INSERT_ONE); SqlSession batchSqlSession = this.sqlSessionBatch(); Throwable var6 = null; try { for(Iterator var7 = entityList.iterator(); var7.hasNext(); ++i) { T anEntityList = var7.next(); batchSqlSession.insert(sqlStatement, anEntityList); if (i >= 1 && i % batchSize == 0) { batchSqlSession.flushStatements(); } } batchSqlSession.flushStatements(); return true; } catch (Throwable var16) { var6 = var16; throw var16; } finally { if (batchSqlSession != null) { if (var6 != null) { try { batchSqlSession.close(); } catch (Throwable var15) { var6.addSuppressed(var15); } } else { batchSqlSession.close(); } } } } @Transactional( rollbackFor = {Exception.class} ) public boolean saveOrUpdate(T entity) { if (null == entity) { return false; } else { Class<?> cls = entity.getClass(); TableInfo tableInfo = TableInfoHelper.getTableInfo(cls); if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) { Object idVal = ReflectionKit.getMethodValue(cls, entity, tableInfo.getKeyProperty()); return !StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable)idVal)) ? this.updateById(entity) : this.save(entity); } else { throw ExceptionUtils.mpe("Error: Can not execute. Could not find @TableId.", new Object[0]); } } } @Transactional( rollbackFor = {Exception.class} ) public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) { if (CollectionUtils.isEmpty(entityList)) { throw new IllegalArgumentException("Error: entityList must not be empty"); } else { Class<?> cls = this.currentModelClass(); TableInfo tableInfo = TableInfoHelper.getTableInfo(cls); int i = 0; SqlSession batchSqlSession = this.sqlSessionBatch(); Throwable var7 = null; try { Iterator var8 = entityList.iterator(); while(var8.hasNext()) { T anEntityList = var8.next(); if (null == tableInfo || !StringUtils.isNotEmpty(tableInfo.getKeyProperty())) { throw ExceptionUtils.mpe("Error: Can not execute. Could not find @TableId.", new Object[0]); } Object idVal = ReflectionKit.getMethodValue(cls, anEntityList, tableInfo.getKeyProperty()); if (!StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable)idVal))) { ParamMap<T> param = new ParamMap(); param.put("et", anEntityList); batchSqlSession.update(this.sqlStatement(SqlMethod.UPDATE_BY_ID), param); } else { batchSqlSession.insert(this.sqlStatement(SqlMethod.INSERT_ONE), anEntityList); } if (i >= 1 && i % batchSize == 0) { batchSqlSession.flushStatements(); } ++i; batchSqlSession.flushStatements(); } } catch (Throwable var19) { var7 = var19; throw var19; } finally { if (batchSqlSession != null) { if (var7 != null) { try { batchSqlSession.close(); } catch (Throwable var18) { var7.addSuppressed(var18); } } else { batchSqlSession.close(); } } } return true; } } @Transactional( rollbackFor = {Exception.class} ) public boolean removeById(Serializable id) { return SqlHelper.delBool(this.baseMapper.deleteById(id)); } @Transactional( rollbackFor = {Exception.class} ) public boolean removeByMap(Map<String, Object> columnMap) { if (ObjectUtils.isEmpty(columnMap)) { throw ExceptionUtils.mpe("removeByMap columnMap is empty.", new Object[0]); } else { return SqlHelper.delBool(this.baseMapper.deleteByMap(columnMap)); } } @Transactional( rollbackFor = {Exception.class} ) public boolean remove(Wrapper<T> wrapper) { return SqlHelper.delBool(this.baseMapper.delete(wrapper)); } @Transactional( rollbackFor = {Exception.class} ) public boolean removeByIds(Collection<? extends Serializable> idList) { return SqlHelper.delBool(this.baseMapper.deleteBatchIds(idList)); } @Transactional( rollbackFor = {Exception.class} ) public boolean updateById(T entity) { return this.retBool(this.baseMapper.updateById(entity)); } @Transactional( rollbackFor = {Exception.class} ) public boolean update(T entity, Wrapper<T> updateWrapper) { return this.retBool(this.baseMapper.update(entity, updateWrapper)); } @Transactional( rollbackFor = {Exception.class} ) public boolean updateBatchById(Collection<T> entityList, int batchSize) { if (CollectionUtils.isEmpty(entityList)) { throw new IllegalArgumentException("Error: entityList must not be empty"); } else { int i = 0; String sqlStatement = this.sqlStatement(SqlMethod.UPDATE_BY_ID); SqlSession batchSqlSession = this.sqlSessionBatch(); Throwable var6 = null; try { for(Iterator var7 = entityList.iterator(); var7.hasNext(); ++i) { T anEntityList = var7.next(); ParamMap<T> param = new ParamMap(); param.put("et", anEntityList); batchSqlSession.update(sqlStatement, param); if (i >= 1 && i % batchSize == 0) { batchSqlSession.flushStatements(); } } batchSqlSession.flushStatements(); return true; } catch (Throwable var17) { var6 = var17; throw var17; } finally { if (batchSqlSession != null) { if (var6 != null) { try { batchSqlSession.close(); } catch (Throwable var16) { var6.addSuppressed(var16); } } else { batchSqlSession.close(); } } } } } public T getById(Serializable id) { return this.baseMapper.selectById(id); } public Collection<T> listByIds(Collection<? extends Serializable> idList) { return this.baseMapper.selectBatchIds(idList); } public Collection<T> listByMap(Map<String, Object> columnMap) { return this.baseMapper.selectByMap(columnMap); } public T getOne(Wrapper<T> queryWrapper, boolean throwEx) { return throwEx ? this.baseMapper.selectOne(queryWrapper) : SqlHelper.getObject(this.baseMapper.selectList(queryWrapper)); } public Map<String, Object> getMap(Wrapper<T> queryWrapper) { return (Map)SqlHelper.getObject(this.baseMapper.selectMaps(queryWrapper)); } public int count(Wrapper<T> queryWrapper) { return SqlHelper.retCount(this.baseMapper.selectCount(queryWrapper)); } public List<T> list(Wrapper<T> queryWrapper) { return this.baseMapper.selectList(queryWrapper); } public IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper) { return this.baseMapper.selectPage(page, queryWrapper); } public List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper) { return this.baseMapper.selectMaps(queryWrapper); } public List<Object> listObjs(Wrapper<T> queryWrapper) { return (List)this.baseMapper.selectObjs(queryWrapper).stream().filter(Objects::nonNull).collect(Collectors.toList()); } public IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper) { return this.baseMapper.selectMapsPage(page, queryWrapper); } }

Wrapper条件查询器

它可以实现很多复杂的查询 参考 https://www.cnblogs.com/kzyuan/p/12706600.html

@Autowired(required = false) private UserMapper userMapper; @Autowired private IUserService iUserService; /** * 以前默认是叫EntityWrapper,现在叫QueryWrapper */ /** * 根据条件查询 */ @Test public void select(){ QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.isNotNull("name") //name不为空的用户 .isNotNull("email") //邮箱不为空 .ge("age",12); //年龄大于等于12 List<User> list=userMapper.selectList(wrapper); System.out.println(list); } /** * 根据名字查询 */ @Test public void selectName(){ QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.eq("name","ting"); List<User> list=userMapper.selectList(wrapper); System.out.println(list); } /** * 查询 10 到 20 岁的用户数 */ @Test public void selectByAge(){ QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.between("age",10,21); List<User> list=userMapper.selectList(wrapper); System.out.println(list); } /** * 模糊查询 */ @Test public void selectLike(){ QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper .notLike("name","2") .like("name","t") //右查询 .likeRight("email","234"); List<Map<String,Object>> users=userMapper.selectMaps(wrapper); System.out.println(users); } /** * 子查询 */ @Test public void selectLike2(){ QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.inSql("id","select id from user where age<21"); List<Object> users=userMapper.selectObjs(wrapper); System.out.println(users); } /** * 排序 */ @Test public void selectByOrder(){ QueryWrapper<User> wrapper=new QueryWrapper<>(); //降序排序 wrapper.orderByDesc("id"); List<User> users=userMapper.selectList(wrapper); System.out.println(users); } /** * 部分字段更新 */ @Test public void update(){ UpdateWrapper<User> wrapper=new UpdateWrapper<>(); User user=new User(); //更新字段 wrapper.set("name","xyz"); wrapper.eq("id",1321972874844389378L); System.out.println("更新结果:"+iUserService.update(user,wrapper)); }

分页 需要新建一个配置类

@Configuration @MapperScan("com.king.mapper") public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false // paginationInterceptor.setOverflow(false); // 设置最大单页限制数量,默认 500 条,-1 不受限制 // paginationInterceptor.setLimit(500); // 开启 count 的 join 优化,只针对部分 left join //paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); return paginationInterceptor; } }

测试代码:

/** * 分页 */ @Test public void page(){ //当前页1,每页大小2 IPage<User> userIPage=new Page<>(1,1); userIPage=userMapper.selectPage(userIPage,null); List<User> list=userIPage.getRecords(); System.out.println(list); }

多表查询

看了一下网上说mybatis-plus不支持多表操作,这就麻烦了,不然mybatis-plus有啥用呢,虽然说网上也有方法,但是我不想用,感觉比较麻烦吧,大家可以自己选择。

现在来看看吧,我们可以用这个代码自动生成器,生成对应的代码,然后在其基础上进行修改就好了,毕竟单表的基本操作他都做好了,多表我们就自己写呗,还是省了不少事的

sql语句:

create TABLE user( user_id INT PRIMARY KEY AUTO_INCREMENT, user_name VARCHAR(100), sex_id Int ) create TABLE sex( sex_id INT PRIMARY KEY AUTO_INCREMENT, sex_name VARCHAR(100) ) insert into user(user_name,sex_id) VALUES("king",1); insert into user(user_name,sex_id) VALUES("ting",2); insert into user(user_name,sex_id) VALUES("aaa",1); insert into sex(sex_name) VALUES("男"); insert into sex(sex_name) VALUES("女"); insert into sex(sex_name) VALUES("变态");

1、配置文件和自动生成代码配置器文件也和上面一样的,结构如下:

2、运行自动生成代码器,输入多个表名 4、首先需要对实体类进行修改 这个外键改成他对应的实体类就好了,并且上面需要加上注解,表明映射结果到哪里

sex类也要进行修改,如果需要的话

5、修改xml文件,映射关系改一下 6、就OK了,就可以使用了,如果需要自定义sql,自己在mapper中添加就是了

最新回复(0)