范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

SpringBoot整合Druid全局事务管理MybatisPlus代码生成器

  在springboot开发当中,Druid,全局事务管理,代码生成器都是非常实用的,特此记录下整合的过程 整合Druid连接池
  springboot默认的连接池是:HikariCP,但是Druid的功能相对来说比较全面。
  第一步:引入相关JAR           com.alibaba         druid-spring-boot-starter         1.1.22                   mysql         mysql-connector-java         runtime     
  第二步:配置相关参数spring:   datasource:     type: com.alibaba.druid.pool.DruidDataSource     druid:       name: 数据源名称       driver-class-name: com.mysql.jdbc.Driver       username: root       password: 123456       url: jdbc:mysql://127.0.0.1:3306/springboot?characterEncoding=utf8&useSSL=false       # 连接池的配置信息       # 初始化大小,最小,最大       initial-size: 5       min-idle: 5       maxActive: 20       # 配置获取连接等待超时的时间       maxWait: 60000       # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒       timeBetweenEvictionRunsMillis: 60000       # 配置一个连接在池中最小生存的时间,单位是毫秒       minEvictableIdleTimeMillis: 300000       validationQuery: SELECT 1       testWhileIdle: true       testOnBorrow: false       testOnReturn: false       # 打开PSCache,并且指定每个连接上PSCache的大小       poolPreparedStatements: true       maxPoolPreparedStatementPerConnectionSize: 20       # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,"wall"用于防火墙       filters: stat,wall,slf4j,config       # 通过connectProperties属性来打开mergeSql功能;慢SQL记录       connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000       web-stat-filter:         enabled: true         url-pattern: "/"         exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"       stat-view-servlet:         enabled: true         url-pattern: "/druid/*"         login-username: admin  # 登录账号   不设置就不需要登录就可以访问druid可视化界面         login-password: 123456 # 登录密码         reset-enable: false         allow: ""  # 白名单 表示所有         deny: 192.168.1.12 # 黑名单
  第三步:在浏览器当中输入:http://127.0.0.1:8080/druid/index.html 即可进入可视化界面全局事务管理器
  springboot当中添加事务直接使用注解@Transactional 即可,但是每个方法都要添加比较麻烦,可以直接通过切面的方式添加一个全局的事务管理器。注意事项是,要注意方法名开头的问题@Configuration @EnableTransactionManagement public class TransactionConfiguration {      /**      * 配置全局事务的切点为service层的所有方法  AOP切面表达式 可参考(https://blog.csdn.net/ycf921244819/article/details/106599489)      * TODO 设置service层所在位置      */     private static final String AOP_POINTCUT_EXPRESSION = "execution (* cn.hjljy.fastboot..*.service..*.*(..))";      /**      * 注入事务管理器      */     @Autowired     private TransactionManager transactionManager;       /**      * 配置事务拦截器      */     @Bean     public TransactionInterceptor txAdvice() {          RuleBasedTransactionAttribute txAttrRequired = new RuleBasedTransactionAttribute();         txAttrRequired.setName("REQUIRED事务");         //设置事务传播机制,默认是PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务         txAttrRequired.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);         //设置异常回滚为Exception  默认是RuntimeException         List rollbackRuleAttributes = new ArrayList<>();         rollbackRuleAttributes.add(new RollbackRuleAttribute(Exception.class));         txAttrRequired.setRollbackRules(rollbackRuleAttributes);          RuleBasedTransactionAttribute txAttrRequiredReadOnly = new RuleBasedTransactionAttribute();         txAttrRequiredReadOnly.setName("SUPPORTS事务");         //设置事务传播机制,PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行         txAttrRequiredReadOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);         //设置异常回滚为Exception  默认是RuntimeException         txAttrRequiredReadOnly.setRollbackRules(rollbackRuleAttributes);         txAttrRequiredReadOnly.setReadOnly(true);          /*事务管理规则,声明具备事务管理的方法名*/         NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();         //方法名规则限制,必须以下列开头才会加入事务管理当中         source.addTransactionalMethod("add*", txAttrRequired);         source.addTransactionalMethod("save*", txAttrRequired);         source.addTransactionalMethod("create*", txAttrRequired);         source.addTransactionalMethod("insert*", txAttrRequired);         source.addTransactionalMethod("submit*", txAttrRequired);         source.addTransactionalMethod("del*", txAttrRequired);         source.addTransactionalMethod("remove*", txAttrRequired);         source.addTransactionalMethod("update*", txAttrRequired);         source.addTransactionalMethod("exec*", txAttrRequired);         source.addTransactionalMethod("set*", txAttrRequired);          //对于查询方法,根据实际情况添加事务管理 可能存在查询多个数据时,已查询出来的数据刚好被改变的情况         source.addTransactionalMethod("get*", txAttrRequiredReadOnly);         source.addTransactionalMethod("select*", txAttrRequiredReadOnly);         source.addTransactionalMethod("query*", txAttrRequiredReadOnly);         source.addTransactionalMethod("find*", txAttrRequiredReadOnly);         source.addTransactionalMethod("list*", txAttrRequiredReadOnly);         source.addTransactionalMethod("count*", txAttrRequiredReadOnly);         source.addTransactionalMethod("is*", txAttrRequiredReadOnly);         return new TransactionInterceptor(transactionManager, source);     }          /**      *  设置切面      */     @Bean     public Advisor txAdviceAdvisor() {         AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();         pointcut.setExpression(AOP_POINTCUT_EXPRESSION);         return new DefaultPointcutAdvisor(pointcut, txAdvice());     } }整合Mybatis-Plus
  第一步:引入JAR包             com.baomidou         mybatis-plus-boot-starter         3.3.2      复制代码
  第二步:添加配置信息mybatis-plus:   mapper-locations: classpath:mapper/*.xml  #xml所在位置  不设置默认是在mapper类同级   configuration:     mapUnderscoreToCamelCase: true  # 开启驼峰匹配  默认为true     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 打印sql语句和入参数据   global-config:     db-config:       logic-delete-value: 1 #逻辑删除  配合@TableLogic注解       logic-not-delete-value: 0 #逻辑不删除       update-strategy: not_null # 更新时字段如果为null,就不进行更新该字段。       insert-strategy: not_null # 插入时如果字段为null,就不插入数据,建议数据库表字段设置默认值
  第三步:添加分页和mapper扫描@Configuration @MapperScan("cn.hjljy.fastboot.mapper") public class MybatisPlusConfiguration {     /**      * mybatis-plus分页插件      */     @Bean     public PaginationInterceptor paginationInterceptor() {         PaginationInterceptor page = new PaginationInterceptor();         //设置分页数据库类型         page.setDbType(DbType.MYSQL);         page.setDialect(new MySqlDialect());         //优化count sql         page.setCountSqlParser(new JsqlParserCountOptimize(true));         //设置每页最大值         page.setLimit(999L);         return page;     } }
  第四步:创建一个Mapper类继承BaseMapper,就可以简单使用了。 可以参考官方文档入门:mp.baomidou.com/guide/quick…整合代码生成器
  AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率
  考虑到dto和po在大部分情况下字段都是一样的,官方未提供DTO,所以可以拷贝一份entity.java.vm修改为dto.java.vm放在resources目录下面。然后根据自定义提示进行修改。 具体结果如下:package $!{cfg.dtoPackage};  #foreach($pkg in ${table.importPackages}) import ${pkg}; #end #if(${swagger2}) import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; #end #if(${entityLombokModel}) import lombok.Data; import lombok.EqualsAndHashCode; #if(${chainModel}) import lombok.experimental.Accessors; #end #end  /**  * 

* $!{table.comment} * * * @author ${author} * @since ${date} */ #if(${entityLombokModel}) @Data #if(${superEntityClass}) @EqualsAndHashCode(callSuper = true) #else @EqualsAndHashCode(callSuper = false) #end #if(${chainModel}) @Accessors(chain = true) #end #end #if(${table.convert}) @TableName("${table.name}") #end #if(${swagger2}) @ApiModel(value="${entity}Dto对象", description="$!{table.comment}") #end #if(${superEntityClass}) public class ${entity}Dto extends ${superEntityClass}#if(${activeRecord})<${entity}>#end { #elseif(${activeRecord}) public class ${entity}Dto extends Model<${entity}> { #else public class ${entity}Dto implements Serializable { #end #if(${entitySerialVersionUID}) private static final long serialVersionUID=1L; #end ## ---------- BEGIN 字段循环遍历 ---------- #foreach($field in ${table.fields}) #if(${field.keyFlag}) #set($keyPropertyName=${field.propertyName}) #end #if("$!field.comment" != "") #if(${swagger2}) @ApiModelProperty(value = "${field.comment}") #else /** * ${field.comment} */ #end #end #if(${field.keyFlag}) ## 主键 #if(${field.keyIdentityFlag}) @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) #elseif(!$null.isNull(${idType}) && "$!idType" != "") @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) #elseif(${field.convert}) @TableId("${field.annotationColumnName}") #end ## 普通字段 #elseif(${field.fill}) ## ----- 存在字段填充设置 ----- #if(${field.convert}) @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) #else @TableField(fill = FieldFill.${field.fill}) #end #elseif(${field.convert}) @TableField("${field.annotationColumnName}") #end ## 乐观锁注解 #if(${versionFieldName}==${field.name}) @Version #end ## 逻辑删除注解 #if(${logicDeleteFieldName}==${field.name}) @TableLogic #end private ${field.propertyType} ${field.propertyName}; #end ## ---------- END 字段循环遍历 ---------- #if(!${entityLombokModel}) #foreach($field in ${table.fields}) #if(${field.propertyType.equals("boolean")}) #set($getprefix="is") #else #set($getprefix="get") #end public ${field.propertyType} ${getprefix}${field.capitalName}() { return ${field.propertyName}; } #if(${chainModel}) public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { #else public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { #end this.${field.propertyName} = ${field.propertyName}; #if(${chainModel}) return this; #end } #end ## --foreach end--- #end ## --end of #if(!${entityLombokModel})-- #if(${entityColumnConstant}) #foreach($field in ${table.fields}) public static final String ${field.name.toUpperCase()} = "${field.name}"; #end #end #if(${activeRecord}) @Override protected Serializable pkVal() { #if(${keyPropertyName}) return this.${keyPropertyName}; #else return null; #end } #end #if(!${entityLombokModel}) @Override public String toString() { return "${entity}{" + #foreach($field in ${table.fields}) #if($!{foreach.index}==0) "${field.propertyName}=" + ${field.propertyName} + #else ", ${field.propertyName}=" + ${field.propertyName} + #end #end "}"; } #end }   具体代码生成器的执行代码如下:public class CodeGenerator { public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("海加尔金鹰(www.hjljy.cn)"); gc.setOpen(false); //设置实体类后缀 gc.setEntityName("%sPo"); //实体属性 Swagger2 注解 gc.setSwagger2(true); gc.setBaseColumnList(true); gc.setBaseResultMap(true); mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/springboot?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true"); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); pc.setModuleName(null); String scanner = scanner("请输入整体业务包名"); String modelName = StringUtils.isBlank(scanner) ? "" : "."+scanner; //moduleName是整体分模块 pc.setParent("cn.hjljy.fastboot"); pc.setMapper("mapper"+modelName); pc.setService("service"+modelName); pc.setServiceImpl("service"+modelName+".impl"); pc.setEntity("pojo"+modelName+".po"); pc.setController("controller"+modelName); mpg.setPackageInfo(pc); String dtoPath = pc.getParent() + ".pojo.dto"; // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 不输出默认的XML 默认生成的xml在mapper层里面 templateConfig.setXml(null); mpg.setTemplate(templateConfig); //配置自定义输出的文件 xml和dto //模板引擎是 velocity String xmlTemplatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(xmlTemplatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/src/main/resources/mapper/" + scanner + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); String dtoTemplatePath = "/dto.java.vm"; // 自定义配置会被优先输出 focList.add(new FileOutConfig(dtoTemplatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/src/main/java/cn/hjljy/fastboot/pojo/"+scanner+"/dto/" + tableInfo.getEntityName() + "Dto" + StringPool.DOT_JAVA; } }); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { Map map = new HashMap<>(); map.put("dtoPackage", dtoPath); this.setMap(map); } }; cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); strategy.setControllerMappingHyphenStyle(true); //设置逻辑删除字段 strategy.setLogicDeleteFieldName("status"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new VelocityTemplateEngine()); mpg.execute(); } /** *

* 读取控制台内容 * */ 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 + "!"); } }总结   算是框架里面非常基础的一些东西。不过能够提高不少的开发效率!!!


