MyBatis-Plus集成Druid环境搭建的详细教程
一、简介
Mybatis-Plus是一款MyBatis动态sql自动注入crud简化增删改查操作中间件。启动加载XML配置时注入mybatis单表动态SQL操作,为简化开发工作、提高生产率而生。Mybatis-Plus启动注入非拦截实现、性能更优。
1.1、原理
1.2、特性
- 无侵入:Mybatis-Plus在Mybatis的基础上进行扩展,只做增强不做改变,引入Mybatis-Plus不会对您现有的Mybatis构架产生任何影响,而且MP支持所有Mybatis原生的特性
- 依赖少:仅仅依赖Mybatis以及Mybatis-Spring
- 损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作
- 预防Sql注入:内置Sql注入剥离器,有效预防Sql注入攻击
- 通用CRUD操作:内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作,更有强大的条件构造器,满足各类使用需求
- 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
- 支持热加载:Mapper对应的XML支持热加载,对于简单的CRUD操作,甚至可以无XML启动
- 支持ActiveRecord:支持ActiveRecord形式调用,实体类只需继承Model类即可实现基本CRUD操作
- 支持代码生成:采用代码或者Maven插件可快速生成Mapper、Model、Service、Controller层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S.比Mybatis官方的Generator更加强大!)
- 支持自定义全局通用操作:支持全局通用方法注入(Writeonce,useanywhere)
- 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
- 内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
- 内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
- 内置全局拦截插件:提供全表delete、update操作智能分析阻断,预防误操作
1.3、简化
MP简化了MyBatis的单表基本操作,提供了两种操作方式:
(1)、传统模式
Mybatis-Plus通过EntityWrapper(简称EW,MP封装的一个查询条件构造器)或者Condition(与EW类似)来让用户自由的构建查询条件,简单便捷,没有额外的负担,能够有效提高开发效率。
(2)、ActiveRecord模式
ActiveRecord(简称AR)模式是软件里的一种架构性模式,主要概念是关系型数据库中的数据在内存中以对象的形式存储。由MartinFowler在其2003年初版的书籍《PatternsofEnterpriseApplicationArchitecture》命名。遵循该模式的对象接口一般包括如Insert,Update,和Delete这样的函数,以及对应于底层数据库表字段的相关属性。
AR模式是一种访问数据库数据的方式。数据表或视图被映射成一个类。每个对象实例则对应于表的一条记录。对象被创建后,通过save就可以向表中新添一行记录。当对象被更新时,表中相应记录也被更新。这个包裹类通过属性或方法的形式实现访问表或视图中的每一个字段。
该模式主要被对象持久化工具采用,用于对象关系映射(ORM).典型的,外键关系会以合适的对象实例属性的形式暴露访问。
1.4、常用实体注解
1.表名注解@TableName
2.主键注解@TableId
3.字段注解@TableFieId
4.序列主键策略注解@KeySequence
二、搭建
环境:
IDEA
SpringBoot-2.0
MyBatis-Plus-2.2.0
MyBatisPlus-spring-boot-starter-1.0.5
druid-spring-boot-starter-1.1.9
首先创建SpringBootMaven项目,然后加入以下依赖:
4.0.0 com.fendo.mybatis.plus demo 0.0.1-SNAPSHOT jar mybatis-plus mybatis-plus示例 org.springframework.boot spring-boot-starter-parent 2.0.0.RELEASE UTF-8 UTF-8 1.8 1.8 1.8 1.0.5 2.2.0 1.2.39 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jetty org.springframework.boot spring-boot-devtools runtime mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-test test com.baomidou mybatisplus-spring-boot-starter ${mybatisplus-spring-boot-starter.version} com.baomidou mybatis-plus ${mybatisplus.version} com.alibaba fastjson ${fastjson.version} com.alibaba druid-spring-boot-starter 1.1.9 com.jayway.restassured rest-assured 2.9.0 io.springfox springfox-swagger2 2.2.2 io.springfox springfox-swagger-ui 2.2.2 org.springframework.boot spring-boot-maven-plugin
然后新建application.yml配置文件
#Tomcat server: tomcat: uri-encoding:UTF-8 max-threads:1000 min-spare-threads:30 port:8080 connection-timeout:5000 #datasource spring: datasource: name:fendo url:jdbc:mysql://localhost:3306/fendo_plus_boot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false username:root password:root type:com.alibaba.druid.pool.DruidDataSource driver-class-name:com.mysql.jdbc.Driver initialSize:5 minIdle:5 maxActive:20 maxWait:60000 timeBetweenEvictionRunsMillis:60000 minEvictableIdleTimeMillis:300000 validationQuery:SELECT1FROMDUAL testWhileIdle:true testOnBorrow:false testOnReturn:false poolPreparedStatements:true maxPoolPreparedStatementPerConnectionSize:20 spring.datasource.filters:stat,wall,log4j connectionProperties:druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 #jackson时间格式化 jackson: time-zone:GMT+8 date-format:yyyy-MM-ddHH:mm:ss thymeleaf: cache:false prefix:classpath:/templates/ suffix:.html mode:LEGACYHTML5 encoding:UTF-8 check-template:false enabled:false resources:#指定静态资源的路径 static-locations:classpath:/static/,classpath:/views/ mvc: view: prefix:/WEB-INF/ suffix:.jsp #Mybatis-Plus配置 mybatis-plus: mapper-locations:classpath:/mapper/*Mapper.xml typeAliasesPackage:com.fendo.mybatis.plus.entity typeEnumsPackage:com.fendo.mybatis.plus.entity.enums #global-config: #id-type:2 #field-strategy:2 #db-column-underline:true #refresh-mapper:true ##capital-mode:true ##key-generator:com.baomidou.springboot.xxx #logic-delete-value:0 #logic-not-delete-value:1 #sql-injector:com.baomidou.mybatisplus.mapper.LogicSqlInjector ##meta-object-handler:com.baomidou.springboot.xxx ##sql-injector:com.baomidou.springboot.xxx #configuration: #map-underscore-to-camel-case:true #cache-enabled:false global-config: id-type:3#0:数据库ID自增1:用户输入id2:全局唯一id(IdWorker)3:全局唯一ID(uuid) db-column-underline:false refresh-mapper:true configuration: map-underscore-to-camel-case:true cache-enabled:true#配置的缓存的全局开关 lazyLoadingEnabled:true#延时加载的开关 multipleResultSetsEnabled:true#开启的话,延时加载一个属性时会加载该对象全部属性,否则按需加载属性 log-impl:org.apache.ibatis.logging.stdout.StdOutImpl#打印sql语句,调试用
创建MyBatis-Plus配置类MybatisPlusConfig
/** *projectName:fendo-plus-boot *fileName:MybatisPlusConfig.java *packageName:com.fendo.mybatis.plus.config *date:2018-01-1223:13 *copyright(c)2017-2020xxx公司 */ packagecom.fendo.mybatis.plus.config; importcom.baomidou.mybatisplus.plugins.PaginationInterceptor; importcom.baomidou.mybatisplus.plugins.PerformanceInterceptor; importorg.mybatis.spring.annotation.MapperScan; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; /** *@version:V1.0 *@author:fendo *@className:MybatisPlusConfig *@packageName:com.fendo.mybatis.plus.config *@description:Mybatis-plus配置类 *@data:2018-01-1223:13 **/ @Configuration @MapperScan("com.fendo.mybatis.plus.mapper*") publicclassMybatisPlusConfig{ /** *mybatis-plusSQL执行效率插件【生产环境可以关闭】 */ @Bean publicPerformanceInterceptorperformanceInterceptor(){ returnnewPerformanceInterceptor(); } /** *分页插件 */ @Bean publicPaginationInterceptorpaginationInterceptor(){ returnnewPaginationInterceptor(); } }
三、测试
首先创建User表
CREATETABLE`user`( `id`varchar(32)NOTNULL, `name`varchar(255)DEFAULTNULL, `age`int(2)DEFAULTNULL, `sex`int(2)DEFAULTNULL, `create_by`varchar(255)DEFAULTNULL, `create_date`datetimeDEFAULTNULL, `update_by`varchar(255)DEFAULTNULL, `update_date`datetimeDEFAULTNULL, `remarks`varchar(255)DEFAULTNULL, `del_flag`varchar(255)DEFAULTNULL, PRIMARYKEY(`id`) )ENGINE=InnoDBDEFAULTCHARSET=utf8;
然后创建controller,entity,service,mapper,项目结构如下所示:
Controller测试类如下:
/** *projectName:mybatis-plus *fileName:UserController.java *packageName:com.fendo.mybatis.plus.controller *date:2018-03-2419:07 *copyright(c)2017-2020xxx公司 */ packagecom.fendo.mybatis.plus.controller; importcom.alibaba.fastjson.JSONObject; importcom.baomidou.mybatisplus.mapper.EntityWrapper; importcom.baomidou.mybatisplus.plugins.Page; importcom.baomidou.mybatisplus.plugins.pagination.PageHelper; importcom.fendo.mybatis.plus.common.utils.IdGen; importcom.fendo.mybatis.plus.entity.UserEntity; importcom.fendo.mybatis.plus.entity.enums.AgeEnum; importcom.fendo.mybatis.plus.entity.enums.SexEnum; importcom.fendo.mybatis.plus.service.UserService; importio.swagger.annotations.Api; importio.swagger.annotations.ApiOperation; importio.swagger.annotations.ApiResponse; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.transaction.annotation.Transactional; importorg.springframework.web.bind.annotation.GetMapping; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RestController; /** *@version:V1.0 *@author:fendo *@className:UserController *@packageName:com.fendo.mybatis.plus.controller *@description:用户Controller *@data:2018-03-2419:07 **/ @RestController @RequestMapping("/user") @Api("用户操作接口") publicclassUserController{ @Autowired privateUserServiceuserService; /** *分页PAGE */ @GetMapping("/page") @ApiOperation(value="用户分页数据",response=UserEntity.class) @ApiResponse(code=200,message="success") publicPagetest(){ returnuserService.selectPage(newPage (0,12)); } /** *AR部分测试 */ @GetMapping("/insert") publicPage insert(){ UserEntityuser=newUserEntity(IdGen.getUUID(),"testAr",AgeEnum.ONE,SexEnum.FEMALE); System.err.println("删除所有:"+user.delete(null)); user.insert(); System.err.println("查询插入结果:"+user.selectById().toString()); user.setName("mybatis-plus-ar"); System.err.println("更新:"+user.updateById()); returnuser.selectPage(newPage (0,12),null); } /** *增删改查CRUD */ @GetMapping("/crud") publicUserEntitycrud(){ System.err.println("删除一条数据:"+userService.deleteById("85349feb19f04fa78a7a717f4dce031f")); System.err.println("deleteAll:"+userService.deleteAll()); StringIdGens=IdGen.getUUID(); System.err.println("插入一条数据:"+userService.insert(newUserEntity(IdGens,"张三",AgeEnum.TWO,SexEnum.FEMALE))); UserEntityuser=newUserEntity("张三",AgeEnum.TWO,SexEnum.MALE); booleanresult=userService.insert(user); //自动回写的ID Stringid=user.getId(); System.err.println("插入一条数据:"+result+",插入信息:"+user.toString()); System.err.println("查询:"+userService.selectById(id).toString()); System.err.println("更新一条数据:"+userService.updateById(newUserEntity(IdGens,"三毛",AgeEnum.ONE,SexEnum.FEMALE))); for(inti=0;i<5;++i){ userService.insert(newUserEntity(IdGen.getUUID(),"张三"+i,AgeEnum.ONE,SexEnum.FEMALE)); } Page userListPage=userService.selectPage(newPage (1,5),newEntityWrapper<>(newUserEntity())); System.err.println("total="+userListPage.getTotal()+",currentlistsize="+userListPage.getRecords().size()); returnuserService.selectById(IdGens); } /** *插入OR修改 */ @GetMapping("/save") publicUserEntitysave(){ StringIdGens=IdGen.getUUID(); UserEntityuser=newUserEntity(IdGens,"王五",AgeEnum.ONE,SexEnum.FEMALE); userService.insertOrUpdate(user); returnuserService.selectById(IdGens); } @GetMapping("/add") publicObjectaddUser(){ UserEntityuser=newUserEntity(IdGen.getUUID(),"张三'特殊`符号",AgeEnum.TWO,SexEnum.FEMALE); JSONObjectresult=newJSONObject(); result.put("result",userService.insert(user)); returnresult; } @GetMapping("/selectsql") publicObjectgetUserBySql(){ JSONObjectresult=newJSONObject(); result.put("records",userService.selectListBySQL()); returnresult; } /** *7、分页size一页显示数量current当前页码 *方式一:http://localhost:8080/user/page?size=1¤t=1 *方式二:http://localhost:8080/user/pagehelper?size=1¤t=1 */ //参数模式分页 @GetMapping("/pages") publicObjectpage(Pagepage){ returnuserService.selectPage(page); } //ThreadLocal模式分页 @GetMapping("/pagehelper") publicObjectpagehelper(Pagepage){ PageHelper.setPagination(page); page.setRecords(userService.selectList(null)); page.setTotal(PageHelper.freeTotal());//获取总数并释放资源也可以PageHelper.getTotal() returnpage; } /** *测试事物 *http://localhost:8080/user/test_transactional
*访问如下并未发现插入数据说明事物可靠!!
*http://localhost:8080/user/test
*
*启动Application加上@EnableTransactionManagement注解其实可无默认貌似就开启了
*需要事物的方法加上@Transactional必须的哦!! */ @Transactional @GetMapping("/test_transactional") publicvoidtestTransactional(){ StringIdGens=IdGen.getUUID(); userService.insert(newUserEntity(IdGens,"测试事物",AgeEnum.ONE,SexEnum.FEMALE)); System.out.println("这里手动抛出异常,自动回滚数据:"+IdGens); thrownewRuntimeException(); } }
四、代码生成
创建测试类GeneratorStart
/** *projectName:fendo-plus-boot *fileName:GeneratorStart.java *packageName:com.fendo.shiro.generator *date:2018-01-1519:59 *copyright(c)2017-2020xxx公司 */ packagecom.gzsys.modules.gen; importcom.baomidou.mybatisplus.generator.AutoGenerator; importcom.baomidou.mybatisplus.generator.InjectionConfig; importcom.baomidou.mybatisplus.generator.config.*; importcom.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; importcom.baomidou.mybatisplus.generator.config.po.TableInfo; importcom.baomidou.mybatisplus.generator.config.rules.DbType; importcom.baomidou.mybatisplus.generator.config.rules.NamingStrategy; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.List; importjava.util.Map; /** *@version:V1.0 *@author:fendo *@className:GeneratorStart *@packageName:com.gzsys.modules.gen *@description:代码生成器 *@data:2018-01-1519:59 **/ publicclassGeneratorStart{ publicstaticvoidmain(String[]args){ StringpackageName="com.gzsys.modules.yun"; booleanserviceNameStartWithI=false;//user->UserService,设置成true:user->IUserService generateByTables(serviceNameStartWithI,packageName,"USER_LOGIN"); } privatestaticvoidgenerateByTables(booleanserviceNameStartWithI,StringpackageName,String...tableNames){ //全局配置 GlobalConfigconfig=newGlobalConfig(); AutoGeneratormpg=newAutoGenerator(); StringdbUrl="jdbc:oracle:thin:@//106.14.160.67:1521/test"; DataSourceConfigdataSourceConfig=newDataSourceConfig(); dataSourceConfig.setDbType(DbType.ORACLE) .setUrl(dbUrl) .setUsername("test") .setPassword("Eru43wPo") .setDriverName("oracle.jdbc.driver.OracleDriver"); //策略配置 StrategyConfigstrategyConfig=newStrategyConfig(); strategyConfig .setCapitalMode(true)//全局大写命名ORACLE注意 .setEntityLombokModel(false)//实体是否为lombok模型(默认false) .setDbColumnUnderline(true)//表名、字段名、是否使用下划线命名 .setNaming(NamingStrategy.underline_to_camel)//表名生成策略 .setInclude(tableNames);//修改替换成你需要的表名,多个表名传数组 //strategyConfig.setExclude(newString[]{"test"});//排除生成的表 //自定义实体父类 strategyConfig.setSuperEntityClass("com.gzsys.common.persistence.BaseEntity"); //自定义实体,公共字段 strategyConfig.setSuperEntityColumns(newString[]{"ID","CREATE_TIME","CREATE_NAME","UPDATE_TIME","UPDATE_NAME","STATE"}); //自定义mapper父类 //strategyConfig.setSuperMapperClass("com.baomidou.demo.TestMapper"); //自定义service父类 //strategyConfig.setSuperServiceClass("com.baomidou.demo.TestService"); //自定义service实现类父类 //strategyConfig.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl"); //自定义controller父类 strategyConfig.setSuperControllerClass("com.gzsys.common.base.controller.BaseController"); //【实体】是否生成字段常量(默认false) //publicstaticfinalStringID="test_id"; //strategyConfig.setEntityColumnConstant(true); //【实体】是否为构建者模型(默认false) //publicUsersetName(Stringname){this.name=name;returnthis;} //strategyConfig.setEntityBuliderModel(true); config.setActiveRecord(true)//是否开启ActiveRecord模式 .setAuthor("fendo") .setOutputDir("d:\\codeGen") .setFileOverride(true) .setActiveRecord(true) .setEnableCache(false)//XML二级缓存 .setBaseResultMap(true)//XMLResultMap .setBaseColumnList(false);//XMLcolumList if(!serviceNameStartWithI){ config.setServiceName("%sService");//自定义Service后戳,注意%s会自动填充表实体属性! } //注入自定义配置,可以在VM中使用cfg.abc【可无】 InjectionConfigcfg=newInjectionConfig(){ @Override publicvoidinitMap(){ Mapmap=newHashMap (); map.put("abc",this.getConfig().getGlobalConfig().getAuthor()+"-mp"); this.setMap(map); } }; //自定义xxList.jsp生成 List focList=newArrayList (); //focList.add(newFileOutConfig("/template/list.jsp.vm"){ //@Override //publicStringoutputFile(TableInfotableInfo){ ////自定义输入文件名称 //return"D://my_"+tableInfo.getEntityName()+".jsp"; //} //}); //cfg.setFileOutConfigList(focList); //mpg.setCfg(cfg); //调整xml生成目录演示 focList.add(newFileOutConfig("/templates/mapper.xml.vm"){ @Override publicStringoutputFile(TableInfotableInfo){ return"d:\\codeGen/resources/mapping/modules/yun/"+tableInfo.getEntityName()+".xml"; } }); cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); //关闭默认xml生成,调整生成至根目录 TemplateConfigtc=newTemplateConfig(); tc.setXml(null); mpg.setTemplate(tc); //自定义模板配置,可以copy源码mybatis-plus/src/main/resources/templates下面内容修改, //放置自己项目的src/main/resources/templates目录下,默认名称一下可以不配置,也可以自定义模板名称 //TemplateConfigtc=newTemplateConfig(); //tc.setController("..."); //tc.setEntity("..."); //tc.setMapper("..."); //tc.setXml("..."); //tc.setService("..."); //tc.setServiceImpl("..."); //如上任何一个模块如果设置空ORNull将不生成该模块。 //mpg.setTemplate(tc); //生成文件配置 mpg.setGlobalConfig(config)//全局相关配置 .setDataSource(dataSourceConfig)//数据源配置 .setStrategy(strategyConfig)//数据库表配置 .setPackageInfo(//包相关配置 newPackageConfig()//跟包相关的配置项 .setParent(packageName)//父包名。如果为空,将下面子包名必须写全部,否则就只需写子包名 .setController("controller")//Controller包名 .setEntity("entity")//entity包名 //.setXml("/") ) .execute(); } privatevoidgenerateByTables(StringpackageName,String...tableNames){ generateByTables(true,packageName,tableNames); } }
SpringBoot整合mybatis与swagger2
到此这篇关于MyBatis-Plus集成Druid环境搭建的详细教程的文章就介绍到这了,更多相关MyBatis-Plus环境搭建内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。