您的位置:首页 > 大数据 > 人工智能

jdbc工具类-生成domain实体

2017-04-30 20:27 267 查看

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

需求,很简单,但是写的时候,也遇到了一些问题,主要是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&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&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("代码生成成功");
}

}


最终效果:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息