1. 程式人生 > >java spring jdbc 自動封閉實體類

java spring jdbc 自動封閉實體類

1.封裝的工具類

package jdbc.util;


import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


public class JdbcUtil {
private static final Map<String, String> dateFormat;
static{
dateFormat=new HashMap<String, String>();
dateFormat.put("^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})", "yyyy-MM-dd HH:mm:ss");
dateFormat.put("^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3})", "yyyy-MM-dd HH:mm:ss.SSS");
dateFormat.put("^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{2})", "yyyy-MM-dd HH:mm:ss.SS");
dateFormat.put("^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{1})", "yyyy-MM-dd HH:mm:ss.S");
dateFormat.put("^(\\d{4}-\\d{2}-\\d{2})", "yyyy-MM-dd");
dateFormat.put("^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2})", "yyyy-MM-dd HH:mm");
dateFormat.put("^(\\d{4}-\\d{2}-\\d{2} \\d{2})", "yyyy-MM-dd HH");
dateFormat.put("^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{7})", "yyyy-MM-dd HH:mm:ss.SSSSSSS");

}
@SuppressWarnings("unchecked")
public static Object objectToBean(ResultSet rs, Class clazz) throws Exception {
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
Object o = clazz.newInstance();
for (int i = 1; i <= count; i++) {
String columnName = rsmd.getColumnName(i);
if ("row_num".equals(columnName)) {
continue;
}
Field field;
try {
field = clazz.getDeclaredField(columnName);
} catch (Exception e) {
System.out.println("類["+clazz.getName()+"]未找到該欄位["+columnName+"]");
continue;



// 屬性對應的set方法
String methodName = "set" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
// 將欄位值set進bean的屬性值
// Class<?>
// parameterTypes=classMap.get(field.getType().getSimpleName());
// clazz.getDeclaredMethod(methodName, parameterTypes).invoke(o,
// rs.getObject(columnName));
// 判斷bean 屬性的型別
boolean bool = rs.getObject(i) != null;
if (field.getType().getSimpleName().equals("Integer")) {
if (bool) {
clazz.getDeclaredMethod(methodName, Integer.class).invoke(o, rs.getInt(columnName));
}
} else if (field.getType().getSimpleName().equals("int")) {
if (bool) {
clazz.getDeclaredMethod(methodName, int.class).invoke(o, rs.getInt(columnName));
} else {
clazz.getDeclaredMethod(methodName, int.class).invoke(o, 0);
}
} else if (field.getType().getSimpleName().equals("String")) {
if (bool) {
clazz.getDeclaredMethod(methodName, String.class).invoke(o, rs.getString(columnName));
}


} else if (field.getType().getSimpleName().equals("double")) {


if (bool) {
clazz.getDeclaredMethod(methodName, double.class).invoke(o, rs.getDouble(columnName));
} else {
clazz.getDeclaredMethod(methodName, double.class).invoke(o, 0);
}


} else if (field.getType().getSimpleName().equals("Double")) {
if (bool) {
clazz.getDeclaredMethod(methodName, Double.class).invoke(o, rs.getDouble(columnName));
}


} else if (field.getType().getSimpleName().equals("Date")) {
if (bool) {
//clazz.getDeclaredMethod(methodName, Date.class).invoke(o, new Date(rs.getTime(columnName).getTime()));
//clazz.getDeclaredMethod(methodName, Date.class).invoke(o, rs.getDate(columnName));
clazz.getDeclaredMethod(methodName, Date.class).invoke(o, rs.getTimestamp(columnName));
//SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSS");;
//System.out.println(formatter.format(rs.getTimestamp(columnName)));
/*boolean dfBool=true;
String dateStr=rs.getString(columnName);
for (String key : dateFormat.keySet()) {
Pattern pat = Pattern.compile(key);
        Matcher mat = pat.matcher(dateStr);
        if (mat.matches()) {
        SimpleDateFormat formatter = new SimpleDateFormat(dateFormat.get(key));;
clazz.getDeclaredMethod(methodName, Date.class).invoke(o, formatter.parse(dateStr));
//System.out.println(dateStr+":對應的時間格式"+dateFormat.get(key));
dfBool=false;
break;
        }
}
if (dfBool) {
//throw new Exception(dateStr+":沒有匹配到對應的時間格式");
System.out.println(dateStr+":沒有匹配到對應的時間格式");
}*/

}


} else if (field.getType().getSimpleName().equals("Long")) {
if (bool) {
clazz.getDeclaredMethod(methodName, Long.class).invoke(o, rs.getLong(columnName));
}
} else if (field.getType().getSimpleName().equals("long")) {
if (bool) {
clazz.getDeclaredMethod(methodName, long.class).invoke(o, rs.getLong(columnName));
} else {
clazz.getDeclaredMethod(methodName, long.class).invoke(o, 0);
}
} else if (field.getType().getSimpleName().equals("float")) {


if (bool) {
clazz.getDeclaredMethod(methodName, float.class).invoke(o, rs.getFloat(columnName));
} else {
clazz.getDeclaredMethod(methodName, float.class).invoke(o, 0);
}


} else if (field.getType().getSimpleName().equals("Float")) {
if (bool) {
clazz.getDeclaredMethod(methodName, Float.class).invoke(o, rs.getFloat(columnName));
}


} else {
System.out.println("目前只支援int ,double與 String 型別資料屬性");
continue;
}
}
return o;
}

}

2. spring RowMapper

package jdbc.util;


import java.sql.ResultSet;
import java.sql.SQLException;


import org.springframework.jdbc.core.RowMapper;


public class MyRowMapper<T> implements RowMapper<T>{


private Class<T> persistentClass;


/**
* 構造
* @param persistentClass
*/
public MyRowMapper(final Class<T> persistentClass) {
this.persistentClass = persistentClass;
}




@SuppressWarnings({ "rawtypes", "unchecked" })
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
Class clazz = persistentClass;
T entity = null;
try {
entity = (T)JdbcUtil.objectToBean(rs, clazz);
} catch (Exception e) {
e.printStackTrace();
}
return entity;
}

}

