jdbc工具类-生成domain实体

最近两天项目里遇到一个需求,要求将数据库里某些表的某些字段,加密,但是还要保证能及时还原回去.

需求,很简单,但是写的时候,也遇到了一些问题,主要是oracle数据库使用数据库查询数据库时,resultset返回的结果集,我们的数据库最大1329条,当然这个参数可以修改,但是,我们遇到问题的时候不能去修改配置,治标不治本,所以,还是分页查询吧,最终问题解决了.

其中比较坑的就是,注意使用jdbc的批量操作,每个一定量的数据批量提交一次,我们的数据较小,所以我每隔一百条记录提交一次就好,测试1300记录,导出,加密,还原不到一分钟,(还是字段较多的哦),总体性能不错.

当时,写这个工具的时候,考虑到后期数据的变动,采用了反射,将指定的sql语句查询出来的resultset映射成javabean对象,更新时,将javabean转换为list参数列表,然后生成更新语句,总的来说这设计,帮我减少了很多工作.
但是整个写代码的过程中,很麻烦的就是,属性顺序要和sql查询顺序一致.

当然,javabean还是提前手写好了.
这一步,要是表多了,自己手写很累,所以考虑一下,正好也有时间了,就稍微学习了下,利用freeemark生成javabean,当初本来想看看mybatis的逆向工程的源码的,但是我的maven不知道咋回事,暂时不能用了,所以暂时也没心情整他,所以就自己写一个吧.
使用的技术:freemark模板引擎,jdbc
好了,不废话了,我们来一步步实现吧.

需求:根据数据库生成javabean

用到的jar包,freemarker 2.3和mysqljdbc-connector

1.第一步jdbc查询出所有的表,和表的列信息和列类型信息

具体实现如下:

package com.taoyuan.jdbc;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author 都市桃源 读取数据库信息 2017年4月30日
 */
public class ConvertUtil {
    public static final Map<String,String> columnToJavaType=new HashMap<String,String>();
    static{//mysql类型到java类型的转换
        columnToJavaType.put("VARCHAR", "String");
        columnToJavaType.put("INT", "Integer");
        columnToJavaType.put("BIGINT", "Long");
        columnToJavaType.put("TIME", "Date");
        columnToJavaType.put("DATETIME", "Date");
        columnToJavaType.put("TEXT", "String");
    }
    public static List<Table> getTables(Connection con) throws SQLException {
        DatabaseMetaData metaData = con.getMetaData();// 获取数据库信息
        //获取数据库信息
        ResultSet rs = metaData.getTables(null, null, null, new String[] { "TABLE", "VIEW" });
        List<Table> tables=new LinkedList<Table>();
        Table tab=null;
        List<Attribute> columnList=null;
        while (rs.next()) {//遍历表和列
            if (rs.getString(4) != null
                    && (rs.getString(4).equalsIgnoreCase("TABLE") || rs.getString(4).equalsIgnoreCase("VIEW"))) {
                String tableName = rs.getString(3).toLowerCase();
                tab=new Table();
                tab.setTableName(toClassCase(tableName));
                columnList=new ArrayList<Attribute>();
                ResultSet colRet = metaData.getColumns(null, "%", tableName, "%");//获取列
                Attribute col=null;
                while (colRet.next()) {//遍历列
                    col=new Attribute();
                    String columnName = colRet.getString("COLUMN_NAME");
                    String columnType = colRet.getString("TYPE_NAME");
                    col.setName(toCamelCase(columnName));
                    col.setType(columnToJavaType.get(columnType));
                    columnList.add(col);
                }
                tab.setColumns(columnList);
            }
            tables.add(tab);

        }
        return tables;
    }

    public static void main(String[] args) throws Exception {
    /*  String driver = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/note?useUnicode=true&amp;characterEncoding=UTF-8";
        String user = "root";
        String password = "";
        Class.forName(driver);
        Connection conn = DriverManager.getConnection(url, user, password);*/

    }
    /**将字符串转换为驼峰命名
     * @param str
     * @return
     */
    public static String toCamelCase(String str){
        if(str==null||!str.contains("_"))return str;
        StringBuffer buf=new StringBuffer();
        char[] charArray = str.toCharArray();
        for(int i=0,len=charArray.length;i<len-1;i++){
            if(charArray[i]=='_'&&(charArray[i+1]>='a'&&charArray[i+1]<'z')){
                charArray[i+1]=(char) (charArray[i+1]-32);
            }
            if(charArray[i]!='_')
            buf.append(charArray[i]);
        }
        buf.append(charArray[charArray.length-1]);
        return buf.toString();
    }
    /**转换类名
     * @param str
     * @return
     */
    public static String toClassCase(String str){
        String camelCase = toCamelCase(str);
        String substring = camelCase.substring(0,1);
        return camelCase.replaceFirst(substring, substring.toUpperCase());
    }

}
封装下对象table和属性:

