用反射、註解及DBUtils對Dao層抽取

今天閒着無聊,用反射、註解及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 {

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章