今天閒着無聊,用反射、註解及DBUtils對Dao層進行了抽取,實現了對基礎CRUD的操作,上代碼:
接口
package com.fly.utils;
import java.sql.SQLException;
import java.util.List;
public interface BaseDao<T> {
public T getEntityById(Object id) throws SQLException;
public List<T> getAllEntities() throws SQLException;
public List<T> getAllEntitiesForPage(PageBean<T> pageBean) throws SQLException;
public int deleteEntityById(Object id) throws SQLException;
public int updateEntity(T t) throws SQLException;
public int saveEntity(T t) throws SQLException;
}
實現類:
package com.fly.utils;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
public class BaseDaoImpl<T> implements BaseDao<T> {
private Class classT;
private Field idField;
private List<Field> normalFields;
public BaseDaoImpl() {
//獲取泛型參數類型
ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
classT = (Class) type.getActualTypeArguments()[0];
//通過註解的方式,獲取Id字段以及普通字段
Field[] fields = classT.getDeclaredFields();
normalFields = new ArrayList<>();
for (Field field : fields) {
boolean isId = field.isAnnotationPresent(Id.class);
boolean isNoneProperty = field.isAnnotationPresent(NoneProperty.class);
if (isId) {
idField = field;
} else if (!isNoneProperty) {
normalFields.add(field);
}
}
}
/**
* 查詢單條數據,簡單
*/
@Override
public T getEntityById(Object id) throws SQLException {
QueryRunner qr = new QueryRunner();
String sql = "select * from " + classT.getSimpleName().toLowerCase() + " where " + idField.getName() + " = ?";
Object[] params = {id};
T t = qr.query(C3P0Utils.getConnnection(), sql, new BeanHandler<T>(classT), params);
return t;
}
/**
* 查詢所有數據,簡單
*/
@Override
public List<T> getAllEntities() throws SQLException {
QueryRunner qr = new QueryRunner();
String sql = "select * from " + classT.getSimpleName().toLowerCase();
List<T> list = qr.query(C3P0Utils.getConnnection(), sql, new BeanListHandler<T>(classT));
return list;
}
/**
* 獲取分頁數據
*/
@Override
public List<T> getAllEntitiesForPage(PageBean<T> pageBean) throws SQLException {
QueryRunner qr = new QueryRunner();
String sql = "select * from " + classT.getSimpleName().toLowerCase() + " limit ?,?";
Object[] params = {pageBean.getStartIndex(), pageBean.getPageSize()};
List<T> list = qr.query(C3P0Utils.getConnnection(), sql, new BeanListHandler<T>(classT), params);
return list;
}
/**
* 刪除單條數據,簡單
*/
@Override
public int deleteEntityById(Object id) throws SQLException {
QueryRunner qr = new QueryRunner();
String sql = "delete from " + classT.getSimpleName().toLowerCase() + " where " + idField.getName() + " = ?";
Object[] params = {id};
int rows = qr.update(C3P0Utils.getConnnection(), sql, params);
return rows;
}
/**
* 更新單條數據,複雜
* 通過反射找到所有字段
* 通過反射獲取各字段具體值
* 組合sql語句
* 組合參數數組
*/
@Override
public int updateEntity(T t) throws SQLException {
QueryRunner qr = new QueryRunner();
String sql = "update " + classT.getSimpleName().toLowerCase() + " set ";
List<Object> paramList = new ArrayList<>();
for (int i = 0; i < normalFields.size(); i++) {
paramList.add(getProperty(t, normalFields.get(i)));
if (i == normalFields.size() - 1) {
sql += normalFields.get(i).getName() + "=? ";
} else {
sql += normalFields.get(i).getName() + "=?,";
}
}
paramList.add(getProperty(t, idField));
sql += "where " + idField.getName() + "=?";
Object[] params = paramList.toArray();
int rows = qr.update(C3P0Utils.getConnnection(), sql, params);
return rows;
}
/**
* 保存單條數據,複雜
* 通過反射找到所有字段
* 通過反射獲取各字段具體值
* 組合sql語句
* 組合參數數組
*/
@Override
public int saveEntity(T t) throws SQLException {
QueryRunner qr = new QueryRunner();
String sql = "insert into " + classT.getSimpleName().toLowerCase() + " (" + idField.getName();
String sql2 = ") values (?";
List<Object> paramList = new ArrayList<>();
paramList.add(getProperty(t, idField));
for (int i = 0; i < normalFields.size(); i++) {
paramList.add(getProperty(t, normalFields.get(i)));
sql += "," + normalFields.get(i).getName();
sql2 += ",?";
}
sql += sql2 + ")";
System.out.println(sql);
Object[] params = paramList.toArray();
int rows = qr.update(C3P0Utils.getConnnection(), sql, params);
return rows;
}
/**
* 通過反射獲取字段的值
*/
private Object getProperty(T t, Field field) {
String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
try {
Method getter = classT.getMethod(getterName);
return getter.invoke(t);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
還有兩個註解:
Id註解
package com.fly.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
}
非字段註解
package com.fly.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoneProperty {
}