你还在安装mybatis-generator插件?300行自己手写一个Mybatis代码生成工具类吧!

你还在安装mybatis-generator插件?300行自己手写一个Mybatis代码生成工具类吧!

Mybatis如何实现逆向工程,根据表接口直接生成entity类和Mapper文件呢?

之前的做法:

  • 打开百度找mybatis-generator,翻找一大堆乱七八糟的教程

  • 安装mybatis-generator插件,

  • 添加maven依赖

  • 搞了一大堆,结果生成的东西还是乱七八糟的。

所以把原理搞懂自己实现一个代码生成类吧。

在这里插入图片描述

主要知识点:

JDBC

数据库表字段查询

IO操作

部分地方用到一些反射获取到属性名之类的东西

字符串转换的操作

然后就是一堆的字符串拼接操作。

原理其实很简单,就是读取数据库中的COLUMN_NAME和DATA_TYPE,再拼接成java的类型,和属性名;

最后把拼接的字符串写入到文件中就行了

下面附上详细代码

MybatisUtil.java

package com.bigfire.test.common.utils;

import org.springframework.util.StringUtils;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**

- @ IDE    :IntelliJ IDEA.

- @ Author :dahuo.

- @ Date   :2019/7/23  16:44

- @ Addr   :China ShangHai

- @ Email  :[email protected]