卖到供不应求!苹果145元抛光布再上架,是否为智商税?大家是否还记得,苹果在iPhone13系列发布之际,在官网上架了一款售价145元的抛光布。在当时,互联网上一片哗然,大多数用户都在吐槽其价格离谱,毕竟普通的抛光布有个十几块就算贵的饱受批评的19美元苹果抛光布重新上架金融界1月12日消息,苹果公司售价19美元的抛光布因定价过高在互联网上引发愤怒和批评,但现在该产品已重新上市。这款售价19美元的抛光布,可用于苹果公司的任何产品。去年10月该产品刚互联网政务服务助力一流软环境建设来源光明日报习近平总书记在全国网络安全和信息化工作会议上强调,要运用信息化手段推进政务公开党务公开,加快推进电子政务,构建全流程一体化在线服务平台,更好解决企业和群众反映强烈的办事国家广电总局开展短视频专项治理取得实效36氪获悉,据国家广播电视总局微信公众号,国家广播电视总局自去年10月以来,按照中央文娱领域综合治理工作的精神,持续督导抖音快手等10多家用户规模大应用软件使用频率高的短视频平台,活着,就单单为了活着本身活着欢迎关注公众号夜半夏曲这两天看到一个新闻,腾讯游戏开发大神毛星云意外离世。我起初看到这个新闻,以为又是一个过劳死的案例,毕竟互联网大厂996福报的言论还不时回响在耳畔,互联网大厂们新手怎么学好编程?现在IT行业越来越火热,想要学习编程的人越来越多。跨界转行是大多数人面临的问题,不只是编程,其他行业也是如此。学会计转行做编辑学土木工程转行做电子学计算机转行做了编辑学机械转行做程如何在算法岗位脱颖而出?作为一个从业几年,并且做过几年面试官的算法工程师来说,认为最主要的任务还是定义问题和解决问题,所以成为一个合格的算法工程师要求就是不仅有考察建模的能力还要有模型优化的能力。在面向业5G手机选购指南价格从1199到2999,你会选择哪部手机?5G网络的出现,代表着数据连接和传输技术又向前迈进了一步,因此,支持5G连接的智能手机也比其它4G手机更受欢迎。如果你正考虑买5G手机,而且预算在1000到3000之间,那么请继续200元内的好耳机不少,论音质和综合性能脱颖而出的非它莫属如果你说你想买人生中的第一副HIFI耳机,我想你极大可能会花上八百上千,并且从此可能入烧。如果你说你想买一副所谓的HiFi耳机听听歌,我想你的预算也就三百块钱左右,总之不会超过五百低音炮音箱应该如何配置声拓电子音爵士低音炮音箱应该如何配置声拓电子音爵士低音炮音箱也是一种使用于多种场景的音箱,那么低音炮音箱如何配置呢?第一,看场合。使用场合不一样,配置的要求也不一样。比如,作为剧院是要求配置超低有效省电的客厅空调,使用舒适又安心客厅里的空调对于很多人来说都不是非常重要的家电,因为大家总是觉得客厅里的空调比较大,这样容易浪费电,也会给家庭增加更多的开支。其实这个时候我们可以选择新一级能效的空调,不仅能够有效
全球首款音乐阅读器海信TOUCH正式发布开启沉浸听读新时代5月20日,海信举办主题为HiTOUCH的新品发布会,正式推出护眼阅读新产品全球首款音乐阅读器海信TOUCH。凭借行业内首搭四通道环境光传感器与瑞声声学合作,联合瑞典Dirac音效海信TOUCH带你体验更香的高品质音乐相伴的护眼阅读虽然说现在的工作节奏紧张,可仔细盘算一下,独处的时间还是很多的。可偏偏就是在这独处时间里,很多人的娱乐质量并不能达到预期效果。就比如看小说消遣时光,如果有高品质音乐伴奏,那感觉岂不音阅相随生活更美海信TOUCH带你618欢乐畅读喜欢看书的朋友,很多都经历了纸质书籍向电子书的转变,科技发展让阅读工具与时俱进。只是用来看电子书的电子设备存在有害蓝光,眼睛会出现眼干眼涩视力下降等问题,这让我们不得不寻找更健康的翻译总是有偏差?讯飞扫描词典笔专业水准值得信赖学生在学习英语的过程中经常会遇到不会的句子,这时候一般都有两种解决方法一个一个的查询出句子中的生词自我翻译,或者直接将整句话输入到手机中借助相关软件进行翻译,无论是哪一种效率都比较RXR时雾正式发布全新产品线不二,自带IP形象的高端换弹产品4月15日RXR时雾宣布,不二系列换弹电子雾化器正式上线,这是继呆呆系列之后推出的全新旗舰款产品线,采用了包括功率自动切换曝光显影,等边CNC等多个行业首创技术的中高端产品。RXR悦读节海信阅读手机超值福利来袭乐享极致护眼阅读体验数字阅读时代,人们获得信息以及阅读的方式都发生了很大的变化,在更便捷地利用碎片化时间的同时,电子设备带来的蓝光伤害却成了让人头疼的问题。而海信阅读手机从根源出发来为用户提供更舒适护阅读和音乐更般配海信TOUCH疏压悦读好搭档下班后,宅在家里,用海信TOUCH音乐阅读器听着音乐看着书,沉浸在书的海洋里,这种悦耳悦心的美好体验,真是既疏压又解惑。和一般的电子书阅读器不同,海信TOUCH音乐阅读器的音效真的参与地球日的最佳方式普洛斯践行可持续发展江苏常熟,普洛斯正在开发建设总建筑面积15,000平方米的互联网数据中心,为云计算互联网公司金融以及政府和企业客户服务,为长三角地区互联网大数据及人工智能产业发展提供基础设施支持。远景限时优惠高达8000元欢迎垂询福田深圳深意店远景现车限时优惠,可试乘试驾远景现车在店,购车可享多重优惠方案零息方案首付20,2年0息50享3年0息超长期限超低月供方案首付50,每天18元远景带回家附加贷0首付低帝豪GL新能源限时优惠让利高达1。3万深圳深意吉利汽车全系底价促销,恭迎到店品鉴!近期购帝豪GLPHEV优惠政策如下1。现金优享现金优惠13000元,2。金融优享银行贴息4000元,3。置换优享置换补贴7000元,4。海信TOUCH音乐阅读器口袋中的音乐库与藏书阁经常听到这么一句话要么去旅行,要么去读书,身体和灵魂必须有一个在路上。最近小编发现了一款特别适合在路上阅读的神器海信TOUCH音乐阅读器。带着这款阅读音乐器出门,完全无需在背囊中开