package com.taoyuan.jdbc;

public class Attribute {
private String type;
private String name;
public Attribute() {
super();
}
public Attribute(String name,String type) {
super();
this.type = type;
this.name = name;
}
public String getType() {
return type;
}

public void setType(String type) {
    this.type = type;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}

package com.taoyuan.jdbc;

import java.util.List;

/**
 * @author 都市桃源
 *2017年4月30日
 *表实体
 */
public class Table {
    private String tableName;
    private List<Attribute> columns;
    public String getTableName() {
        return tableName;
    }
    public void setTableName(String tableName) {
        this.tableName = tableName;
    }
    public List<Attribute> getColumns() {
        return columns;
    }
    public void setColumns(List<Attribute> columns) {
        this.columns = columns;
    }



}

调用方法ConvertUtil.getTbales,就可以获取所有表和视图的信息,jdbc的类型对应,各位可以自己添加,我测试的时候就用到这个几个

2,第二步,代码生成

首先准备模板,一个正常的freemarker模板

package ${packageName};


/**
 *  @author ${author}
 */
public class ${className} {
    <#list attrs as attr> 
    private ${attr.type} ${attr.name};
    </#list>

    <#list attrs as attr>
    public void set${attr.name?cap_first}(${attr.type} ${attr.name}){
        this.${attr.name} = ${attr.name};
    }
    public ${attr.type} get${attr.name?cap_first}(){
        return this.${attr.name};
    }

    </#list>

}

编写模板生成代码,官网上有例子http://freemarker.org/
参考博客:
http://blog.csdn.net/whithorse/article/details/19206087

我的需求很简单,生成dao的我就不写了,而且就算生成也很鸡肋.

基础配置

#jdbc配置
url=jdbc:mysql://localhost:3306/note?useUnicode=true&amp;characterEncoding=UTF-8
driver=com.mysql.jdbc.Driver
user=root
password=
#生成类的包名
packageName=com.toyuanx.pojo
#作者
author=taoyuan
#采用模板名称
templatePath=pojo.ftl
#模板所在目录
templateDir=D:/freemarker


代码生成工具类

package com.taoyuan.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import com.taoyuan.jdbc.Attribute;
import com.taoyuan.jdbc.ConvertUtil;
import com.taoyuan.jdbc.Table;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

public class DomainGenerator {
    static Properties pro=new Properties();
    static{
        try {
            pro.load(DomainGenerator.class.getClassLoader().getResourceAsStream("jdbc.properties"));
        } catch (IOException e) {
        System.out.println("加载配置文件失败");
        }
    }
    public static void main(String[] args) throws Exception {
        String driver = pro.getProperty("driver");
        String url = pro.getProperty("url");
        String user = pro.getProperty("user");
        String password = pro.getProperty("password");
        String packageName = pro.getProperty("packageName");
        String author = pro.getProperty("author");
        Class.forName(driver);
        Connection conn = DriverManager.getConnection(url, user, password);
        List<Table> tables = ConvertUtil.getTables(conn);
        gen(tables,packageName,author);
    }

    public static  void gen(List<Table> tables,String packageName,String author ) throws IOException, TemplateException{
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        cfg.setDirectoryForTemplateLoading(new File(pro.getProperty("templateDir")));   
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        Template temp = cfg.getTemplate(pro.getProperty("templatePath")); 
        for(int i=0,length=tables.size();i<length;i++){
            Table table = tables.get(i);
        Map<String, Object> root = new HashMap<String, Object>();
        root.put("packageName", packageName);
        root.put("author", "taoyuan");
        root.put("className", table.getTableName());
        root.put("attrs", table.getColumns());

        File dir = new File("D:/freemarker");
        if(!dir.exists()){
            dir.mkdirs();
        }
        OutputStream fos = new  FileOutputStream( new File(dir, table.getTableName()+".java")); //java文件的生成目录   
        Writer out = new OutputStreamWriter(fos);
        temp.process(root, out);

        fos.flush();  
        fos.close();
        }
        System.out.println("代码生成成功");
    }


}

最终效果:
这里写图片描述

这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值