- @ Desc   :
  */
  public class MybatisUtil {

  private static String url = "";
  private static String user = "";
  private static String password = "";
  private static String driverClass = "com.mysql.jdbc.Driver";
  private static String tableName = "";//表名
  private static String entityPackName = "";//要生成的entity包名

  public static void main(String[] args) {
  //        System.out.println(generateEntity());//生成实体类
      System.out.println(generateMapper(AppFont.class, AppFontDao.class));//生成Mapper
  }

//------------------------------------------------下方代码不用修改---------------------------------------------------------
//生成实体类
private static String generateEntity(){
    String className = lineToUpCase(tableName);
    StringBuilder sb = new StringBuilder();
    sb.append("package ").append(entityPackName).append(".").append(className).append("\n\n");
    sb.append("import lombok.Data;\n");
    sb.append("import lombok.experimental.Accessors;\n");
    sb.append("import java.io.Serializable;\n");
    List<Entity> entities = getDBColumnMap(tableName);
    //生成注释代码
    sb.append("/**\n");
    sb.append("* @ Date    :").append(LocalDate.now()).append(".\n");
    sb.append("* auto generate code by MybatisUtil.java.\n");
    sb.append("*/\n");
    sb.append("@Data\n");
    sb.append("public class ").append(className).append(" implements Serializable {\n");
    for (int i = 0; i < entities.size(); i++) {
        String columnName = entities.get(i).getColumnName();
        String dataType = entities.get(i).getDataType();
        sb.append("    private ");
        if (dataType.equals("varchar")){
            sb.append("String ").append(Tran(columnName)).append(";\n");
        }else if (dataType.equals("int")){
            sb.append("Integer ").append(Tran(columnName)).append(";\n");
        }else if (dataType.equals("bigint")){
            sb.append("Long ").append(Tran(columnName)).append(";\n");
        }else if(dataType.contains("time")){
            sb.append("Date ").append(Tran(columnName)).append(";\n");
        }else {
            sb.append("Date ").append(Tran(columnName)).append(";\n");
        }
    }
    sb.append("\n}\n");
    String desktopPath = FileSystemView.getFileSystemView() .getHomeDirectory().getAbsolutePath();
    String entityFileName =new StringBuilder(desktopPath).append("/").append(className).append(".java").toString();
    writeStringToFile(entityFileName,sb.toString());
    return sb.toString();
}
    //生成Mapper文件
    private static String generateMapper(Class entityClass,Class daoClass){
        String className = lineToUpCase(tableName);
        String entityNamespace = entityClass.getPackage().getName();
        String daoNamespace = daoClass.getPackage().getName();
        StringBuilder[] zsbs = new StringBuilder[7];
        for (int i=0;i<7;i++){
            zsbs[i]=new StringBuilder();
        }
        List<Entity> entities = getDBColumnMap(tableName);
        for (int i = 0; i < entities.size(); i++) {
            String columnName = entities.get(i).getColumnName();
            zsbs[0].append("        <result column=\"").append(columnName).append("\" property=\"").append(Tran(columnName)).append("\"/>").append("\n");
            zsbs[1].append("        ").append(columnName).append(",\n");
            zsbs[2].append("            <if test=\"pojo.").append(Tran(columnName)).append(" != null\"> ").append(columnName).append(", </if>\n");
            zsbs[3].append("            <if test=\"pojo").append(Tran(columnName)).append(" != null\"> #{pojo.").append(Tran(columnName)).append("}, </if>\n");
            zsbs[4].append("            #{pojo.").append(Tran(columnName)).append("},\n");
            if (!columnName.equals("id"))
                zsbs[5].append("            <if test=\"pojo.").append(Tran(columnName)).append(" != null\"> ").append(columnName).append(" = #{pojo.").append(Tran(columnName)).append("}, </if>\n");
            zsbs[6].append("            <if test=\"pojo.").append(Tran(columnName)).append(" != null\"> AND id = #{pojo.").append(Tran(columnName)).append("} </if>\n");
        }
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
        sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\" >\n");
        sb.append("<mapper namespace=\"").append(daoNamespace).append("\">\n");
        sb.append("\n");
        sb.append("    <resultMap id=\"AllColumnMap\" type=\"").append(entityNamespace).append("\">\n");
        sb.append(zsbs[0].toString());
        sb.append("    </resultMap>\n\n");
        sb.append("    <sql id=\"all_column\">\n");
        sb.append(zsbs[1].toString());
        sb.append("    </sql>\n\n");
        //添加
        sb.append("    <insert id=\"insert\">\n");
        sb.append("        INSERT INTO ").append(tableName).append("\n");
        sb.append("        <trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");
        sb.append(zsbs[2].toString());
        sb.append("        </trim>\n");
        sb.append("        VALUES\n");
        sb.append("        <trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");
        sb.append(zsbs[3].toString());
        sb.append("        </trim>\n");
        sb.append("    </insert>\n\n");
        sb.append("    <insert id=\"insertList\">");
        sb.append("        INSERT INTO ").append(tableName).append("(\n");
        sb.append("        <include refid=\"all_column\"/>\n");
        sb.append("        )VALUES\n");
        sb.append("        <foreach collection=\"pojos\" item=\"pojo\" index=\"index\" separator=\",\">\n");
        sb.append("            (\n");
        sb.append(zsbs[4].toString());
        sb.append("            )\n");
        sb.append("        </foreach>\n");
        sb.append("    </insert>\n\n");
        //更新
        sb.append("    <update id=\"update\">\n");
        sb.append("        UPDATE ").append(tableName).append("\n");
        sb.append("        <set>\n");
        sb.append(zsbs[5].toString());
        sb.append("        </set>\n");
        sb.append("        WHERE id = #{pojo.id}\n");
        sb.append("    </update>\n\n");
        //查询
        sb.append("    <select id=\"select\" resultMap=\"AllColumnMap\">\n");
        sb.append("        SELECT <include refid=\"all_column\"/>");
        sb.append("        FROM ").append(tableName).append("\n");
        sb.append("        <where>\n");
        sb.append(zsbs[6].toString());
        sb.append("        </where>\n");
        sb.append("        LIMIT 1000\n");
        sb.append("    </select>\n\n");
        //删除
        sb.append("    <delete id=\"delete\">\n");
        sb.append("        DELETE FROM ").append(tableName).append(" where id = #{pojo.id}\n");
        sb.append("    </delete>\n\n");
        //findById
        sb.append("    <select id=\"findById\" resultMap=\"AllColumnMap\">\n");
        sb.append("        SELECT <include refid=\"all_column\"/>\n");
        sb.append("        FROM ").append(tableName).append("\n");
        sb.append("        where\n");
        sb.append("        id = #{id}\n");
        sb.append("        LIMIT 1\n");
        sb.append("    </select>\n");
        sb.append("</mapper>\n");
        String desktopPath = FileSystemView.getFileSystemView() .getHomeDirectory().getAbsolutePath();
        String mapperFileName =new StringBuilder(desktopPath).append("/").append(className).append("Mapper").append(".xml").toString();
        writeStringToFile(mapperFileName,sb.toString());
        return sb.toString();
    }
