zoukankan      html  css  js  c++  java
  • Java逆向工程(数据库表生成java类)

    说起来倒是挺简单的,就是听着名字感觉挺高大上。逆向工程方式有很多,比如mybatis就提供了一个这样的工具mybatis-genderator,这个我反正是没用过只是听说过,以前在公司都是用公司写好的的工具,最近也是闲的无聊自己动手写了一个。

    我的这个工程师基于spring和mybatis写的,有兴趣的加上spring-mvc,加个页面也是不错的。

    其实呢使用mybatis做逆向工程很简单就是两个select查询就好了,数据库底子好的童鞋们应该记得一下这两个查询语句的(不记得也没关系,可以学嘛):

      1. 查询库中的所有表: select * from information_schema.TABLES where TABLE_SCHEMA=(select database())

      2.查询表中的所有字段信息: select * from information_schema.COLUMNS where TABLE_SCHEMA = (select database()) and TABLE_NAME=#{tableName}

    对于第一条sql来说查询那个库就连接哪个就行了,不需要传参数。但是第二条sql需要将表名传进去的(这也是无可厚非的)

    必不可少的我们是需要数据库的4大连接参数,凡是和数据库挂钩应该都需要这几个玩意(这声明一下我这里是用的MySQL)。其他的配置文件上的事情我就不多说了。今天重点不在这里

    接下来简单的将dao、service层贴出来了,和平时的web结构一样很简单。

    service层

    service实现类

    接下来就是今天的重点了。其实也很简单,可能很多人都已经想到了,我们都已经获取到了表字段信息了,那么我们只需要一个文件流不就可以了?(嗯,没错,大兄弟,反正我就是这么写的)

    其实我的这个很简单,主要围绕一个stringbuffer进行,先拼接到字符串中,然后用流写到文件中。下边我粘一下我的代码吧。

    package com.ml.code.one.codegenerator.util;
    
    import com.ml.code.one.codegenerator.myservice.MyCodeService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    @Component
    public class CodeGenerator {
        @Autowired
        private  MyCodeService service;
    
        public void codeGenerator(String tableName,String path){
            List<Map> columns = service.listColumn(tableName);//查询所有的表字段信息
            String className = getClassName(tableName);
            StringBuffer sb = new StringBuffer();
            sb.append("package "+getPackageName(path)+";
    ");
            sb.append("import java.io.Serializable;"+"
    ");
            sb.append("import java.util.*;
    ");
            sb.append("import java.lang.*;
    ");
            sb.append("import lombok.Data;
    ");
            sb.append("import lombok.ToString;
    
    ");
            sb.append("@Data
    @ToString
    ");
            sb.append("public class "+className+" implements Serializable {
    ");
            sb.append("	private static final long serialVersionUID = 1L;
    
    ");
            //获取字段信息
            Iterator<Map> iterator = columns.iterator();
            while (iterator.hasNext()){
                Map next = iterator.next();
                Object dataType = next.get("DATA_TYPE");//获取数据类型
                String type = classCast(dataType);//数据类型
                Object property = next.get("COLUMN_NAME");//获取字段名称
                String propertity = getPropertity(property);//属性名称
                Object annotation = next.get("COLUMN_COMMENT");//注解
                sb.append("	private "+type+" "+propertity+";"+"//"+(String)annotation+"
    ");
            }
            sb.append("}");
            //拼接结束
    
            //生成文件
            try {
                //生成java文件
                getFile(className,sb.toString(),path);
                //生成mapper.xml
    //            getMapperFile(className,path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 生成类名
         * @param tableName 表名
         * @return
         */
        private String getClassName(String tableName){
            String newClassName="";
            int i = tableName.indexOf("_");
            if (i<0){//没有下划线
                newClassName = tableName.substring(0, 1).toUpperCase() + tableName.substring(1)+"Po";
            }else{//有下划线
                String[] strs = tableName.split("_");
                StringBuffer sb = new StringBuffer();
                for (int m = 0; m<strs.length; m++){
                    sb.append(strs[m].substring(0, 1).toUpperCase() + strs[m].substring(1));
                }
                newClassName=sb.toString()+"Po";
            }
            return newClassName;
        }
        //生成属性java类型
        private String classCast(Object obj){
            String type="";
            String str=(String)obj;
            if (str.equals("varchar")||str.equals("char")||str.equals("text")){
                type="String";
            }else if (str.equals("int")){
                type="Integer";
            }else if (str.equals("bigint")){
                type="Long";
            }else if (str.equals("double")||str.equals("float")){
                type="Double";
            }else if (str.equals("date")||str.equals("datetime")||str.equals("timestamp")){
                type="Date";
            }else {
                type="String";
            }
            return type;
        }
        //数据库字段名字转java属性名字
        private  String getPropertity(Object obj){
            String pro="";
            String colum=(String)obj;
            int index = colum.indexOf("_");//判断是否存在下划线
            if (index<0){//没有下划线
                pro=colum.substring(0,1).toLowerCase()+colum.substring(1);//首字母小写
            }else {//有下划线
                StringBuilder sb = new StringBuilder();
                String[] colums = colum.split("_");
                for (int i = 0; i<colums.length; i++){
                    if (i==0){
                        sb.append(colums[i].substring(0,1).toLowerCase()+colums[i].substring(1));//拼接第一个,并将首字母小写
                    }else{
                        sb.append(colums[i].substring(0,1).toUpperCase()+colums[i].substring(1));//除了第一个都将首字母大写
                    }
                }
                pro=sb.toString();
            }
    
            return pro;
        }
    
        /**
         * 生成包名
         */
        private  String getPackageName(String path){
            int index = path.indexOf("java\");
            String newPackage="";
            if (index>0){
                String substring = path.substring(index+5);
                newPackage = substring.replace("\", ".");
            }
            return newPackage;
        }
    
        /**
         * 生成文件
         * @param fileName 文件名
         * @param info 要写入的内容
         * @throws IOException
         */
        private  void getFile(String fileName,String info,String path) throws IOException {
            //生成文件
            File file = new File(path+"\"+fileName+".java");
            if (!file.exists()){
                file.createNewFile();
            }
            FileWriter writer = new FileWriter(file);
            writer.write(info);
            writer.flush();
            writer.close();
        }
    
        /**
         * 生成Mapper.xml
         * @param poName
         */
        private void getMapperFile(String poName,String path) throws IOException {
            //获取文件名
            StringBuilder fileName = new StringBuilder();
            int index = poName.indexOf("Po");
            if (index<0){//没有Po后缀时
                fileName.append(poName+"Mapper");
            }else{//存在Po后缀
                String sub = poName.substring(0, index);//截取到需要的部分
                fileName.append(sub+"Mapper");
            }
            //获取路径
            StringBuilder newPath = new StringBuilder();
            int main = path.indexOf("main\");
            if (main>0){
                String substring = path.substring(0, main+5);
                newPath.append(substring).append("\resources\mapper\");
            }
    
            File file = new File(newPath+fileName.toString()+".xml");
            StringBuilder xmlInfo = new StringBuilder();
            xmlInfo.append("<?xml version="1.0" encoding="UTF-8"?>
    ");
            xmlInfo.append("<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
    " +
                    "     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    ");
            xmlInfo.append("<mapper namespace="">
    ");
            xmlInfo.append("
    
    ");
            xmlInfo.append("</mapper>");
            FileWriter fw = new FileWriter(file);
            fw.write(xmlInfo.toString());
            fw.flush();
            fw.close();
        }
    }

    这里我用的是boot工程写的,运行的时候我选择用boot自带的test工具运行就ok了(别忘了在启动类上加上dao层的包扫描呦)

    到这里呢这个简单的逆向工程就结束了,这个可以直接生成到你指定文件下,顺带连Mapper.xml也生成了的。大佬勿喷。

    有需要源码的可以到以下网盘获取,(网盘中的也只是一部分,只是逆向工程部分,其他的需要你们自行补充,应该是不难的) 

    补充一下,如果有用idea的我建议用idea的代码生成工具哈  下载一个插件就可以了  EasyCode,至于使用方法很简单,把你的idea连上数据库就好了,而且还可以手动配置呢

    链接:https://pan.baidu.com/s/1KW7h9vro2U199hsL85Q38w
    提取码:obpf

  • 相关阅读:
    React学习笔记(六) Create React App
    React学习笔记(五) 状态提升
    React学习笔记(四) 条件渲染与列表渲染
    React学习笔记(三) 事件处理与表单元素
    React学习笔记(二) 组件
    React学习笔记(一) 入门
    React学习笔记
    Vue学习笔记
    Vue学习笔记(十二) Vue Ajax
    路飞_day2
  • 原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/11075363.html
Copyright © 2011-2022 走看看