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

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


假如鸿蒙失败了华为鸿蒙OS的发布会全程看完了,很激动,中间还卡顿了几次,从刚开始4。2万次播放进入的,到发布会结束时达到了60多万次,而这仅仅是发布会的一个直播入口,有网友吐槽也说挤爆了,可见从鸿蒙OS发布,水波纹扩散绝美!一分钟火速用PPT教你get同款这两天的一件大事儿,就是鸿蒙操作系统和华为全场景新品发布会!这个意思也就是说,鸿蒙手机不再只是国人口中的概念了,而是一款实实在在的产品。我第一时间HarmonyOS的官博,看到置顶开拓儿童智能终端新赛道,展锐成功背后的逻辑每个时代的儿童都有自己的专属玩伴,随着时代的进步和科技的发展,智能终端成为了如今儿童们的好伙伴。在刚刚过去的六一儿童节,国内知名芯片厂商紫光展锐联合一众知名儿童品牌发布了一组海报,马上就发布!一加新品曝光这次不玩旗舰近日,据外媒androidcentral报道,一加官方确认即将推出一款新品,并将其命名为一加NordCE。有消息称,该机屏采用了左上角挖孔曲面屏设计,搭载了6。4英寸的AMOLED鸿蒙系统为什么有的才3个G,我的要5。9G呢?这个嘛,有的手机硬件低端点,用个简化版就行,很多功能推给你那破手机它也带不动反而搞得很卡。有的手机硬件配置高端,就可以全面发挥功能了,就可以用完整版体验更多功能。简单来说就是有钱了华为第一款鸿蒙平板电脑发布售价4999元起2021年6月2日晚,根据多家科技媒体的消息,华为正式发布HarmonyOS2(鸿蒙),这意味着鸿蒙手机已经变成面向市场的正式产品。这个新的操作系统将打通手机电脑平板电视无人驾驶车鸿蒙是什么,和你我有什么关系?鸿蒙是中国对抗西方国家的科技战武器之一,和你我关系就像原子弹,你说中国的原子弹跟我们直接关系基本没有,但是如果中国没有原子弹,那就请你参考一下中东那些活在西方阴影下的国家国民。没什2021年了,荣耀V20怎么样?荣耀V20是2018年12月发布的一款产品,到今天已经快2年半了,其配置上采用麒麟980处理器,6。4英寸LCD挖孔屏,前置2500万像素摄像头,后置4800万像素主摄和TOF景深万物归一华为鸿蒙OS2系统全解本内容来源于什么值得买APP,观点仅代表作者本人作者App发现号今晚的发布会上,华为正式推出了最新的鸿蒙OS2系统,并开始在MateP等多款手机MatePad平板等设备上推送,这标华为鸿蒙系统详解,没看懂或错过发布会的看这篇文章就够了昨晚华为举行了鸿蒙2。0系统的线上发布会,正式版系统发布,将广泛应用于手机电脑平板以及各种家电设备甚至是汽车等等,废话不多说,接下来小麦就带大家来了解以下鸿蒙系统的定位。真正的万物今天华为升级鸿蒙系统的是不是只有那些个内测用户。没其他的?感谢您的阅读!我们发现确实有些人并没有升级到鸿蒙系统。实际上在6月2号开始,华为鸿蒙系统发布会之后,只要符合规定的手机都可以升级到鸿蒙系统。一般来说,华为mate30系列以上的手机
联想官方确认Legion3Pro将使用骁龙898处理器,性能提升20左右联想在中国的智能手机业务总经理陈进发布了关于Legion3Pro的消息,这是一款即将使用骁龙898芯片组(SM8450)的未来游戏旗舰。骁龙895处理器。其已经通过三星4nm工艺的作为一款高性能商务本战66四代持续保持冷静的秘诀是什么?惠普战66四代锐龙版,是近期颇受好评的一款轻薄型笔记本电脑。出色的性价比,良好的性能表现,不错的颜值,观感极佳的屏幕成为用户办公日常休闲娱乐的首选机型之一。对于轻薄型笔记本来说,外iPhone12和iPhone12Pro的性能到底有多大差距Phone12和iPhone12Pro在性能方面的差距并不大,但是4GB运行内存的iPhone12和6GB运行内存的iPhone12Pro,在系统更新周期上,可能会差两个版本。iP实惠好用的蓝牙耳机品牌,学生党无线蓝牙耳机推荐自从推出AirPods后,大家也纷纷将有线耳机换成了真无线蓝牙耳机,作为数码爱好者的学生党自然会被吸引,聚焦到周围就不难发现,有越来越多的年轻人都开始使用真无线耳机了,在这里就推荐比苹果产品更精致的是,它的包装果粉之家,专业苹果手机技术研究十年!您身边的苹果专家每当苹果发售新品时,网上就会出现大量相关开箱评测视频,而每一则爆火视频的背后都是清一色的苹果新品讲解视频。不过,近日YouTub5G基带芯片越来越便宜,4G芯片价格逆势走高,5G被市场倒逼欧界欧界报道随着缺芯潮在全球范围内的肆虐又退却后,其留下了不少负面影响,其中就包括手机等数码产品汽车产品以及各类急需芯片的行业无法实现正常的更新换代,成本也陡然上升。似乎缺芯潮带来的影简单合并收款码,一码收款方便快捷大家好,现在现金付款已经慢慢介绍,更多的是线上网上支付,很多的商贩店铺等,为了方便顾客付款,使用微信支付宝收款码,但是单独下载的收款码只能支持一方收款,为所以很多店铺使用合并的收款腾讯绞杀抖音,不止1个亿作者小满编辑原野风暴掀起时,总会掀起一片模糊黑白边界的混沌。只有拨开它们,世人才可能窥见纷争的本质。这并不容易。热播剧扫黑风暴,正在溢出时空边界,于商业世界中卷起更激烈的风暴腾讯起自己安装充电桩的流程现如今电动汽车已经在我们的生活中非常常见了,并且在未来一定是新能源汽车的天下。那么很多网友会有这些疑问买新能源车我们充电怎么办呢?哪些电动车送充电桩?哪些车电动车又不送充电桩呢?在4G用不久了?工信部官方回应来了如今已经是科技的时代,我们身边的许多东西都在以非常快的速度更换着,时代在不同的推陈出新,想当年诺基亚辉煌一时,却在两年间就被安卓系统所淘汰掉,而如今我们也在面临着4G和5G之间的升知乎国家何时整治程序员的高薪现象?太可怕了点击开发者技术前线,选择关注让一部分开发者看到未来作者可可开发者技术前线原创随着阿里女员工被侵害事件的持续发酵,码农渐渐被大家知晓。自从网友们知道了互联网公司员工的待遇之后,大家抨