//---------------------------------------------JDBC---------------------------------------------
    static{
        try {
            Properties prop = new Properties();
            Class clazz = MybatisUtil.class;
            Class.forName(driverClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接方法
    public static Connection getConnection(){
        try {
            Connection conn = DriverManager.getConnection(url, user, password);
            return conn;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    //释放资源的方法
    public static void close(Statement stmt,Connection conn){
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }
    //释放资源的方法
    public static void close(ResultSet rs,Statement stmt,Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        close(stmt,conn);
    }
    //---------------------------------------------获取列名和类型的部分---------------------------------------------
    //获取数据库字段和属性
    public static List<Entity> getDBColumnMap(String tableName){
        Connection conn = MybatisUtil.getConnection();
        String sql = "SELECT COLUMN_NAME,DATA_TYPE FROM information_schema.columns WHERE table_name = ?";
        try {
            PreparedStatement ptmt  = conn.prepareStatement(sql);
            ptmt.setString(1,tableName);
            ResultSet rs = ptmt.executeQuery();
            //如果有数据,rs.next()返回true
            List<Entity> list = new ArrayList();
            while(rs.next()){
                list.add(new Entity().setColumnName(rs.getString("COLUMN_NAME")).setDataType(rs.getString("DATA_TYPE")));
            }
            close(rs,ptmt,conn);
            return list;
        }catch (Exception e){
            e.printStackTrace();
            try {
                conn.close();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            return new ArrayList<>();
        }
    }
    //临时存储类
    static class Entity {
        private String columnName;
        private String dataType;
        public String getColumnName(){ return this.columnName; }
        public String getDataType(){ return this.dataType; }
        public Entity setColumnName(String columnName){ this.columnName = columnName; return this; }
        public Entity setDataType(String dataType){ this.dataType = dataType; return this; }
        @Override
        public String toString() { return "["+this.getColumnName()+","+this.getDataType()+"]"; }
    }
//------------------------------------------依赖的一些字符串处理方法--------------------------------------------------
    //下划线写法转换未驼峰写法
    private static String Tran(String columnName){
        return toLowerCaseFirst(lineToUpCase(columnName));
    }
    //首字母转小写
    private static String toLowerCaseFirst(String s){
        if(Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }
    //下划线转首字母大写
    private static String lineToUpCase(String str){
        StringBuilder builder = new StringBuilder();
        Arrays.asList(str.split("_")).forEach(temp -> builder.append(StringUtils.capitalize(temp)));
        return builder.toString();
    }

//首字母转大写
private static String toUpperCaseFirst(String s){
    if(Character.isUpperCase(s.charAt(0)))
        return s;
    else
        return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
}
//统计字符串出现次数
private static Integer countString(String str,String s) {
    int count = 0,len = str.length();
    while(str.indexOf(s) != -1) {
        str = str.substring(str.indexOf(s) + 1,str.length());
        count++;
    }
    return count;
}

//--------------------------------------IO操作---------------------------------
    //字符串写入文件中
    public static Boolean writeStringToFile(String path, String resources)
    {
        FileOutputStream fos;
        File f = new File(path);
        try
        {
            fos = new FileOutputStream(f);
            fos.write(resources.getBytes());
            fos.close();
        } catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
        return true;
    }

}

本人也经常整理一些好用的工具类

相关文章

几个java工具类,字符串处理类,HTTP模拟请求类,文件下载类,IO读写类,随机字符生成类,格式化工具类

size size

javase基础socket编程之局域网聊天,局域网文件共享

原创文章 19 获赞 2 访问量 4898

猜你喜欢

转载自blog.csdn.net/qq_34173920/article/details/97025975