自制Mysql資料庫連線工具(含使用說明)
阿新 • • 發佈:2018-12-10
我們在對mysql資料庫進行操作時,就要使用JDBC去連線資料庫,所以程式碼不免要出現大量的冗餘,比如連線,關閉等等實現其實都是一樣的,所以聰明的程式設計師就會將這些重複的功能封裝,簡化使用過程,提高程式碼複用性。
1.BaseDao原始碼
package com.xintoucloud.jdbcutil; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import com.xintoucloud.jdbcutil.exception.NoEntityClassException; import com.xintoucloud.jdbcutil.exception.NoIdException; public class BaseDao <E,P extends Serializable> { //例項類Class物件 private Class<?> entityClass; //實體類對應的表名 private String tableName; //主鍵列名(為了根據id查詢和刪除) private String idColumn; //實體類屬性和表的欄位對映關係的集合(為了拼接SQL語句),save(E entity),update(E endity) private List<PropertyColumnMapper> propertyColumnMappers; //列名和屬性名對映Map(為了通過列名找到屬性名,進行對映一個列值到屬性),為了查詢 private Map<String,String> columnPropertyMap; //Id屬性 private Field idField; protected BaseDao() { //獲取父類的泛型class Type type = this.getClass().getGenericSuperclass(); ParameterizedType parameterizedType = (ParameterizedType)type; entityClass =(Class<?>) (parameterizedType.getActualTypeArguments()[0]); if(entityClass==null){ throw new NoEntityClassException("沒有使用泛型指定實體類"); } columnPropertyMap = new HashMap<>(); scanTableAnnotation(); scanIdProperty(); scanNormalProperty(); } /** * 掃描Table註解:得到表名 */ private void scanTableAnnotation() { Table table = entityClass.getAnnotation(Table.class); if(table != null) { tableName = table.value(); } else { tableName = entityClass.getSimpleName(); } } /** * 掃描Id屬性:為了得到主鍵列和屬性 */ private void scanIdProperty() { boolean hasId = false; Field[] fields = entityClass.getDeclaredFields(); for(int i=0;i<fields.length;i++) { Field field = fields[i]; Id idAnnotation = field.getAnnotation(Id.class); //如果有Id註解 if(idAnnotation != null) { //預設屬性名稱作為主鍵名稱 idColumn = field.getName(); //如果Id註解有value值,那麼主鍵名稱就變成value值 String value = idAnnotation.value(); if(!value.isEmpty()) { idColumn = value; } //賦值idField,(找到了Id屬性) idField = field; columnPropertyMap.put(idColumn, field.getName()); //(找到了Id屬性) hasId = true; } } if(!hasId) { throw new NoIdException("請設定Id標示"); } } /** * 掃描普通屬性 */ private void scanNormalProperty() { Field[] fields = entityClass.getDeclaredFields(); propertyColumnMappers = new ArrayList<>(); for(int i=0;i<fields.length;i++) { Field field = fields[i]; //不管Id屬性 if(field.equals(idField)) { continue; } //判斷是否需要忽略 Transient transientAnnotation = field.getAnnotation(Transient.class); //如果不需要忽略 if(transientAnnotation == null) { Column column = field.getAnnotation(Column.class); String columnName=null; //有Column註解 if(column != null) { //列名就是註解的value columnName = column.value(); } else { //否則是屬性的名稱 columnName = field.getName(); } PropertyColumnMapper propertyColumnMapper = new PropertyColumnMapper(field.getName(),columnName,field.getType()); propertyColumnMappers.add(propertyColumnMapper); columnPropertyMap.put(columnName, field.getName()); } } } /** * 通用的更新方法 * * @param sql * 要執行的SQL語句,引數使用?佔位符 * @param parameters * 佔位符的值,順序和SQL佔位符對應 * @return 更新影響的行數 */ public int update(String sql, Object[] parameters) { Connection conn = JdbcUtil.getConnection(); int affectedRow = 0; try (PreparedStatement st = conn.prepareStatement(sql)) { // 給佔位符賦值 setParameters(st, parameters); affectedRow = st.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } return affectedRow; } /** * 往那張表中填? * 往哪些欄位填(這個表一共有多少欄位?哪些不需要填?) * 主鍵如果是自增不需要填 * * 儲存一個物件 * @param entity 要儲存的物件 * @return 資料表中受影響的行數 * * */ public int save(E entity) { //需要設定的引數數量賦值成需要儲存的普通列的數量 6 int parameterCount = propertyColumnMappers.size(); StringBuilder sb = new StringBuilder("insert into "); sb.append(tableName); sb.append("("); //迴圈實體類屬性和表的欄位對映關係的集合,拼接要新增的列名(除了Id列) //insert into Student(sname, for(int index=0;index<propertyColumnMappers.size();index++) { PropertyColumnMapper propertyMapper = propertyColumnMappers.get(index); sb.append(propertyMapper.getColumnName()); //一個列名後加,分割,最後一個列名後不加 if(index<propertyColumnMappers.size()-1) { sb.append(","); } } //判斷id列是否需要加入 Id idAnnotation = idField.getAnnotation(Id.class); GenarateType genarate = idAnnotation.genarate(); //如果Id是手工設定,拼接Id列名(參與儲存操作) if(genarate == GenarateType.ASSIGNED) { sb.append(","); sb.append(idColumn); } sb.append(") "); sb.append("values "); sb.append("("); //拼接普通列對應的佔位符? for(int index=0;index<propertyColumnMappers.size();index++) { sb.append("?"); if(index<propertyColumnMappers.size()-1) { sb.append(","); } } //如果Id是手工設定,拼接Id列名對應的佔位符 if(genarate == GenarateType.ASSIGNED) { sb.append(",?"); //需要設定的引數數量+1 7 parameterCount++; } //insert into Student(sname,ssex,sage,sdept,leftMoney,birthday,sno) values (?,?,?,?,?,?,?) sb.append(")"); System.out.println(sb.toString()); //引數陣列 7 Object[] parameters = new Object[parameterCount]; //給引數陣列賦值 for(int index=0;index<propertyColumnMappers.size();index++) { PropertyColumnMapper propertyMapper = propertyColumnMappers.get(index); //從實體物件中取值 String propertyName = propertyMapper.getPropertyName(); String getMethodName = null; //如果是boolean if(propertyMapper.getPropertyType().equals(boolean.class)) { getMethodName = "is"+propertyName.substring(0,1).toUpperCase()+propertyName.substring(1); } else { //getNo getMethodName = "get"+propertyName.substring(0,1).toUpperCase()+propertyName.substring(1); } try { //呼叫方法取值放入引數Object陣列 parameters[index] = entityClass.getDeclaredMethod(getMethodName).invoke(entity); } catch (Exception e) { e.printStackTrace(); } } //如果Id列要儲存,獲取Id列對應屬性的值加到引數值陣列中 if(parameterCount > propertyColumnMappers.size()) { try { String getMethodName = "get"+idField.getName().substring(0,1).toUpperCase()+idField.getName().substring(1); //Id列永遠在最後 parameters[propertyColumnMappers.size()] = entityClass.getDeclaredMethod(getMethodName).invoke(entity); } catch (Exception e) { e.printStackTrace(); } } for(Object o : parameters) { System.out.println(o); } return update(sb.toString(), parameters); } /** * update student set sname=?,sage=? where sno=? * 根據Id更新:資料表字段對應的屬性都必須全部賦值,否則將置成屬性預設值 * @param entity 要更新的實體 * @return 受影響的資料行數 */ public int update(E entity) { StringBuilder sb = new StringBuilder("update "); sb.append(tableName); sb.append(" "); sb.append("set "); for(int index=0;index<propertyColumnMappers.size();index++) { PropertyColumnMapper propertyMapper = propertyColumnMappers.get(index); sb.append(propertyMapper.getColumnName()); sb.append("=?"); if(index<propertyColumnMappers.size()-1) { sb.append(","); } } sb.append(" "); sb.append("where "); sb.append(idColumn); sb.append("=?"); //update student set sname=?,ssex=?... where sno=? System.out.println(sb.toString()); /*for(int i=0;i<values.length;i++) { System.out.println(values[i]); }*/ //return update(sb.toString(), values); Object[] parameters = new Object[propertyColumnMappers.size()+1]; for(int index=0;index<propertyColumnMappers.size();index++) { PropertyColumnMapper propertyMapper = propertyColumnMappers.get(index); //從實體物件中取值 String propertyName = propertyMapper.getPropertyName(); String getMethodName = null; //如果是boolean if(propertyMapper.getPropertyType().equals(boolean.class)) { getMethodName = "is"+propertyName.substring(0,1).toUpperCase()+propertyName.substring(1); } else { getMethodName = "get"+propertyName.substring(0,1).toUpperCase()+propertyName.substring(1); } try { //呼叫方法取值放入引數Object陣列 parameters[index] = entityClass.getDeclaredMethod(getMethodName).invoke(entity); } catch (Exception e) { e.printStackTrace(); } } try { String getMethodName = "get"+idField.getName().substring(0,1).toUpperCase()+idField.getName().substring(1); parameters[propertyColumnMappers.size()] = entityClass.getDeclaredMethod(getMethodName).invoke(entity); } catch (Exception e) { e.printStackTrace(); } for(Object o : parameters) { System.out.println(o); } return update(sb.toString(),parameters); } /** * ?刪除的是哪張表的資料? * ?怎麼確定主鍵的名稱? * 根據主鍵查詢一條記錄並封裝為實體物件 * @param idValue id值 */ public E get(P idValue) { String sql = "select * from "+tableName+" where "+idColumn+"=?"; System.out.println("get(sql)="+sql); return get(sql,new Object[] {idValue}); } /** * 根據主鍵刪除一條記錄並封裝為實體物件 * @param idValue id值 * @return 受影響的資料行數 */ public int delete(P idValue) { String sql = "delete from "+tableName+" where "+idColumn+"=?"; System.out.println("delete(sql)="+sql); return update(sql,new Object[] {idValue}); } /** * 統計一個表中的全部記錄行數 * @return 全部記錄行數 */ public int count() { String sql = "select count(*) from "+tableName; return count(sql, null); } /** * 根據傳入的SQL語句統計結果集行數 * @param sql SQL語句 * @param parameters 引數值陣列 * @return 結果集行數 */ public int count(String sql,Object[] parameters) { Connection conn = JdbcUtil.getConnection(); PreparedStatement st = null; ResultSet rs = null; int rowCount = 0; try { st = conn.prepareStatement(sql); // 給佔位符賦值 setParameters(st, parameters); rs = st.executeQuery(); if(rs.next()) { rowCount = rs.getInt(1); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.closeResultSet(rs); JdbcUtil.closeStatement(st); } return rowCount; } /** * 根據查詢SQL語句查詢一條記錄並封裝為實體物件 * @param sql 查詢SQL語句 * @param parameters 佔位符的值,順序和SQL佔位符對應 * @return 返回封裝好的實體物件,如果記錄不存在返回null */ public E get(String sql, Object ... parameters) { Connection conn = JdbcUtil.getConnection(); PreparedStatement st = null; ResultSet rs = null; E obj = null; try { st = conn.prepareStatement(sql); // 給佔位符賦值 setParameters(st, parameters); rs = st.executeQuery(); //String sql = "select bid,bname from board"; if(rs.next()) { //把一行記錄封裝到一個實體物件裡 obj = oneRowToObject(rs); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.closeResultSet(rs); JdbcUtil.closeStatement(st); } return obj; } /** * 根據查詢SQL語句查詢一條記錄並封裝為實體物件 * @param sql 查詢SQL語句 * @param parameters 佔位符的值,順序和SQL佔位符對應 * @param rowMapper 行對映物件 * @return 返回封裝好的實體物件,如果記錄不存在返回null */ public <V> V get(String sql,RowMapper<V> rowMapper, Object...parameters) { Connection conn = JdbcUtil.getConnection(); PreparedStatement st = null; ResultSet rs = null; V obj = null; try { st = conn.prepareStatement(sql); // 給佔位符賦值 setParameters(st, parameters); rs = st.executeQuery(); //String sql = "select bid,bname from board"; if(rs.next()) { //把一行記錄封裝到一個實體物件裡 obj = rowMapper.mapRow(rs); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.closeResultSet(rs); JdbcUtil.closeStatement(st); } return obj; } /** * 根據查詢SQL語句查詢多條記錄並封裝為實體物件集合 * @param sql 查詢SQL語句 * @param parameters 佔位符的值,順序和SQL佔位符對應 * @return 返回封裝好的實體物件集合,如果記錄不存在返回一個空集合 */ public List<E> list(String sql, Object...parameters) { Connection conn = JdbcUtil.getConnection(); PreparedStatement st = null; ResultSet rs = null; List<E> list = new ArrayList<>(); try { st = conn.prepareStatement(sql); // 給佔位符賦值 setParameters(st, parameters); rs = st.executeQuery(); while(rs.next()) { //把一行記錄封裝到一個實體物件裡 E obj = oneRowToObject(rs); list.add(obj); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.closeResultSet(rs); JdbcUtil.closeStatement(st); } return list; } /** * 單表分頁查詢 * @param start 開始位置 * @param limit 限定行數 * @return 返回封裝好的實體物件集合,如果記錄不存在返回一個空集合 */ public List<E> list(int start,int limit) { String sql = "select * from "+tableName+" limit ?,?"; return list(sql,new Object[] {start,limit}); } /** * 單表分頁查詢 * @param start 開始位置 * @param limit 限定行數 * @return 返回封裝好的實體物件集合,如果記錄不存在返回一個空集合 */ public void list(Page<E> page) { if(page.autoCount) { int totalCount = count(); page.setTotalCount(totalCount); } List<E> data = list(page.start,page.limit); page.setResult(data); } /** * 多表連線查詢 * 根據查詢SQL語句查詢多條記錄並封裝為實體物件集合 * @param sql 查詢SQL語句 * @param parameters 佔位符的值,順序和SQL佔位符對應 * @param rowMapper 行的對映器 * @return 返回封裝好的實體物件集合,如果記錄不存在返回一個空集合 */ public <V> List<V> listJoin(String sql,RowMapper<V> rowMapper, Object...parameters) { Connection conn = JdbcUtil.getConnection(); PreparedStatement st = null; ResultSet rs = null; List<V> list = new ArrayList<>(); try { st = conn.prepareStatement(sql); // 給佔位符賦值 setParameters(st, parameters); rs = st.executeQuery(); while(rs.next()) { //把一行記錄封裝到一個實體物件裡 //回撥介面 V obj = rowMapper.mapRow(rs); list.add(obj); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.closeResultSet(rs); JdbcUtil.closeStatement(st); } return list; } /** * 一行到一個物件的對映 * @param rs 結果集 * @return 設定好資料的一個物件 * @throws InstantiationException * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException * @throws SQLException */ @SuppressWarnings("unchecked") private E oneRowToObject(ResultSet rs) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SQLException { E obj = (E) entityClass.getConstructor().newInstance(); //獲取結果集元資料 ResultSetMetaData rsmd = rs.getMetaData(); for(int i=0;i<rsmd.getColumnCount();i++) { //獲取一列的列名和資料型別 String columnName = rsmd.getColumnName(i+1); Integer columnType = rsmd.getColumnType(i+1); //拼實體物件裡對應的set方法名 //String methodName = "set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1); //sno -> no String fieldName = columnPropertyMap.get(columnName); if(fieldName!=null) { String methodName = "set"+columnPropertyMap.get(columnName).substring(0,1).toUpperCase()+columnPropertyMap.get(columnName).substring(1); //System.out.println(methodName); switch(columnType) { case java.sql.Types.INTEGER: case java.sql.Types.SMALLINT: case java.sql.Types.TINYINT: Method method = null; try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, int.class); if(method != null) { method.invoke(obj, rs.getInt(columnName)); } } catch (Exception e) { //再試使用Integer型別對映 method = entityClass.getMethod(methodName, Integer.class); if(method != null) { method.invoke(obj, rs.getInt(columnName)); } } break; case java.sql.Types.BIGINT: try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, long.class); if(method != null) { method.invoke(obj, rs.getLong(columnName)); } } catch (Exception e) { //先嚐試使用Integer型別對映 method = entityClass.getMethod(methodName, Long.class); if(method != null) { method.invoke(obj, rs.getLong(columnName)); } } break; case java.sql.Types.BIT: try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, boolean.class); if(method != null) { method.invoke(obj, rs.getBoolean(columnName)); } } catch (Exception e) { //先嚐試使用Integer型別對映 method = entityClass.getMethod(methodName, int.class); if(method != null) { method.invoke(obj, rs.getInt(columnName)); } } break; case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: case java.sql.Types.LONGVARCHAR: try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, String.class); if(method != null) { method.invoke(obj, rs.getString(columnName)); } } catch (NoSuchMethodException e) { } break; case java.sql.Types.DATE: try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, String.class); if(method != null) { method.invoke(obj, rs.getString(columnName)); } } catch (Exception e) { //先嚐試使用Integer型別對映 method = entityClass.getMethod(methodName, Date.class); if(method != null) { method.invoke(obj, rs.getDate(columnName)); } } break; case java.sql.Types.TIMESTAMP: try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, String.class); if(method != null) { method.invoke(obj, rs.getString(columnName)); } } catch (Exception e) { //先嚐試使用Integer型別對映 method = entityClass.getMethod(methodName, Date.class); if(method != null) { method.invoke(obj, rs.getTimestamp(columnName)); } } break; case java.sql.Types.TIME: try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, String.class); if(method != null) { method.invoke(obj, rs.getString(columnName)); } } catch (Exception e) { //先嚐試使用Integer型別對映 method = entityClass.getMethod(methodName, Date.class); if(method != null) { method.invoke(obj, rs.getTime(columnName)); } } break; case java.sql.Types.FLOAT: case java.sql.Types.REAL: case java.sql.Types.DOUBLE: try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, double.class); if(method != null) { method.invoke(obj, rs.getDouble(columnName)); } } catch (Exception e) { //先嚐試使用Integer型別對映 method = entityClass.getMethod(methodName, String.class); if(method != null) { method.invoke(obj, rs.getString(columnName)); } } break; case java.sql.Types.DECIMAL: try { //先嚐試使用int型別對映 method = entityClass.getMethod(methodName, BigDecimal.class); if(method != null) { method.invoke(obj, rs.getBigDecimal(columnName)); } } catch (Exception e) { //先嚐試使用Integer型別對映 method = entityClass.getMethod(methodName, String.class); if(method != null) { method.invoke(obj, rs.getString(columnName)); } } break; default: break; } } } return obj; } /** * 私有方法:給SQL語句佔位符賦值 * @param st PreparedStatement物件 * @param parameters 引數陣列 * @throws SQLException SQL異常 */ private void setParameters(PreparedStatement st, Object[] parameters) throws SQLException { if (parameters != null && parameters.length > 0) { for (int i = 0; i < parameters.length; i++) { st.setObject(i + 1, parameters[i]); } } } }
2.column
package com.xintoucloud.jdbcutil; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 對映實體屬性名對應表的列名 * @author Administrator * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { /** * 對映的列名,預設和屬性名一樣 * @return */ String value(); }
3.generateType
package com.xintoucloud.jdbcutil;
public enum GenarateType {
AUTO_INCREMENT,
ASSIGNED
}
4.id
package com.xintoucloud.jdbcutil; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 標示一個主鍵的註解,只能用到屬性上 * @author Administrator * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Id { /** * 對應的列名,預設為""和屬性名一樣 * @return */ String value() default ""; /** * 主鍵生成型別,預設自動增長 * @return */ GenarateType genarate() default GenarateType.AUTO_INCREMENT; }
5.JdbcUtil
package com.xintoucloud.jdbcutil;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* 資料庫連線工具類
* @author [email protected]
*
*/
public class JdbcUtil {
private static String DRIVER;
private static String URL;
private static String USER;
private static String PASSWORD;
private static final ThreadLocal<Connection> THREAD_LOCAL = new ThreadLocal<>();
static {
InputStream is = JdbcUtil.class.getResourceAsStream("/db-config.properties");
Properties properties = new Properties();
try {
properties.load(is);
DRIVER = properties.getProperty("DRIVER_CLASS");
URL = properties.getProperty("URL");
USER = properties.getProperty("USER");
PASSWORD = properties.getProperty("PASSWORD");
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 獲取資料庫連線
* @return 資料庫連線,如果有異常返回null
*/
public static Connection getConnection() {
//System.out.println("getConnection");
//嘗試從本地執行緒變數中獲取連線
Connection conn = THREAD_LOCAL.get();
//如果本地執行緒變數中沒有連線
if(conn == null) {
try {
//從資料庫獲取連線
conn = DriverManager.getConnection(URL,USER,PASSWORD);
//放入本地執行緒變數
THREAD_LOCAL.set(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
return conn;
}
/**
* 開啟事務
*/
public static void beginTransaction() {
Connection conn = getConnection();
if(conn != null) {
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 提交事務
*/
public static void commit() {
Connection conn = getConnection();
if(conn != null) {
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 回滾事務
*/
public static void rollback() {
Connection conn = getConnection();
if(conn != null) {
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 關閉結果集
* @param rs
*/
public static void closeResultSet(ResultSet rs) {
try {
if(rs != null) {
rs.close();
rs = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 關閉Statement
* @param st
*/
public static void closeStatement(Statement st) {
try {
if(st != null) {
st.close();
st = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 關閉連線
*/
public static void closeConnection() {
Connection conn = THREAD_LOCAL.get();
if(conn != null) {
try {
conn.close();
//從執行緒本地變數中移除
THREAD_LOCAL.remove();
conn = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 釋放資源
* @param conn 連線物件
* @param st Statement物件
* @param rs ResultSet物件
*/
public static void closeAll(Connection conn,Statement st,ResultSet rs) {
try {
if(rs != null) {
rs.close();
}
if(st != null) {
st.close();
}
if(conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
6.Page
package com.xintoucloud.jdbcutil;
import java.util.ArrayList;
import java.util.List;
/**
*
* @param <T>
* Page中記錄的型別.
*
* @author YCCN
*/
public class Page<T> {
// -- 分頁引數 --//
protected int start;
protected int limit;
// 是否自動查詢總條數
protected boolean autoCount = true;
// -- 返回結果 --//
protected List<T> result = new ArrayList<T>();
// 儲存資料總條數
protected int totalCount;
// -- 建構函式 --//
public Page() {
}
public Page(int start, int limit) {
this.start = start;
this.limit = limit;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
/**
* 獲得查詢物件時是否先自動執行count查詢獲取總記錄數, 預設為false.
*/
public boolean isAutoCount() {
return autoCount;
}
/**
* 設定查詢物件時是否自動先執行count查詢獲取總記錄數.
*/
public void setAutoCount(final boolean autoCount) {
this.autoCount = autoCount;
}
/**
* 獲得頁內的記錄列表.
*/
public List<T> getResult() {
return result;
}
/**
* 設定頁內的記錄列表.
*/
public void setResult(final List<T> result) {
this.result = result;
}
/**
* 獲得總記錄數, 預設值為0.
*/
public long getTotalCount() {
return totalCount;
}
/**
* 設定總記錄數.
*/
public void setTotalCount(final int totalCount) {
this.totalCount = totalCount;
}
/**
* 獲得總頁數
*
* @return 總頁數
*/
public int getTotalPages() {
if (autoCount && totalCount != -1 && limit != -1) {
return totalCount % limit == 0 ? totalCount / limit : totalCount / limit + 1;
}
return 0;
}
/**
* 獲得當前頁
*
* @return 當前頁
*/
public int getPageIndex() {
if (getTotalPages() > 0) {
return start / limit + 1;
}
return 0;
}
/**
* 是否有下一頁
*
* @return
*/
public boolean isNextPage() {
if (getPageIndex() < getTotalPages()) {
return true;
}
return false;
}
/**
* 是否有上一頁
*
* @return
*/
public boolean isPrePage() {
if (getPageIndex() > 1) {
return true;
}
return false;
}
}
7.PropertyColumnMapper
package com.xintoucloud.jdbcutil;
/**
* 實體屬性和列名和屬性型別的對映
* @author Administrator
*
*/
class PropertyColumnMapper {
private String propertyName;
private String columnName;
private Class<?> propertyType;
public PropertyColumnMapper() {}
public PropertyColumnMapper(String propertyName, String columnName,Class<?> propertyType) {
super();
this.propertyName = propertyName;
this.columnName = columnName;
this.propertyType = propertyType;
}
public String getColumnName() {
return columnName;
}
public String getPropertyName() {
return propertyName;
}
public Class<?> getPropertyType() {
return propertyType;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public void setPropertyType(Class<?> propertyType) {
this.propertyType = propertyType;
}
}
8.RowMapper
package com.xintoucloud.jdbcutil;
import java.sql.ResultSet;
/**
* 結果集行的對映(主要對應多表連線查詢)
* @author Administrator
*
*/
public interface RowMapper<V> {
/**
* 結果集一行對映為一個物件
* @param rs 結果集
* @return 對映好的物件
*/
V mapRow(ResultSet rs);
}
9.Table
package com.xintoucloud.jdbcutil;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 設定一個實體對應的表名,如果沒有設定則和實體類名一樣
* @author Administrator
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value() ;
}
10.Transient
package com.xintoucloud.jdbcutil;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 標示一個不持久化的屬性的註解,只能用到屬性上
* @author Administrator
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transient {
}
11.NoEntityClassException
package com.xintoucloud.jdbcutil.exception;
public class NoEntityClassException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = -6894334255503447296L;
public NoEntityClassException(String message) {
super(message);
}
}
12.NoIdException
package com.xintoucloud.jdbcutil.exception;
public class NoIdException extends RuntimeException{
/**
*
*/
private static final long serialVersionUID = -981438111240259266L;
public NoIdException(String message) {
super(message);
}
}