zoukankan      html  css  js  c++  java
  • Mybitis根据工具类反射数据库生成映射+整合springboot

    一 反向生成数据库mapper的工具类:

      添加依赖

    <dependency>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-core</artifactId>
                <scope>test</scope>
                <version>1.3.2</version>
                <optional>true</optional>
            </dependency>
    
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.5</version>
            </dependency>
    
    
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.1</version>
            </dependency>

       工具类

    package org.mybatis.generator.plugins;
    
    import org.mybatis.generator.api.IntrospectedTable;
    import org.mybatis.generator.api.PluginAdapter;
    import org.mybatis.generator.api.dom.java.*;
    import org.mybatis.generator.api.dom.xml.Attribute;
    import org.mybatis.generator.api.dom.xml.TextElement;
    import org.mybatis.generator.api.dom.xml.XmlElement;
    
    import java.util.List;
    
    public class AddLimitOffsetPlugin extends PluginAdapter {
    
        public boolean validate(List<String> warnings) {
            return true;
        }
    
        public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
                IntrospectedTable introspectedTable) {
            FullyQualifiedJavaType offsetType = new FullyQualifiedJavaType(
                    "javax.annotation.Generated");
            topLevelClass.addImportedType(offsetType);
            topLevelClass.addAnnotation("@Generated("" + introspectedTable.getTableConfiguration().getTableName() + "")");
             PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper();
             
            Field limit = new Field();
            limit.setName("limit");
            limit.setVisibility(JavaVisibility.PRIVATE);
            limit.setType(integerWrapper);
            topLevelClass.addField(limit);
    
            Method limitSet = new Method();
            limitSet.setVisibility(JavaVisibility.PUBLIC);
            limitSet.setName("setLimit");
            limitSet.addParameter(new Parameter(integerWrapper, "limit"));
            limitSet.addBodyLine("this.limit = limit;");
            topLevelClass.addMethod(limitSet);
    
            Method limitGet = new Method();
            limitGet.setVisibility(JavaVisibility.PUBLIC);
            limitGet.setReturnType(integerWrapper);
            limitGet.setName("getLimit");
            limitGet.addBodyLine("return limit;");
            topLevelClass.addMethod(limitGet);
    
            Field offset = new Field();
            offset.setName("offset");
            offset.setVisibility(JavaVisibility.PRIVATE);
            offset.setType(integerWrapper);
            topLevelClass.addField(offset);
    
            Method offsetSet = new Method();
            offsetSet.setVisibility(JavaVisibility.PUBLIC);
            offsetSet.setName("setOffset");
            offsetSet.addParameter(new Parameter(integerWrapper, "offset"));
            offsetSet.addBodyLine("this.offset = offset;");
            topLevelClass.addMethod(offsetSet);
    
            Method offsetGet = new Method();
            offsetGet.setVisibility(JavaVisibility.PUBLIC);
            offsetGet.setReturnType(integerWrapper);
            offsetGet.setName("getOffset");
            offsetGet.addBodyLine("return offset;");
            topLevelClass.addMethod(offsetGet);
    
            return true;
        }
    
        public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(
                XmlElement element, IntrospectedTable introspectedTable) {
            XmlElement isNotNullElement = new XmlElement("if");
            isNotNullElement.addAttribute(new Attribute("test", "limit > 0"));
            isNotNullElement.addElement(new TextElement("limit ${limit}"));
            element.getElements().add(isNotNullElement);
    
            isNotNullElement = new XmlElement("if");
            isNotNullElement.addAttribute(new Attribute("test", "offset > 0"));
            isNotNullElement.addElement(new TextElement("offset ${offset}"));
            element.getElements().add(isNotNullElement);
            return true;
        }
    
    }
    package org.mybatis.generator.plugins;
    
    import org.apache.commons.io.IOUtils;
    import org.junit.Test;
    import org.mybatis.generator.api.MyBatisGenerator;
    import org.mybatis.generator.api.ProgressCallback;
    import org.mybatis.generator.config.Configuration;
    import org.mybatis.generator.config.Context;
    import org.mybatis.generator.config.xml.ConfigurationParser;
    import org.mybatis.generator.internal.DefaultShellCallback;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * mybatis代码生成插件调用者.
     */
    public class Generator {
    
        @Test
        public void generate() throws Exception {
            List<String> warnings = new ArrayList<String>();
            boolean overwrite = true;
    
            InputStream stream = Generator.class.getClassLoader().getResourceAsStream("generatorConfig.xml");
    
            ConfigurationParser cp = new ConfigurationParser(warnings);
            InputStreamReader reader = new InputStreamReader(stream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(reader);
    
            String line = bufferedReader.readLine();
            StringBuffer buffer = new StringBuffer();
            while (line != null) {
                buffer.append(line + "
    ");
                line = bufferedReader.readLine();
            }
            String xmlWithParam = buffer.toString();
            
            System.out.println("------- xml config begin -------");
            System.out.println(xmlWithParam);
            System.out.println("------- xml config end -------");
    
            final Configuration config = cp.parseConfiguration(new ByteArrayInputStream(xmlWithParam.getBytes("utf-8")));
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
            System.out.println("------- generator begin -------");
            ProgressCallback cb = new ProgressCallback() {
                private Pattern SqlProviderPattern = Pattern.compile("\w*SqlProvider\.java");
                private List<String> taskNames = new ArrayList();
    
                @Override
                public void startTask(String taskName) {
                    /*
                     * 输出这些信息从而知道 生成那些类了 
                    * Generating Example class for table demo
                    * Generating Primary Key class for table demo 
                    * Generating Record class for table demo 
                    * Generating Mapper Interface for table demo 
                    * Generating SQL Provider for table demo 
                    * Saving file DemoExample.java
                    * Saving file DemoKey.java Saving file Demo.java
                    * Saving file DemoMapper.java
                    * Saving file DemoSqlProvider.java
                     */
                    // System.out.println(taskName);
                    taskNames.add( taskName);
                }
    
                @Override
                public void saveStarted(int arg0) {}
    
                @Override
                public void introspectionStarted(int arg0) {}
    
                @Override
                public void generationStarted(int arg0) {}
    
                @Override
                public void done() {
                    for(String taskName : taskNames){
                    Matcher matcher = SqlProviderPattern.matcher(taskName);
                        if (matcher.find()) {
                            final String SqlProviderFilename = matcher.group();
                            System.out.println("处理生成文件,selectByExample  增加mysql分页: " + SqlProviderFilename);
                            List<Context> contexts = config.getContexts();
                            FilenameFilter filter = new FilenameFilter() {
                                @Override
                                public boolean accept(File dir, String name) {
                                    return SqlProviderFilename.equalsIgnoreCase(name);
                                }
                            };
                            boolean done = false;
                            for (Context ctx : contexts) {
                                if(done){
                                    break;
                                }
                                String targetProject = ctx.getJavaClientGeneratorConfiguration().getTargetProject();
                                String targetPackage = ctx.getJavaClientGeneratorConfiguration().getTargetPackage();
                                String dir = targetProject.replaceAll("\.", "\\") + "\" + targetPackage.replaceAll("\.", "\\");
                                System.out.println(System.getProperty("user.dir") + dir);
                                File mapperDir = new File(System.getProperty("user.dir"), dir);
                                File[] files = mapperDir.listFiles(filter);
                                if (files != null && files.length > 0) {
                                    File sqlProviderFile = files[0];
                                    try {
                                        Generator.addMysqlLimit(sqlProviderFile);
                                        done = true;
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                            if(!done){
                                 System.out.println("转换失败!!!! selectByExample  增加mysql分页: " + SqlProviderFilename);
                            } else {
                                System.out.println("转换成功!!!! selectByExample  增加mysql分页: " + SqlProviderFilename);
                            }
                        }
                    }
                }
    
                @Override
                public void checkCancel() throws InterruptedException {}
            };
            myBatisGenerator.generate(cb);
            for (String warning : warnings) {
                System.out.println(warning);
            }
            System.out.println("------- generator end -------");
            // System.out.println(config.getClassPathEntries());
        }
    
        private static void addMysqlLimit(File sqlProviderFile) throws Exception {
            /*
             * 这是自动生成的selectByExample 中的代码片段
            if (example != null && example.getOrderByClause() != null) {
                ORDER_BY(example.getOrderByClause()); // 整个文件唯一
            }
            
            return SQL();
            
             * 将return SQL()改为下面片段即可:
    
            String sqlString = SQL();
            if (example != null && example.getLimit() != null) {
                sqlString += " limit " + example.getLimit();
            }
            if (example != null && example.getOffset() != null) {
                sqlString += " offset " + example.getOffset();
            }
            return sqlString;
             */
            BufferedReader reader = new BufferedReader( new FileReader(sqlProviderFile));
            List<String> lines = IOUtils.readLines(reader);
            reader.close();
            String limitString = "        String sqlString = SQL();
    " +
                    "        if (example != null && example.getLimit() != null) {
    " +
                    "            sqlString += " limit " + example.getLimit();
    " +
                    "        }
    " +
                    "        if (example != null && example.getOffset() != null) {
    " +
                    "            sqlString += " offset " + example.getOffset();
    " +
                    "        }
    " +
                    "        return sqlString;";
            ArrayList<String> newLines = new ArrayList<String>();
    
            
            for (int i=0; i< lines.size();++i) {
                String line = lines.get(i);
                newLines.add(line );
                if(line.replaceAll(" ", "") .equalsIgnoreCase("ORDER_BY(example.getOrderByClause());")) {
                    // 添加下一行大括号和空白行
                    ++i;
                    newLines.add(lines.get(i));
                    ++i;
                    newLines.add(lines.get(i));
                    
                    ++i; // 跳过 return SQL();
                    newLines.addAll(Arrays.asList( limitString.split("
    ")));
                }
            }
            
    //        for (String line : newLines) {
    //            System.out.println(line);
    //        }
            FileOutputStream writer = new FileOutputStream(sqlProviderFile);
            IOUtils.writeLines(newLines, "
    ",writer,"UTF-8");
            writer.close();
        }
        
        public static void main(String[] args) throws Exception {
           new Generator().generate();
        }
    }

      映射关系配置xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
    <generatorConfiguration>
    
        <context id="entmobile" targetRuntime="MyBatis3">
    
            <plugin type="org.mybatis.generator.plugins.AddLimitOffsetPlugin" />
            <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
    
            <commentGenerator>
                <property name="suppressDate" value="true" />
                <!-- remove comments -->
                <property name="suppressAllComments" value="true" />
            </commentGenerator>
             
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/demo?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"
                userId="root" password="root" />
                
            <!-- java type resolver -->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false" />
            </javaTypeResolver>
    
            <!-- gem entity -->
            <!-- data -->
            <javaModelGenerator targetPackage="com.自己建的实体类包.domain"
                targetProject="./src/main/java">
                <property name="enableSubPackages" value="true" />
                <property name="trimStrings" value="false" />
            </javaModelGenerator>
             
            <!-- //////////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
            <!-- gem annotated mapper -->
            <!-- data -->
            <javaClientGenerator type="ANNOTATEDMAPPER"
                targetPackage="com.自己建的mapper包.mapper"
                targetProject="./src/main/java">
                <property name="enableSubPackages" value="true" />
            </javaClientGenerator>
            
            
            <!--  
            <table tableName="material_type">
                <generatedKey column="id" sqlStatement="JDBC"/>
            </table>
            -->
    
            <table tableName="表名">
                <generatedKey column="id" sqlStatement="JDBC"/>
            </table>
    
    
    
    
        </context>
    </generatorConfiguration>

    另外springboot启动类中添加注解:

      @EnableAutoConfiguration 

    二 数据库配置 application.yml:

    spring:
      datasource:
          url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&connectTimeout=3000&socketTimeout=1000
          username: root           # 自己修改填写
          password: root         # 自己修改填写
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.jdbc.Driver
          minIdle: 5
          maxActive: 100
          initialSize: 10
          maxWait: 60000
          timeBetweenEvictionRunsMillis: 60000
          minEvictableIdleTimeMillis: 300000
          validationQuery: select 'x'
          testWhileIdle: true
          testOnBorrow: false
          testOnReturn: false
          poolPreparedStatements: true
          maxPoolPreparedStatementPerConnectionSize: 50
          removeAbandoned: true
          filters: stat # ,wall,log4j # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
          connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
          useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
          druidLoginName: wjf # 登录druid的账号
          druidPassword: wjf # 登录druid的密码
          cachePrepStmts: true  # 开启二级缓存
      redis:
             database: 0
             host: XX.XX.XX.XX
             port: 6380
             password: 1234567
      activemq:
          broker-url: tcp://XX.XX.XX.XX:61616
          user: admin
          password: zhangjiawen
          pool:
            enabled: true
            max-connections: 100
    mybatis:
       typeAliasesPackage: com.concurrent.mapper # 自己修改填写
       mapperLocations: classpath:/com/concurrent/mapper/*.xml
       mapperScanPackage: com.concurrent.mapper
       configLocation: classpath:/mybatis-config.xml

       mybatis-config.xml:

    <?xml version="1.0" encoding="UTF-8"?>  
    <!DOCTYPE configuration  
         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
         "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <settings>
            <!-- 使全局的映射器启用或禁用缓存。 -->
            <setting name="cacheEnabled" value="true" />
            <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
            <setting name="lazyLoadingEnabled" value="true" />
            <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->        
             <setting name="aggressiveLazyLoading" value="true"/>        
             <!-- 是否允许单条sql 返回多个数据集  (取决于驱动的兼容性) default:true -->
            <setting name="multipleResultSetsEnabled" value="true" />
            <!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
            <setting name="useColumnLabel" value="true" />
            <!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。  default:false  -->
            <setting name="useGeneratedKeys" value="false" />
            <!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分  FULL:全部  -->
            <setting name="autoMappingBehavior" value="PARTIAL" />
            <!-- 这是默认的执行类型  (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新)  -->
            <setting name="defaultExecutorType" value="SIMPLE" />
            
            <setting name="defaultStatementTimeout" value="25" />
            
            <setting name="defaultFetchSize" value="100" />
            
            <setting name="safeRowBoundsEnabled" value="false" />
            <!-- 使用驼峰命名法转换字段。 -->
            <setting name="mapUnderscoreToCamelCase" value="true" />
            <!-- 设置本地缓存范围 session:就会有数据的共享  statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
            <setting name="localCacheScope" value="SESSION" />
            <!-- 默认为OTHER,为了解决oracle插入null报错的问题要设置为NULL -->
            <setting name="jdbcTypeForNull" value="NULL" />
            <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />
        </settings>
        
    </configuration>
     

    另外还有将mapper数据映射加入spring扫描

    package com.concurrent.service;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import com.alibaba.druid.support.http.StatViewServlet;
    import com.alibaba.druid.support.http.WebStatFilter;
    import org.mybatis.spring.annotation.MapperScan;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
    
    import javax.sql.DataSource;
    import java.sql.SQLException;
    
    
    /**
     * Created  on 2016/10/25 0025.
     */
    
    @Configuration
    @MapperScan("com.自己建的映射包.mapper")
    @EnableRedisHttpSession(maxInactiveIntervalInSeconds= 50)
    public class DataSourceConfig {
        private Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);
    
        @Value("${spring.datasource.url}")
        private String dbUrl;
    
        @Value("${spring.datasource.type}")
        private String dbType;
    
        @Value("${spring.datasource.username}")
        private String username;
    
        @Value("${spring.datasource.password}")
        private String password;
    
        @Value("${spring.datasource.driver-class-name}")
        private String driverClassName;
    
        @Value("${spring.datasource.initialSize}")
        private int initialSize;
    
        @Value("${spring.datasource.minIdle}")
        private int minIdle;
    
        @Value("${spring.datasource.maxActive}")
        private int maxActive;
    
        @Value("${spring.datasource.maxWait}")
        private int maxWait;
    
        @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
        private int timeBetweenEvictionRunsMillis;
    
        @Value("${spring.datasource.minEvictableIdleTimeMillis}")
        private int minEvictableIdleTimeMillis;
    
        @Value("${spring.datasource.validationQuery}")
        private String validationQuery;
    
        @Value("${spring.datasource.testWhileIdle}")
        private boolean testWhileIdle;
    
        @Value("${spring.datasource.testOnBorrow}")
        private boolean testOnBorrow;
    
        @Value("${spring.datasource.testOnReturn}")
        private boolean testOnReturn;
    
        @Value("${spring.datasource.poolPreparedStatements}")
        private boolean poolPreparedStatements;
    
        @Value("${spring.datasource.filters}")
        private String filters;
    
        @Value("${spring.datasource.connectionProperties}")
        private String connectionProperties;
    
        @Value("${spring.datasource.useGlobalDataSourceStat}")
        private boolean useGlobalDataSourceStat;
    
        @Value("${spring.datasource.druidLoginName}")
        private String druidLoginName;
    
        @Value("${spring.datasource.druidPassword}")
        private String druidPassword;
    
        @Bean(name="dataSource",destroyMethod = "close", initMethod="init")
        @Primary //不要漏了这
        public DataSource dataSource(){
            DruidDataSource datasource = new DruidDataSource();
            try {
                datasource.setUrl(this.dbUrl);
                datasource.setDbType(dbType);
                datasource.setUsername(username);
                datasource.setPassword(password);
                datasource.setDriverClassName(driverClassName);
                datasource.setInitialSize(initialSize);
                datasource.setMinIdle(minIdle);
                datasource.setMaxActive(maxActive);
                datasource.setMaxWait(maxWait);
                datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
                datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
                datasource.setValidationQuery(validationQuery);
                datasource.setTestWhileIdle(testWhileIdle);
                datasource.setTestOnBorrow(testOnBorrow);
                datasource.setTestOnReturn(testOnReturn);
                datasource.setPoolPreparedStatements(poolPreparedStatements);
                datasource.setFilters(filters);
            } catch (SQLException e) {
                logger.error("druid configuration initialization filter", e);
            }
            return datasource;
        }
    
        /////////  下面是druid 监控访问的设置  /////////////////
        @Bean
        public ServletRegistrationBean druidServlet() {
            ServletRegistrationBean reg = new ServletRegistrationBean();
            reg.setServlet(new StatViewServlet());
            reg.addUrlMappings("/druid/*");  //url 匹配
            reg.addInitParameter("allow", "192.168.16.110,127.0.0.1"); // IP白名单 (没有配置或者为空,则允许所有访问)
            reg.addInitParameter("deny", "192.168.16.111"); //IP黑名单 (存在共同时,deny优先于allow)
            reg.addInitParameter("loginUsername", this.druidLoginName);//登录名
            reg.addInitParameter("loginPassword", this.druidPassword);//登录密码
            reg.addInitParameter("resetEnable", "false"); // 禁用HTML页面上的“Reset All”功能
            return reg;
        }
    
        @Bean(name="druidWebStatFilter")
        public FilterRegistrationBean filterRegistrationBean() {
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
            filterRegistrationBean.setFilter(new WebStatFilter());
            filterRegistrationBean.addUrlPatterns("/*");
            filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); //忽略资源
            filterRegistrationBean.addInitParameter("profileEnable", "true");
            filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
            filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
            return filterRegistrationBean;
        }
    }

    使用例子:

      @Resource
        private SysUserMapper sysUserMapper;
    
        private BloomFilter<Integer> bf;
    
        /***
         * PostConstruct 程序启动时候加载此方法
         */
        @PostConstruct
        public void initBloomFilter() {
            SysUserExample sysUserExample = new SysUserExample();
            List<SysUser> sysUserList = sysUserMapper.selectByExample(sysUserExample);
           
        }


  • 相关阅读:
    面向对象上
    面向对象下
    java大话设计模式
    《人体使用手册》阅读摘录
    mosquitto——一个开源的mqtt代理
    mosquitto0.15libmosquitto.c源码分析
    mosquitto0.15clientpub_client.c源码分析
    mosquitto0.15clientsub_client.c源码分析
    厦门三天游如何安排
    mimics教程中文版——第二章
  • 原文地址:https://www.cnblogs.com/jiawen010/p/11647116.html
Copyright © 2011-2022 走看看