外贸人常用的网站南召微网站建设

当前位置: 首页 > news >正文

外贸人常用的网站,南召微网站建设,电子信息工程论坛,潍坊市网站优化前言 最近有个想法想整理一个内容比较完整springboot项目初始化Demo。 连接Oracle数据库集成mybatis-plus#xff0c;自定义WrapperFactory。配置代码生成器 一、引入jar包 !–oracle驱动 –dependencygroupIdorg.springframework.boot/groupI…前言 最近有个想法想整理一个内容比较完整springboot项目初始化Demo。 连接Oracle数据库集成mybatis-plus自定义WrapperFactory。配置代码生成器 一、引入jar包 !–oracle驱动 –dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependencygroupIdcom.oracle.ojdbc/groupIdartifactIdojdbc8/artifactIdversion19.3.0.0/version/dependency!– oracle8 所需的字符集 –dependencygroupIdcn.easyproject/groupIdartifactIdorai18n/artifactIdversion12.1.0.2.0/version/dependency!–mybatis-plus–dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.1/version/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-generator/artifactIdversion3.5.1/version/dependencydependencygroupIdorg.freemarker/groupIdartifactIdfreemarker/artifactIdversion2.3.28/version/dependency!–mybatis-plus– 二、新建配置文件application-dev.yaml 以根据不同的环境配置不同的属性文件application-{profile} 表示环境名称。 例如application-dev.yaml用于开发环境application-prod.yaml用于生产环境。 增加数据库配置 hikari连接池配置 spring:datasource:driver-class-name: oracle.jdbc.OracleDriverurl: jdbc:oracle:thin://127.0.0.1:1521/orclusername: murg_demopassword: 654321hikari:connection-test-query: SELECT 1 FROM DUALminimum-idle: 10maximum-pool-size: 50idle-timeout: 120000max-lifetime: 180000connection-timeout: 18000 logging:level:org.springframework.security: debug 启动服务看服务是否正常启动 三、自定义MyBatis 构造对象加工厂。 用于规定查询返回值格式 主要用于处理和字段大小写规定 package com.murg.bootdemo.interceptor;import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.wrapper.ObjectWrapper; import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory; import java.util.Map;/*** 自定义ObjectWrapperFactory 结果处理 去除 字段大写转小写/ public class MapWrapperFactory implements ObjectWrapperFactory {Overridepublic boolean hasWrapperFor(Object object) {return object instanceof Map;}Overridepublic ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {return new MyMapWrapper(metaObject,(Map)object);} }package com.murg.bootdemo.interceptor;import org.apache.commons.lang3.math.NumberUtils; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.wrapper.MapWrapper;import java.util.Map;/** mybatis 结果处理 去除_ 字段大写转小写/ public class MyMapWrapper extends MapWrapper {public MyMapWrapper(MetaObject metaObject, MapString, Object map) {super(metaObject, map);}Overridepublic String findProperty(String name, boolean useCamelCaseMapping) {if (useCamelCaseMapping ((name.charAt(0) A name.charAt(0) Z)|| name.contains(_))) {return underlineToCamelhump(name);}return name;}/** 将下划线风格替换为驼峰风格* param inputString* return/public String underlineToCamelhump(String inputString) {StringBuilder sb new StringBuilder();boolean nextUpperCase false;for (int i 0; i inputString.length(); i) {char c inputString.charAt(i);if (c ) {if (sb.length() 0) {nextUpperCase true;}} else {if (nextUpperCase) {if (NumberUtils.isNumber(String.valueOf©)) {sb.append().append©;} else {sb.append(Character.toUpperCase©);}nextUpperCase false;} else {sb.append(Character.toLowerCase©);}}}return sb.toString();} }四、自定义WrapperFactoryConverter 以上配置好WrapperFactory后启动会报错 提示找不到合适的converter将string转化为ObjectWrapperFactory对象 缺少对应的converterspringboot不会提供反射机制来构建一个对象的converter需要手写一个 package com.murg.bootdemo.interceptor;import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component;Component ConfigurationPropertiesBinding public class ObjectWrapperFactoryConverter implements ConverterString, ObjectWrapperFactory {Overridepublic ObjectWrapperFactory convert(String source) {try {return (ObjectWrapperFactory) Class.forName(source).newInstance();} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {throw new RuntimeException(e);}} }五、整合MyBatisPlus代码生成器 mybatis-plus-generator配合freemaker引擎 5.1下面这些文件直接创建在resources/generator1/templates的目录下把内容复制进去就行了。这些文件就是代码生成的格式模板。 controller.java.ftl package \({package.Controller};import org.springframework.web.bind.annotation.RequestMapping;#if restControllerStyle import org.springframework.web.bind.annotation.RestController; #else import org.springframework.stereotype.Controller; /#if #if superControllerClassPackage?? import \){superControllerClassPackage}; /#if/** p* \({table.comment!} 前端控制器* /p** author \){author}* since \({date}*/ #if restControllerStyle RestController #else Controller /#if RequestMapping(#if package.ModuleName?? package.ModuleName ! /\){package.ModuleName}/#if/#if controllerMappingHyphenStyle??\({controllerMappingHyphen}#else\){table.entityPath}/#if) #if kotlin class \({table.controllerName}#if superControllerClass?? : \){superControllerClass}()/#if #else #if superControllerClass?? public class \({table.controllerName} extends \){superControllerClass} { #else public class \({table.controllerName} { /#if} /#ifentity.java.ftl package \){package.Entity};#list table.importPackages as pkg import \({pkg}; /#list #if swagger import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /#if #if entityLombokModel import lombok.Getter; import lombok.Setter;#if chainModel import lombok.experimental.Accessors;/#if /#if/*** p* \){table.comment!}* /p** author \({author}* since \){date}/ #if entityLombokModel Getter Setter#if chainModel Accessors(chain true)/#if /#if #if table.convert TableName(\({schemaName}\){table.name}) /#if #if swagger ApiModel(value \({entity}对象, description \){table.comment!}) /#if #if superEntityClass?? public class \({entity} extends \){superEntityClass}#if activeRecord\({entity}/#if { #elseif activeRecord public class \){entity} extends Model\({entity} { #elseif entitySerialVersionUID public class \){entity} implements Serializable { #else public class \({entity} { /#if #if entitySerialVersionUIDprivate static final long serialVersionUID 1L; /#if #-- ---------- BEGIN 字段循环遍历 ---------- #list table.fields as field#if field.keyFlag#assign keyPropertyName\){field.propertyName}//#if#if field.comment!?length gt 0#if swaggerApiModelProperty(${field.comment})#else/** \({field.comment}*//#if/#if#if field.keyFlag#-- 主键 --#if field.keyIdentityFlagTableId(value \){field.annotationColumnName}, type IdType.AUTO)#elseif idType??TableId(value \({field.annotationColumnName}, type IdType.\){idType})#elseif field.convertTableId(\({field.annotationColumnName})/#if#-- 普通字段 --#elseif field.fill??#-- ----- 存在字段填充设置 -----#if field.convertTableField(value \){field.annotationColumnName}, fill FieldFill.\({field.fill})#elseTableField(fill FieldFill.\){field.fill})/#if#elseif field.convertTableField(\({field.annotationColumnName})/#if#-- 乐观锁注解 --#if field.versionFieldVersion/#if#-- 逻辑删除注解 --#if field.logicDeleteFieldTableLogic/#ifprivate \){field.propertyType} \({field.propertyName}; /#list #------------ END 字段循环遍历 ----------#if !entityLombokModel#list table.fields as field#if field.propertyType boolean#assign getprefixis/#else#assign getprefixget//#ifpublic \){field.propertyType} \({getprefix}\){field.capitalName}() {return \({field.propertyName};}#if chainModelpublic \){entity} set\({field.capitalName}(\){field.propertyType} \({field.propertyName}) {#elsepublic void set\){field.capitalName}(\({field.propertyType} \){field.propertyName}) {/#ifthis.\({field.propertyName} \){field.propertyName};#if chainModelreturn this;/#if}/#list /#if#if entityColumnConstant#list table.fields as fieldpublic static final String \({field.name?upper_case} \){field.name};/#list /#if #if activeRecordOverridepublic Serializable pkVal() {#if keyPropertyName??return this.\({keyPropertyName};#elsereturn null;/#if}/#if #if !entityLombokModelOverridepublic String toString() {return \){entity}{ #list table.fields as field#if field_index0\({field.propertyName} \){field.propertyName} #else, \({field.propertyName} \){field.propertyName} /#if/#list};} /#if }entity.kt.ftl package \({package.Entity}#list table.importPackages as pkg import \){pkg} /#list #if swagger import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /#if/*** p* \({table.comment}* /p** author \){author}* since \({date}*/ #if table.convert TableName(\){schemaName}\({table.name}) /#if #if swagger ApiModel(value \){entity}对象, description \({table.comment!}) /#if #if superEntityClass?? class \){entity} : \({superEntityClass}#if activeRecord\){entity}/#if { #elseif activeRecord class \({entity} : Model\){entity}() { #elseif entitySerialVersionUID class \({entity} : Serializable { #else class \){entity} { /#if#– ———- BEGIN 字段循环遍历 ———- #list table.fields as field #if field.keyFlag#assign keyPropertyName\({field.propertyName}/ /#if #if field.comment!?length gt 0 #if swaggerApiModelProperty(\){field.comment}) #else/*** \({field.comment}*/ /#if /#if #if field.keyFlag #-- 主键 -- #if field.keyIdentityFlagTableId(value \){field.annotationColumnName}, type IdType.AUTO) #elseif idType ??TableId(value \({field.annotationColumnName}, type IdType.\){idType}) #elseif field.convertTableId(\({field.annotationColumnName}) /#if #-- 普通字段 -- #elseif field.fill?? #-- ----- 存在字段填充设置 ----- #if field.convertTableField(value \){field.annotationColumnName}, fill FieldFill.\({field.fill}) #elseTableField(fill FieldFill.\){field.fill}) /#if #elseif field.convertTableField(\({field.annotationColumnName}) /#if #-- 乐观锁注解 -- #if field.versionFieldVersion /#if #-- 逻辑删除注解 -- #if field.logicDeleteFieldTableLogic /#if#if field.propertyType Integervar \){field.propertyName}: Int? null#elsevar \({field.propertyName}: \){field.propertyType}? null/#if/#list #– ———- END 字段循环遍历 ———- #if entityColumnConstantcompanion object { #list table.fields as fieldconst val \({field.name?upper_case} : String \){field.name}/#list}/#if #if activeRecordoverride fun pkVal(): Serializable? { #if keyPropertyName??return \({keyPropertyName} #elsereturn null /#if}/#ifoverride fun toString(): String {return \){entity}{ #list table.fields as field #if field_index0\({field.propertyName} \){field.propertyName} #else, \({field.propertyName} \){field.propertyName} /#if /#list}} }mapper.java.ftl package \({package.Mapper};import \){package.Entity}.\({entity}; import \){superMapperClassPackage}; #if mapperAnnotation import org.apache.ibatis.annotations.Mapper; /#if/*** p* \({table.comment!} Mapper 接口* /p** author \){author}* since \({date}*/ #if mapperAnnotation Mapper /#if #if kotlin interface \){table.mapperName} : \({superMapperClass}\){entity} #else public interface \({table.mapperName} extends \){superMapperClass}\({entity} {} /#ifmapper.xml.ftl ?xml version1.0 encodingUTF-8? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespace\){package.Mapper}.\({table.mapperName}#if enableCache!-- 开启二级缓存 --cache type\){cacheClassName}//#if #if baseResultMap!– 通用查询映射结果 –resultMap idBaseResultMap type\({package.Entity}.\){entity} #list table.fields as field #if field.keyFlag#–生成主键排在第一位–id column\({field.name} property\){field.propertyName} / /#if /#list #list table.commonFields as field#–生成公共字段 –result column\({field.name} property\){field.propertyName} / /#list #list table.fields as field #if !field.keyFlag#–生成普通字段 –result column\({field.name} property\){field.propertyName} / /#if /#list/resultMap/#if #if baseColumnList!– 通用查询结果列 –sql idBase_Column_List #list table.commonFields as field\({field.columnName}, /#list\){table.fieldNames}/sql/#if /mapperservice.java.ftl package \({package.Service};import \){package.Entity}.\({entity}; import \){package.Mapper}.\({table.mapperName}; import \){superServiceImplClassPackage}; import org.springframework.stereotype.Service;/**

  • p* ${table.comment!} 服务实现类* /p *
  • author ${author}
  • since \({date} */ Service public class \){table.serviceImplName} extends \({superServiceImplClass}\){table.mapperName}, ${entity} {}5.2创建生成代码类CodeGenerator  package com.murg.bootdemo.util;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.config.ConstVal; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.TemplateType; import com.baomidou.mybatisplus.generator.config.rules.DateType; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import org.apache.commons.lang3.StringUtils;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Collections; import java.util.List;/*** Generator生成代码/ public class CodeGenerator {public static void main(String[] args) {generator();}public static void generator() {final String[] moduleName new String[1];FastAutoGenerator.create(new DataSourceConfig.Builder(jdbc:oracle:thin://127.0.0.1:1521/orcl,murg_test,654321))// 全局配置.globalConfig((scanner, builder) - builder.author(StringUtils.defaultString(getGitUsername(), codeGenerator)).fileOverride().outputDir(System.getProperty(user.dir) /src/main/java).disableOpenDir().enableSwagger().dateType(DateType.ONLY_DATE))// 包配置.packageConfig((scanner, builder) - builder.parent(com.murg.bootdemo. scanner.apply(请输入包名从 com.murg.bootdemo. 开始 )).xml(mapper).serviceImpl(service)).templateConfig((builder - builder.disable(TemplateType.SERVICE, TemplateType.CONTROLLER).serviceImpl(/templates/service.java)))// 策略配置.strategyConfig((scanner, builder) - builder.addInclude(getTables(scanner.apply(请输入表名多个英文逗号分隔所有输入 all).toUpperCase())).controllerBuilder().enableRestStyle().enableHyphenStyle().serviceBuilder().convertServiceImplFileName((entityName - entityName ConstVal.SERVICE)).entityBuilder().enableLombok().idType(IdType.INPUT).build()).templateEngine(new FreemarkerTemplateEngine())//.addIgnoreColumns(prseno) 排除某个字段.execute();}private static String getGitUsername() {Runtime runtime Runtime.getRuntime();Process exec;try {exec runtime.exec(git config user.name);} catch (IOException e) {e.printStackTrace();return null;}InputStreamReader inputStreamReader new InputStreamReader(exec.getInputStream());BufferedReader bufferedReader new BufferedReader(inputStreamReader);try {return bufferedReader.readLine();} catch (IOException e) {e.printStackTrace();return null;}}// 处理 all 情况protected static ListString getTables(String tables) {return all.equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(,));} }5.3运行CodeGenerator 生成代码 点击左侧按钮 运行main方法控制台输出内容 按照控制台输出内容输入包名和表名多个表名用英文逗号分隔会在输入的包下生成文件 六、测试服务数据库连接 获取TT26相关数据 6.1启动类增加注解MapperScan 指定mapper扫描位置 MapperScan(com.murg.bootdemo..mapper) package com.murg.bootdemo;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cache.annotation.EnableCaching;MapperScan(com.murg.bootdemo.*.mapper) SpringBootApplication public class BootdemoApplication {public static void main(String[] args) {SpringApplication.run(BootdemoApplication.class, args);}} 6.2创建测试接口controller 引入Tt26Service 调用getOne方法查询数据库获取Tt26数据 getOne方法为MyBatis-Plus 通用IService使用不了解的同学可以了解一下MyBatis-Plus用法。 package com.murg.bootdemo.business.controller; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.murg.bootdemo.business.entity.Tt26; import com.murg.bootdemo.business.service.Tt26Service; import com.murg.bootdemo.common.WebResult; import lombok.RequiredArgsConstructor; import org.springframework.http.; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; import java.util.HashMap; import java.util.Map;RequiredArgsConstructor RestController public class TestRestController {private final RestTemplate restTemplate;private final Tt26Service tt26Service;RequestMapping(value /getTt26, method RequestMethod.GET)public Tt26 getTt26(RequestParam String code){//通过不同的id获取不同的namereturn tt26Service.getOne(Wrappers.Tt26lambdaQuery().eq(Tt26::getCode,code))}}启动服务访问接口测试结果