1。Mybatis存在的痛点 我们知道MyBatis是一个基于java的持久层框架,它内部封装了jdbc,极大提高了我们的开发效率。 但是使用Mybatis开发也有很多痛点:每个Dao接口都需要自己定义一堆增删改查方法。Desc:UserDao接口Author:公众号:知否技术date:下午7:43202257publicinterfaceUserDao{获取所有用户信息ListUsergetUserList();根绝id获取用户信息UsergetUserById(intid);新增用户信息booleanadd(Useruser);更新用户信息booleanupdate(Useruser);删除用户信息booleandelete(intid);} 2。每个Mapper文件都需要写一堆基本的增删改查语句。 3。如果查询的列表需要分页,我们还需要给查询方法封装成分页对象。 你可能会说:Mybatis还能有痛点?用着多方便! 对于小项目而言,用着确实还行。但是遇到大项目,光Dao接口都有几百个,如果还要手动定义一堆增删改查方法和sql语句,那也很浪费时间。 那有没有这样一个框架: 1。封装了Mybatis,自带CRUD方法,我们不需要自己定义CRUD方法。 2。提供各种查询方法,不需要在mapper文件中写一些基础的sql语句。 3。封装了分页功能,让分页查询无比丝滑。 有的,MybatisPlus闪亮登场。 2。邂逅MybatisPlus 官网:https:baomidou。com MybatisPlus是在Mybatis原有功能的基础上进行了封装。它不做改变,而是增强了Mybatis的功能。 我们不用写mappe。xml,直接调用它的API就能完成CRUD和各种查询操作。 而且它自带分页插件等一些高级功能,极大地提高了我们的开发效率。3。入门案例 开发环境:开发工具:IDEA构建工具:Maven数据库:MySQL项目框架:SpringBoot 1。新建SpringBoot项目 2。引入依赖!mybatisplus依赖dependencygroupIdcom。baomidougroupIdmybatisplusbootstarterartifactIdversion3。4。0versiondependency!mysql驱动dependencygroupIdmysqlgroupIdmysqlconnectorjavaartifactIdscoperuntimescopedependency!testdependencygroupIdorg。springframework。bootgroupIdspringbootstartertestartifactIdscopetestscopedependency 3。创建数据库表 user表:CREATETABLEuser(idbigintNOTNULLAUTOINCREMENTCOMMENTid,namevarchar(20)CHARACTERSETutf8mb4COLLATEutf8mb4generalciDEFAULTNULLCOMMENT姓名,ageintDEFAULTNULLCOMMENT年龄,PRIMARYKEY(id)USINGBTREE)ENGINEInnoDBAUTOINCREMENT1508421137384648706DEFAULTCHARSETutf8mb4COLLATEutf8mb4generalciROWFORMATDYNAMIC; 4。实体类publicclassUser{TableId(valueid,typeIdType。ASSIGNID)privateLongid;privateStringname;privateintage;publicUser(Stringname,intage){this。namename;this。ageage;}publicLonggetId(){returnid;}publicvoidsetId(Longid){this。idid;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this。namename;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this。ageage;}} 5。修改application。ymlserver:port:8082servlet:contextpath:mybatisplusdemo数据源配置spring:datasource:username:rootpassword:12345678url:jdbc:mysql:localhost:3306ssm?allowPublicKeyRetrievaltrueuseSSLfalsedriverclassname:com。mysql。cj。jdbc。Driver 6。新建UserMapper接口 注: (1)因为mybatis规定:mapper。xml文件的名字要和接口名字一样,所以很多人习惯将Dao接口命名为xxxMapper。 (2)BaseMapper是MybatisPlus内置的接口,它包含基本的CRUD方法。 7。启动类添加MapperScan注解 8。测试SpringBootTestpublicclassMybatisPlusDemoApplicationTests{ResourceprivateUserMapperuserMapper;TestvoidtestMybatisPlus(){for(inti18;i20;i){UserusernewUser(王小波i,i);userMapper。insert(user);}}} 9。总结 我们发现只要继承MybatisPlus的BaseMapper,就能完成基本的增删改查操作,非常方便。 4。基本增删改查 1。新增UserusernewUser(王小波,19);userMapper。insert(user); 2。编辑 根据id更新数据introwsuserMapper。updateById(user);if(rows0){System。out。println(更新成功);} 3。删除 根据主键删除信息userMapper。deleteById(152635612); 根据map条件删除信息MapString,ObjectparamnewHashMap();param。put(age,18);introwsuserMapper。deleteByMap(param);if(rows0){System。out。println(删除成功!);} 根据id集合批量删除ListIntegeridsStream。of(110,112,113,115)。collect(Collectors。toList());introwsuserMapper。deleteBatchIds(ids);if(rows0){System。out。println(删除成功!);} 4。查询 根据id查询UseruseruserMapper。selectById(152382374); 根据map条件查询MapString,ObjectparamnewHashMap();param。put(age,18);ListUseruserListuserMapper。selectByMap(param); 根据id集合批量查询ListIntegeridsStream。of(110,112,113,115)。collect(Collectors。toList());ListUseruserListuserMapper。selectBatchIds(ids);5。构造器 MybatisPlus提供了查询构造器和更新构造器用来生成带有where条件的sql语句。 (1)封装查询条件的构造器:QueryWrapper 常用查询条件: 等于:eqQueryWrapperUseruserWrappernewQueryWrapper();查询名字是张三的用户userWrapper。eq(name,张三);ListUseruserListuserMapper。selectList(userWrapper); 不等于:neQueryWrapperUseruserWrappernewQueryWrapper();userWrapper。ne(name,张三);查询名字不是张三的用户ListUseruserListuserMapper。selectList(userWrapper); 模糊查询:likeQueryWrapperUseruserWrappernewQueryWrapper();模糊查询userWrapper。like(name,张);ListUseruserListuserMapper。selectList(userWrapper); 降序:orderByDescQueryWrapperUseruserWrappernewQueryWrapper();模糊查询并根据number倒序userWrapper。like(name,张)。orderByDesc(number);ListUseruserListuserMapper。selectList(userWrapper); 升序:orderByAscQueryWrapperUseruserWrappernewQueryWrapper();模糊查询并根据number降序userWrapper。like(name,张)。orderByAsc(number);ListUseruserListuserMapper。selectList(userWrapper); 其他常用的条件可以去官网查看相关文档,这里不再过多赘述:https:baomidou。compages10c804in (2)封装更新条件的构造器:UpdateWrapper UpdateWrapper的where条件和QueryWrapper的一样,只不过需要set值。UpdateWrapperUseruserWrappernewUpdateWrapper();userWrapper。set(name,王小波)。set(age,22)。eq(name,张三);6。通用Service MybatisPlus中有一个通用的接口Iservice和实现类,封装了常用的增删改查等操作。 1。新建service和实现类 UserServiceDesc:Author:公众号:知否技术date:下午9:572022511publicinterfaceUserServiceextendsIServiceUser{} UserServiceImplDesc:Author:公众号:知否技术date:下午9:572022511ServicepublicclassUserServiceImplextendsServiceImplUserMapper,UserimplementsUserService{} 2。测试 我们发现该IService接口封装了一些常用的方法,极大地提高了我们的开发效率。7。常用注解 1。TableId MybatisPlus会默认将实体类中的id作为主键。 TableId表示id的生成策略,常用的有两种: (1)基于数据库的自增策略 (2)使用雪花算法策略随机生成 2。TableName 如果实体类和数据库的表名不一致,可以使用这个注解做映射 例如: 3。TableField 当表属性和实体类中属性名不一致时,可以使用这个注解做映射: 8。分页 MybatisPlus内部封装了分页插件,只用简单配置一下就能实现分页功能。 1。配置类Desc:Author:公众号:知否技术date:下午9:312022511ConfigurationMapperScan(com。zhifou。mapper)publicclassMybatisPlusConfig{BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptornewMybatisPlusInterceptor();interceptor。addInnerInterceptor(newPaginationInnerInterceptor(DbType。MYSQL));returninterceptor;}} 2。测试TestvoidtestMybatisPlus(){intcurrent1;intsize10;PageUseruserPagenewPage(current,size);获取分页数据ListUserlistuserPage。getRecords();list。forEach(user{System。out。println(user);});PageUserpageuserMapper。selectPage(userPage,null);System。out。println(当前页:page。getCurrent());System。out。println(每页条数:page。getSize());System。out。println(总记录数:page。getTotal());System。out。println(总页数:page。getPages());}9。代码生成器 MybatisPlus可以帮助我们自动生成controller、service、dao、model、mapper。xml等文件,极大地提高了我们的开发效率。 1。引入依赖!代码生成器dependencygroupIdcom。baomidougroupIdmybatisplusgeneratorartifactIdversion3。5。1versiondependencydependencygroupIdorg。freemarkergroupIdfreemarkerartifactIddependency 2。代码生成器工具类publicclassCodeGenerator{publicstaticvoidmain(String〔〕args){连接数据库FastAutoGenerator。create(jdbc:mysql:localhost:3306ssm?allowPublicKeyRetrievaltrueuseSSLfalseuseUnicodetruecharacterEncodingUTF8serverTimezoneUTC,root,123456)。globalConfig(builder{builder。author(知否技术)设置作者。fileOverride()覆盖已生成文件设置日期时间。dateType(DateType。ONLYDATE)。outputDir(D:WorkSpaceideamybatisplusdemosrcmainjava);指定输出目录})。packageConfig(builder{builder。parent(com。zhifou)设置父包名。pathInfo(Collections。singletonMap(OutputFile。mapperXml,D:WorkSpaceideamybatisplusdemosrcmainresourcesmapper));设置mapperXml生成路径})。strategyConfig(builder{builder。addInclude(tuser)设置需要生成的表名。addTablePrefix(t);设置过滤表前新增数据,自动为创建时间赋值IFillcreateFillnewColumn(createddate,FieldFill。INSERT);IFillupdateFillnewColumn(updateddate,FieldFill。UPDATE);builder。entityBuilder()设置id类型。idType(IdType。ASSIGNID)开启Lombok。enableLombok()开启连续设置模式。enableChainModel()驼峰命名模式。naming(NamingStrategy。underlinetocamel)。columnNaming(NamingStrategy。underlinetocamel)自动为创建时间、修改时间赋值。addTableFills(createFill)。addTableFills(updateFill)逻辑删除字段。logicDeleteColumnName(isdeleted);Restful风格builder。controllerBuilder()。enableRestStyle();去除Service前缀的Ibuilder。serviceBuilder()。formatServiceFileName(sService);mapper设置builder。mapperBuilder()。enableBaseResultMap()。enableBaseColumnList();})固定。templateEngine(newFreemarkerTemplateEngine())使用Freemarker引擎模板,默认的是Velocity引擎模板。execute();}} 关键点: (1)配置数据库连接信息。 自动生成代码需要连接数据库 (2)指定输出目录,这里直接设置你项目的目录,到时候不用赋值粘贴了。 (3)设置父包名。 (4)设置表名 然后右键运行,代码就会自动生成。10。application。yml配置MybatisPlusmybatisplus:globalconfig:dbconfig:columnunderline:true驼峰形式logicdeletefield:isDeleted全局逻辑删除的实体字段名logicdeletevalue:1逻辑已删除值(默认为1)logicnotdeletevalue:0逻辑未删除值(默认为0)dbtype:mysqlidtype:assignidid策略tableprefix:t配置表的默认前缀mapperlocations:classpath:mapperMapper。xmlmapper文件位置typealiasespackage:com。zhifou。entity实体类别名configuration:logimpl:org。apache。ibatis。logging。stdout。StdOutImplahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a:打印sql语句11。完整代码链接:https:pan。baidu。coms1nlRjKOWs3ON53Dh1XXLKGw提取码:9un712。遇到的坑 1。传参为0时,查询语句失效。 例如传递的age为0,查询就会失效selectidgetUserresultTypeuserselectid,name,age,sexfromuserwhereiftestage!nullandage!age{age}ifwhereselect 原因:判断int是否为空只要!null就行了,如果加上type!,0会被转为null。 2。MybatisPlus更新字段为null失败 解决办法:TableField(updateStrategyFieldStrategy。IGNORED)privateStringname; 该注解会忽略为空的判断, 链接:https:juejin。cnpost7097006142836408327