j3. jdbc 通用dao

package jdbc.dao;


import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import javax.sql.DataSource;


import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.util.Assert;



import jdbc.util.PageTools;
jimport  jdbc.util.MyRowMapper;


public class JdbcDao<T> {


private Class<T> persistentClass;
private String databaseType;


protected String getDatabaseType() {
return databaseType;
}


public void setDatabaseType(String databaseType) {
this.databaseType = databaseType;
}


/**
* 構造

* @param persistentClass
*/
public JdbcDao(final Class<T> persistentClass) {
this.persistentClass = persistentClass;
}


private JdbcTemplate jdbcTemplate;


public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}

public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public Date getSystemDate() throws Exception {
String sql="";
if ("sqlserver".equals(databaseType) ) {
sql="select getDate()";
}else if ("postgreSQL".equals(databaseType) ) {
sql="select now()";
}else if ("mysql".equals(databaseType)) {
sql="select now()";
}else if ("access".equals(databaseType)) {
sql="select now()";
}else if ("oracle".equals(databaseType)) {
sql="select sysdate from dual";
}else {
throw new Exception ("不支援當前資料庫時間查詢");
}
Timestamp timestamp=jdbcTemplate.queryForObject(sql, new RowMapper<Timestamp>(){


@Override
public Timestamp mapRow(ResultSet rs, int arg1) throws SQLException {
Timestamp date = null;
try {
date = rs.getTimestamp(1);
} catch (Exception e) {
e.printStackTrace();
}
return date;
}

});
return timestamp;
}


