为简化开发而生 Mybatis简化JDBC操作 MyBatisPlus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。1、特性无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作强大的CRUD操作:内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作,更有强大的条件构造器,满足各类使用需求支持Lambda形式调用:通过Lambda表达式,方便的编写各类查询条件,无需再担心字段写错支持主键自动生成:支持多达4种主键策略(内含分布式唯一ID生成器Sequence),可自由配置,完美解决主键问题支持ActiveRecord模式:支持ActiveRecord形式调用,实体类只需继承Model类即可进行强大的CRUD操作支持自定义全局通用操作:支持全局通用方法注入(Writeonce,useanywhere)内置代码生成器:采用代码或者Maven插件可快速生成Mapper、Model、Service、Controller层代码,支持模板引擎,更有超多自定义配置等您来使用内置分页插件:基于MyBatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询分页插件支持多种数据库:支持MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer等多种数据库内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询内置全局拦截插件:提供全表delete、update操作智能分析阻断,也可自定义拦截规则,预防误操作2、支持数据库mysql、mariadb、oracle、db2、h2、hsql、sqlite、postgresql、sqlserver达梦数据库、虚谷数据库、人大金仓数据库3、快速开始1、创建数据库DROPTABLEIFEXISTSCREATETABLEuser(idBIGINT(20)NOTNULLCOMMENT主键ID,nameVARCHAR(30)NULLDEFAULTNULLCOMMENT姓名,ageINT(11)NULLDEFAULTNULLCOMMENT年龄,emailVARCHAR(50)NULLDEFAULTNULLCOMMENT邮箱,PRIMARYKEY(id));INSERTINTOuser(id,name,age,email)VALUES(1,Jone,18,test1baomidou。com),(2,Jack,20,test2baomidou。com),(3,Tom,28,test3baomidou。com),(4,Sandy,21,test4baomidou。com),(5,Billie,24,test5baomidou。com);2、新建SpringBoot项目导入依赖dependencyspanstylecolor:E06C75;ttdarkmodecolor:E06C75;groupIdspanorg。springframework。bootspangroupIdspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;artifactIdspanspringbootdevtoolsspanartifactIdspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;scopespanruntimespanscopespanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;optionalspantruespanoptionalspanspandependencyspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;dependencyspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;groupIdspanmysqlspangroupIdspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;artifactIdspanmysqlconnectorjavaspanartifactIdspanspandependencyspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;dependencyspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;groupIdspanorg。projectlombokspangroupIdspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;artifactIdspanlombokspanartifactIdspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;optionalspantruespanoptionalspanspandependencyspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;dependencyspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;groupIdspancom。baomidouspangroupIdspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;artifactIdspanmybatisplusbootstarterspanartifactIdspanspanstylecolor:E06C75;ttdarkmodecolor:E06C75;versionspan3。3。1。tmpspanversionspanspandependencyspanli连接数据库spring:datasource:url:jdbc:mysql:localhost:3306mybatisplus?useSSLtrueuseUnicodetruecharacterEncodingUTF8serverTimezoneGMTuseSSL安全连接useUnicode编码characterEncoding编码格式serverTimezone时区username:用户名password:密码driverclassname:com。mysql。cj。jdbc。Driver创建实体类UserDataAllArgsConstructorNoArgsConstructorpublicclassUser{privateLprivateSprivateIprivateS}实现接口UserMapperMapperRepository代表持久层publicinterfaceUserMapperextendsBaseMapperspanstylecolor:D19A66;ttdarkmodecolor:D19A66;Userspan{所有的CRUD已经编写完成}li在SpringBoot启动类中添加MapperScan注解,扫描Mapper文件夹SpringBootApplicationMapperScan(com。xiaobear。mapper)扫描文件夹publicclassMybatisplusApplication{publicstaticvoidmain(String〔〕args){SpringApplication。run(MybatisplusApplication。class,args);}}测试SpringBootTestclassMybatisplusApplicationTests{AutowiredprivateUserMapperuserMTestvoidcontextLoads(){查询所有用户ListlistuserMapper。selectList(null);list。forEach(System。out::println);}}4、配置日志 使用默认控制台输出日志配置ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志amybatisplus:configuration:logimpl:org。apache。ibatis。logging。stdout。StdOutImpl5、CRUD扩展Insert测试插入TestpublicvoidtestInsert(){UserusernewUser();user。setName(小熊);user。setAge(18);user。setEmail(2861184805qq。com);intinsertuserMapper。insert(user);自动生成idSystem。out。println(insert);System。out。println(user);}} 结果 主键生成策略雪花算法:Twitter利用zookeeper实现了一个全局ID生成的服务Snowflake:github。comtwittersno: snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096个ID),最后还有一个符号位,永远是0 主键自增 我们配置主键自增实体类字段上加上TableId(typeIdType。AUTO)数据库字段上一定要自增 再次测试即可publicenumIdType{AUTO(0),数据库id自增NONE(1),未设置主键INPUT(2),手动输入ASSIGNID(3),默认全局idASSIGNUUID(4),全局唯一idDeprecatedIDWORKER(3),DeprecatedIDWORKERSTR(3),IDWORKER字符串表示法DeprecatedUUID(4);privateIdType(intkey){this。}publicintgetKey(){returnthis。}}updateTestpublicvoidtestupdate(){通过条件自动拼接动态sqlUserusernewUser();user。setId(6L);user。setName(你是最棒的);intiuserMapper。updateById(user);updateById参数是一个对象System。out。println(i);}} 自动填充 数据库级别(工作中不使用) 1、在表中字段增加createtime、updatetime 2、通过测试插入方法privateDatecreateTprivateDateupdateT 3、查看结果 代码级别 1、实体类属性上增加注解TableField(fillFieldFill。INSERT)privateDatecreateTTableField(fillFieldFill。INSERTUPDATE)privateDateupdateT 2、实现元对象处理器接口:com。baomidou。mybatisplus。core。handlers。MetaObjectHandler 自定义实现类MyMetaObjectHandlerComponent加入到IOC容器里Slf4jpublicclassMyMetaObjectHandlerimplementsMetaObjectHandler{OverridepublicvoidinsertFill(MetaObjectmetaObject){log。info(startinsertfill。。。。);this。setFieldValByName(createTime,newDate(),metaObject);this。setFieldValByName(updateTime,newDate(),metaObject);}OverridepublicvoidupdateFill(MetaObjectmetaObject){log。info(startupdatefill。。。。);this。setFieldValByName(updateTime,newDate(),metaObject);}} 3、测试插入,观察时间乐观锁 十分乐观,它总是认为不会出现问题,无论干什么都不上锁,如果出现了问题,再次更新值测试! 乐观锁实现方式:取出记录时,获取当前version更新时,带上这个version执行更新时,setversionnewVersionwhereversionoldVersion如果version不对,就更新失败 1、给数据库新增字段verison,默认值为1 2、实体类新增字段Version乐观锁注解privateI 3、注册插件ConfigurationMapperScan(com。xiaobear。mapper)publicclassMybatisPlusConfig{注册乐观锁插件BeanpublicOptimisticLockerInterceptoroptimisticLockerInterceptor(){returnnewOptimisticLockerInterceptor();}} 4、测试TestpublicvoidtestOptimisticLocker(){查询用户信息UseruseruserMapper。selectById(1L);修改信息user。setName(xiaobear);user。setAge(2);执行intupdateuserMapper。updateById(user);System。out。println(update);}测试失败TestpublicvoidtestOptimisticLocker2(){UseruseruserMapper。selectById(1L);user。setName(xiaobear);user。setAge(2);Useruser2userMapper。selectById(1L);user2。setName(xiaobear111);user2。setAge(10);模拟另一个线程进行插队操作intupdateuserMapper。updateById(user);intupdate2userMapper。updateById(user2);System。out。println(update);System。out。println(update2);}悲观锁 十分悲观,它总是认为会出现问题,无论干什么都会上锁,再去操作!查询操作单个查询TestpublicvoidtestSelect(){UseruseruserMapper。selectById(2L);System。out。println(user);}批量查询TestpublicvoidtestSelectByBatchId(){ListUserusersuserMapper。selectBatchIds(Arrays。asList(1,2,3));users。forEach(System。out::println);}条件查询mapTestpublicvoidtestSelectByBatchIds(){HashMapString,ObjectmapnewHashMap();map。put(name,xiaobear);ListUserusersuserMapper。selectByMap(map);users。forEach(System。out::println);}分页查询 分页插件分页插件BeanpublicPaginationInterceptorpaginationInterceptor(){returnnewPaginationInterceptor();PaginationInterceptorpaginationInterceptornewPaginationInterceptor();设置请求的页面大于最大页后操作,true调回到首页,false继续请求默认falsepaginationInterceptor。setOverflow(false);设置最大单页限制数量,默认500条,1不受限制paginationInterceptor。setLimit(500);开启count的join优化,只针对部分leftjoinpaginationInterceptor。setCountSqlParser(newJsqlParserCountOptimize(true));returnpaginationI} 测试测试分页插件TestpublicvoidtestPage(){参数一:当前页参数二:页面大小PageUserpagenewPage(1,5);userMapper。selectPage(page,null);page。getRecords()。forEach(System。out::println);System。out。println(page。getTotal());}删除操作测试删除TestpublicvoiddeleteById(){intiuserMapper。deleteById(1L);System。out。println(i);}测试id批量删除TestpublicvoiddeleteById2(){userMapper。deleteBatchIds(Arrays。asList(1L,2L,3L));}通过map删除TestpublicvoidtestDeleteMap(){HashMapString,ObjectmapnewHashMap();map。put(name,小熊);userMapper。deleteByMap(map);}逻辑删除物理删除:从数据库中直接删除 逻辑删除:在数据库没有移除,而是通过一个变量来让他失效!防止数据丢失,类似回收站 数据库添加字段,实体类上加上字段TableLogicprivateI 测试删除、查询6、性能分析插件 性能分析拦截器,用于输出每条SQL语句及其执行时间SQL执行效率插件BeanProfile({dev,test})设置devtest环境开启publicPerformanceInterceptorperformanceInterceptor(){returnnewPerformanceInterceptor();}7、条件构造器wrapperAutowiredprivateUserMapperuserMTestvoidcontextLoads(){QueryWrapperUserwrappernewQueryWrapper();wrapper。isNotNull(name)。isNotNull(email)。ge(age,3);userMapper。selectList(wrapper)。forEach(System。out::println);}Testvoidtest(){QueryWrapperUserwrappernewQueryWrapper();wrapper。eq(name,Tom);查询名字UseruseruserMapper。selectOne(wrapper);查询一个数据System。out。println(user);}Testvoidtest2(){查询年龄1020QueryWrapperUserwrappernewQueryWrapper();wrapper。between(age,10,20);IntegercountuserMapper。selectCount(wrapper);System。out。println(count);}Testvoidtest3(){模糊查询QueryWrapperUserwrappernewQueryWrapper();wrapper。notLike(name,e)。likeRight(email,t);ListMapString,ObjectmapsuserMapper。selectMaps(wrapper);maps。forEach(System。out::println);}Testvoidtest4(){QueryWrapperUserwrappernewQueryWrapper();wrapper。inSql(id,selectidformuserwhereid3);ListObjectobjectsuserMapper。selectObjs(wrapper);objects。forEach(System。out::println);}8、代码生成器publicclassXiaoBearCode{publicstaticvoidmain(String〔〕args){AutoGeneratormpgnewAutoGenerator();全局配置GlobalConfiggcnewGlobalConfig();StringprojectPathSystem。getProperty(user。dir);gc。setOutputDir(projectPathsrcmainjava);gc。setAuthor(xiaobear);gc。setOpen(false);gc。setSwagger2(true);实体属性Swagger2注解mpg。setGlobalConfig(gc);数据源配置DataSourceConfigdscnewDataSourceConfig();dsc。setUrl(jdbc:mysql:localhost:3306mybatisplus?useSSLtrueuseUnicodetruecharacterEncodingUTF8serverTimezoneGMT);dsc。setSchemaName(public);dsc。setDriverName(com。mysql。cj。jdbc。Driver);dsc。setUsername(用户名);dsc。setPassword(密码);mpg。setDataSource(dsc);包配置PackageConfigpcnewPackageConfig();pc。setModuleName(blog);pc。setParent(com。xiaobear);pc。setEntity(pojo);pc。setMapper(mapper);pc。setService(comxiaobearservice);pc。setServiceImpl(com。xiaobearServiceImpl);pc。setController(comxiaobearcontroller);mpg。setPackageInfo(pc);策略配置StrategyConfigstrategynewStrategyConfig();strategy。setNaming(NamingStrategy。underlinetocamel);strategy。setColumnNaming(NamingStrategy。underlinetocamel);strategy。setEntityLombokModel(true);自动lombokstrategy。setRestControllerStyle(true);公共父类strategy。setSuperControllerClass(你自己的父类控制器,没有就不用设置!);写于父类中的公共字段strategy。setSuperEntityColumns(id);strategy。setInclude(user);映射的表strategy。setLogicDeleteFieldName(deleted);逻辑删除字段自动填充策略TableFillgmtcreatenewTableFill(gmtcreate,FieldFill。INSERT);TableFillgmtmodifiednewTableFill(gmtstrate,FieldFill。INSERT);ArrayListTableFilllistnewArrayList();list。add(gmtcreate);list。add(gmtmodified);strategy。setTableFillList(list);乐观锁strategy。setVersionFieldName(version);strategy。setRestControllerStyle(true);驼峰strategy。setControllerMappingHyphenStyle(true);localhost:8080helloid1strategy。setTablePrefix(pc。getModuleName());mpg。setStrategy(strategy);mpg。setTemplateEngine(newFreemarkerTemplateEngine());mpg。execute();执行}} 错误:19:39:38。943〔main〕DEBUGcom。baomidou。mybatisplus。generator。AutoGenerator准备生成文件。。。Exceptioninthreadmainjava。lang。NoClassDefFoundError:freemarkertemplateConfigurationatcom。baomidou。mybatisplus。generator。engine。FreemarkerTemplateEngine。init(FreemarkerTemplateEngine。java:41)atcom。baomidou。mybatisplus。generator。engine。FreemarkerTemplateEngine。init(FreemarkerTemplateEngine。java:34)atcom。baomidou。mybatisplus。generator。AutoGenerator。execute(AutoGenerator。java:103)atcom。xiaobear。XiaoBearCode。main(XiaoBearCode。java:66)Causedby:java。lang。ClassNotFoundException:freemarker。template。Configurationatjava。net。URLClassLoader。findClass(URLClassLoader。java:382)atjava。lang。ClassLoader。loadClass(ClassLoader。java:418)atsun。misc。LauncherAppClassLoader。loadClass(Launcher。java:355)atjava。lang。ClassLoader。loadClass(ClassLoader。java:351)。。。4more 解决:导入模板引擎依赖 org。freemarkerfreemarkerartifactId2。3。30