Oracle之Entity生成工具-yellowcong

来源:互联网 发布:java 视频服务器 编辑:程序博客网 时间:2024/06/17 01:29

在开发中,一般是表结构设计好了之后,然后生成实体类,所以如果手写,你会哭,因为这些代码基本是类是的,而且手写还容易出错,所以一般通过自动生成的工具来生成,这个是控制台打印出来的效果,具体是咋生成类文件啥的,我就没有做了,主要是这玩意具体是生成到哪个包啊,类叫啥名称啊,不同的项目业务也不一样,所以没有必要接着写了,接着的看你自己的了。

生成效果

这里写图片描述

实现原理代码

这个里面,通过java的工具类,将oracle的表字段信息都获取了,然后打印出来,这个里面需要注意其中的原理,就是查询oracle表USER_COL_COMMENTSUSER_TAB_COLUMNS ,通过他们来获取表字段信息。

修改版本:2017/11/15 对于Number判断进行了修改

package com.yellowcong.utils;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;public class CreateEntity {    private static final String DB_URL = "jdbc:oracle:thin:@10.0.7.170:1522:ORCL5";    private static final String DB_USER = "SOFINAM_HENSEI";    //venas2017   SOFINAM_HENSEI    private static final String DB_PASSWORD = "SOFINAM_HENSEI";    private static Connection conn = null;    //设定set方法的模版    private static final StringBuffer GET_METHOD_TEMPLATE = new StringBuffer();    //设定get方法的模版    private static final StringBuffer SET_METHOD_TEMPLATE = new StringBuffer();    //类的名称    private static final StringBuffer CLASS_TEMPLATE = new StringBuffer();    //测试类    public static void main(String[] args) throws Exception {        String tableName = "TEST_DEMO";        String result = createClass(tableName);        System.out.println(result);    }    static {        try {            Class.forName("oracle.jdbc.driver.OracleDriver");            conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);            //创建Get方法的模版            GET_METHOD_TEMPLATE.append("@Column(\"%s\")\r\n");            GET_METHOD_TEMPLATE.append("public %s get%s() {\r\n");            GET_METHOD_TEMPLATE.append("\treturn %s;\r\n");            GET_METHOD_TEMPLATE.append("}");            //设定set方法的模版            SET_METHOD_TEMPLATE.append("public void set%s(%s %s) {\r\n");            SET_METHOD_TEMPLATE.append("\tthis.%s=%s;\r\n");            SET_METHOD_TEMPLATE.append("}");            //方法体的生成            CLASS_TEMPLATE.append("@Bean(table=\"%s\")\r\n");            CLASS_TEMPLATE.append("public class %s implements Serializable{\r\n");            CLASS_TEMPLATE.append("private static final long serialVersionUID = 1L;\r\n");            CLASS_TEMPLATE.append("%s");            CLASS_TEMPLATE.append("\r\n}");        } catch (Exception e) {            e.printStackTrace();        }    }    public static String createClass(String tableName) throws Exception{        StringBuffer sbBody = new StringBuffer();        List<String> classBody =  CreateEntity.createClassBody(tableName);        for(String classInfo :classBody){            sbBody.append(classInfo);            sbBody.append("\r\n");        }        return String.format(CLASS_TEMPLATE.toString(), tableName,underline2Camel(tableName,false),sbBody.toString());    }    /**     * 生成class的内容     * @param tableName     * @return     * @throws Exception     */    public static List<String> createClassBody(String tableName) throws Exception{        List<EntityInfo> infos = getEntityInfo(tableName);        //类的方法体        List<String> classBody = new ArrayList<String>();        for(EntityInfo info:infos){            String comments = info.getComment();            String dataType = info.getType();            String filed = underline2Camel(info.getField());            //当是String类型的            String fieldResult = String.format("/** %s*/\r\nprivate %s %s;\r\n",comments,dataType,filed);            classBody.add(fieldResult);        }        //setter和getter方法        for(EntityInfo info:infos){            //生成get方法            String strGetMethod = createGetterMethod(info);            classBody.add(strGetMethod);            //生成set方法            String strSetMethod = createSetterMethod(info);            classBody.add(strSetMethod);        }        return classBody;    }    /**     * 生成get方法     * @param info     * @return     */    private static String createGetterMethod(EntityInfo info){        String strGetMethod = String.format(                GET_METHOD_TEMPLATE.toString(),                info.getField(),//注解数据                info.getType(),//返回的数据类型格式                underline2Camel(info.getField(),false), //getUserName                underline2Camel(info.getField()));//userName        return strGetMethod;    }    /**     * 生成set的方法     * @param info     * @return     */    private static String createSetterMethod(EntityInfo info){        String strSetMethod = String.format(                SET_METHOD_TEMPLATE.toString(), //模版                underline2Camel(info.getField(),false), //大驼峰 setUserName                info.getType(),//数据类型                underline2Camel(info.getField()), //小驼峰 userName                underline2Camel(info.getField()), //小驼峰 userName                underline2Camel(info.getField()) //小驼峰 userName                );        return strSetMethod.toString();    }    /**     * 根据传入的数据类型来字符的类型     * 如果你是其他的数据库,可以根据自己的需求来更改这一块     * @param dataType oracle字段的类型     * @param len 字符的长度     * @return     */    private static String getFieldType(String dataType,int len){        String fieldType = "";        //当是String类型的        switch(dataType){        case "CHAR" :            fieldType =  "String";            break;        case  "VARCHAR2":            fieldType = "String";            break;        case "BLOB":            fieldType = "BLOB";            break;        case "DATE":            fieldType = "Date";            break;        case "NUMBER":            if(len == 0){                fieldType = "Long";            }else{                fieldType = len <12?"Integer":"Long";            }            break;        case "FLOAT":            fieldType = len <12?"Float":"Double";            break;        }        return fieldType;    }    /**     * 获取连接     * @return     */    public static Connection getConnection() {        try {            if (conn == null) {                Class.forName("oracle.jdbc.driver.OracleDriver");                conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);            }            return conn;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /**     * 获取实体类的字段信息     * @param tableName     * @return     * @throws Exception     */    public static List<EntityInfo> getEntityInfo(String tableName) throws Exception {        Connection con = CreateEntity.getConnection();        //查询USER_COL_COMMENTS 和USER_TAB_COLUMNS 两个表,查询出字段信息        String sql = "SELECT COL.COLUMN_NAME, COL.COMMENTS, " +                " case TAB.DATA_TYPE when 'NUMBER' then decode(sign(NVL(TAB.DATA_SCALE,0)),0,'NUMBER','FLOAT') else TAB.DATA_TYPE end as DATA_TYPE," +                " DECODE(TAB.DATA_TYPE, 'NUMBER', TAB.DATA_PRECISION + TAB.DATA_SCALE , TAB.DATA_LENGTH) AS DATA_LENGTH "                + "FROM USER_COL_COMMENTS COL, USER_TAB_COLUMNS TAB WHERE COL.TABLE_NAME = ? "                + "AND TAB.TABLE_NAME = COL.TABLE_NAME AND TAB.COLUMN_NAME = COL.COLUMN_NAME ";        PreparedStatement ps = con.prepareStatement(sql);        System.out.println(sql);        ps.setString(1, tableName);        ResultSet rs = ps.executeQuery();        //将查询的信息都放到集合里面,然后回        List<EntityInfo> infos = new ArrayList<EntityInfo>();        while (rs.next()) {            //字段名次            String colNm = rs.getString(1);            //备注            String comments = rs.getString(2);            //oracle 数据类型            String dataType = rs.getString(3);            //oralce 数据长度            Integer len = rs.getInt(4);            //获取对应的java苏汇聚类型            String fieldType = getFieldType(dataType,len);            infos.add(new CreateEntity.EntityInfo(colNm,comments,fieldType,len));        }        ps.close();        con.close();        return infos;    }    /**     * 下划线转驼峰法(默认小驼峰)     *     * @param line     *            源字符串     * @param smallCamel     *            大小驼峰,是否为小驼峰(驼峰,第一个字符是大写还是小写)     * @return 转换后的字符串     */    public static String underline2Camel(String line, boolean ... smallCamel) {        if (line == null || "".equals(line)) {            return "";        }        StringBuffer sb = new StringBuffer();        Pattern pattern = Pattern.compile("([A-Za-z\\d]+)(_)?");        Matcher matcher = pattern.matcher(line);        //匹配正则表达式        while (matcher.find()) {            String word = matcher.group();            //当是true 或则是空的情况            if((smallCamel.length ==0 || smallCamel[0] ) && matcher.start()==0){                sb.append(Character.toLowerCase(word.charAt(0)));            }else{                sb.append(Character.toUpperCase(word.charAt(0)));            }            int index = word.lastIndexOf('_');            if (index > 0) {                sb.append(word.substring(1, index).toLowerCase());            } else {                sb.append(word.substring(1).toLowerCase());            }        }        return sb.toString();    }    /**     * 驼峰法转下划线     *     * @param line     *            源字符串     * @return 转换后的字符串     */    public static String camel2Underline(String line) {        if (line == null || "".equals(line)) {            return "";        }        line = String.valueOf(line.charAt(0)).toUpperCase()                .concat(line.substring(1));        StringBuffer sb = new StringBuffer();        Pattern pattern = Pattern.compile("[A-Z]([a-z\\d]+)?");        Matcher matcher = pattern.matcher(line);        while (matcher.find()) {            String word = matcher.group();            sb.append(word.toUpperCase());            sb.append(matcher.end() == line.length() ? "" : "_");        }        return sb.toString();    }    /**     * 用于存储实体类字段信息     * @author zhangrw     *     */    static class EntityInfo {        private String field;        private String comment;        private String type;        private Integer length;        /**         *         */        public EntityInfo() {            super();        }        /**         * @param field         * @param comment         * @param type         * @param length         */        public EntityInfo(String field, String comment, String type,                Integer length) {            super();            this.field = field;            this.comment = comment;            this.type = type;            this.length = length;        }        public String getField() {            return field;        }        public void setField(String field) {            this.field = field;        }        public String getType() {            return type;        }        public void setType(String type) {            this.type = type;        }        public Integer getLength() {            return length;        }        public void setLength(Integer length) {            this.length = length;        }        public String getComment() {            return comment;        }        public void setComment(String comment) {            this.comment = comment;        }    }}

生成效果

这个是控制台打印出来的效果,具体是咋生成类文件啥的,我就没有做了,主要是这玩意具体是生成到哪个包啊,类叫啥名称啊,不同的项目业务也不一样,所以没有必要接着写了,接着的看你自己的了。
这里写图片描述

类的头信息
这里写图片描述

注意细节

number类型的数据在oracle中的长度是 22,但是我们并不需要这个长度,而是后面的DATA_PRECISIONDATA_SCALE两个字段了,所以要么在SQL上下文章,要么在java处理做文章,这种情况,我们希望在oracle上做文章,这样效率跟高一点

这里写图片描述

优化SQL语句

SELECT COL.COLUMN_NAME,       COL.COMMENTS,       case TAB.DATA_TYPE when 'NUMBER' then             --当是number的情况,判断 DATA_SCALE 是否为0 如果是0 就是number类型             --如果非0 就是FLOAT类型,这个地方,我就这么简单做判断了             decode(sign(TAB.DATA_SCALE),0,'NUMBER','FLOAT')       else           TAB.DATA_TYPE       end as DATA_TYPE,       DECODE(TAB.DATA_TYPE,              'NUMBER',              TAB.DATA_PRECISION + TAB.DATA_SCALE ,              TAB.DATA_LENGTH) AS DATA_LENGTH  FROM USER_COL_COMMENTS COL, USER_TAB_COLUMNS TAB WHERE COL.TABLE_NAME = 'K_TRN_OUTLINE'   AND TAB.TABLE_NAME = COL.TABLE_NAME   AND TAB.COLUMN_NAME = COL.COLUMN_NAME

对于number类型进行特殊的处理,这样字段的长度就正确了,同时将数据类型为number的,如果是浮点,就反回float

这里写图片描述

原创粉丝点击