/**
* 分頁查詢物件集合

* @param sql
*            sql語句
* @param page
*            分頁
* @return list
* @throws Exception 
*/
public List<T> queryForPageByHql(String sql, PageTools page, Object... args) throws Exception {
if (null == page) {
return list(sql, args);
} else {
int count = getResultCount(sql,args);
page.setRecordCount(count);
StringBuffer sb=new StringBuffer();
if ("sqlserver".equals(databaseType)) {
sb.append("select t.* from ");
// 原sql 拼接 查詢 row_number()
sb.append("(");
int beginPos = sql.toLowerCase().indexOf("from");
sb.append(sql.substring(0, beginPos));
sb.append(" , ROW_NUMBER() OVER ("+getOrderby(sql)+") AS row_num ");
sb.append(removeOrders(sql).substring(beginPos));
sb.append(") t");
// 拼接外層sql及 分頁查詢條件
sb.append(" where t.row_num between ").append(page.getStartRow()+1).append(" and ")
.append(page.getStartRow() + page.getPageSize());
}else if ("mysql".equals(databaseType)) {
sb.append(sql);
sb.append("  limit "+page.getPageSize()+" offset "+page.getStartRow()+1);
}else if ("postgreSQL".equals(databaseType)) {
sb.append(sql);
sb.append("  limit "+page.getPageSize()+" offset "+page.getStartRow()+1);
}else {
throw new Exception ("不支援當前資料庫分頁");
}
//System.out.println("分頁SQL["+sb.toString()+"]");
return list(sb.toString(), args);
}
}
public List<T> queryForPageBySql(String sql,RowMapper<T> rowMapper, PageTools page, Object... args) throws BaseException {
if (null == page) {
return listBySql(sql, rowMapper,args);
} else {
int count = getResultCount(sql);
page.setRecordCount(count);
StringBuffer sb=new StringBuffer();
if ("sqlserver".equals(databaseType)) {
sb.append("select t.* from ");
// 原sql 拼接 查詢 row_number()
sb.append("(");
int beginPos = sql.toLowerCase().indexOf("from");
sb.append(sql.substring(0, beginPos));
sb.append(" , ROW_NUMBER() OVER ("+getOrderby(sql)+") AS row_num ");
sb.append(removeOrders(sql).substring(beginPos));
sb.append(") t");
// 拼接外層sql及 分頁查詢條件
sb.append(" where t.row_num between ").append(page.getStartRow()+1).append(" and ")
.append(page.getStartRow() + page.getPageSize());
}else if ("mysql".equals(databaseType)) {
sb.append(sql);
sb.append("  limit "+page.getPageSize()+" offset "+page.getStartRow()+1);
}else if ("postgreSQL".equals(databaseType)) {
sb.append(sql);
sb.append("  limit "+page.getPageSize()+" offset "+page.getStartRow()+1);
}else {
throw new BaseException("不支援當前資料庫分頁");
}
System.out.println("分頁SQL["+sb.toString()+"]");
return listBySql(sb.toString(),rowMapper, args);
}
}
private String getOrderby(String sql) {
Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(sql);
String orderby = "";
while (m.find()) {
     orderby = m.group(); 
}
return orderby;
}


@SuppressWarnings({ "unchecked", "rawtypes" })
private List<T> list(String sql, Object[] args) {
return this.jdbcTemplate.query(sql.toString(), args, new MyRowMapper(this.persistentClass));
}
@SuppressWarnings("unused")
private List<T> listBySql(String sql,RowMapper<T> rowMapper, Object[] args) {
return this.jdbcTemplate.query(sql.toString(), args, rowMapper);
}


/**
* 獲取查詢資料所有記錄數

* @param queryString
*            查詢語句
* @param args
*            引數
* @return 記錄數
*/
public int getResultCount(String queryString, Object... args) {
String countQueryString = " select count (*) " + removeSelect(removeOrders(queryString));
return this.jdbcTemplate.queryForInt(countQueryString, args);
}


private String removeSelect(String hql) {
Assert.hasText(hql);
int beginPos = hql.toLowerCase().indexOf("from");
Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");
return hql.substring(beginPos);
}


private static String removeOrders(String hql) {
Assert.hasText(hql);
Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(hql);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, "");
}
m.appendTail(sb);
return sb.toString();
}
/**
* 查詢單個數值

* @param sql  查詢語句
* @param args  引數
* @return 
*/
/*public int queryForInt(String sql, Object... args) {
return this.jdbcTemplate.queryForInt(sql, args);
}*/

/**
* 查詢單個實提類物件

* @param sql  查詢語句
* @param args  引數
* @return T
*/
public Object queryForObject(String sql, Object... args) {
return  this.jdbcTemplate.queryForObject(sql, args, new MyRowMapper(this.persistentClass));

}

}