框架架構-運用泛型、反射BaseDao基本實現springJPA

這幾天都在學習springJPA對單表的操作,感覺非常方便,只用實現基本的接口就能對所有的類增、刪、查、改進行操作基本不用寫任何的代碼,這樣是不是能簡化項目的開發時間,運用反射和泛型可以實現基於jdbc的BaseDao抽象類,實現增、刪、查、改。只用繼承這個類就能實現對所有的類進行操作了。

首先我們要先連接數據庫:

public class DBHelper {

        private static String dbUrl="jdbc:mysql://localhost:3306/sushe";
        private static String dbUser="root";
        private static String dbPassword="123456";
        private static String jdbcName="com.mysql.jdbc.Driver";

        /**
         * DBHelper的單例
         */
        private static DBHelper instance = null;  

        private DBHelper() {}  

        /**
         * 獲取DBHelper的單例
         * @return
         */
        public static DBHelper getInstance() {  
            if (instance == null) {  
                synchronized (DBHelper.class) {  
                    if (instance == null) {  
                        instance = new DBHelper();  
                    }  
                }  
            }  
            return instance;  
        }  

        static {  
            try {  
                //加載數據庫驅動
                Class.forName(jdbcName);  
            } catch (ClassNotFoundException e) {  
                throw new ExceptionInInitializerError(e);  
            }  
        }  

        public Connection getConnection() throws SQLException {  
            //獲取數據庫連接
            return DriverManager.getConnection(dbUrl, dbUser, dbPassword);  
        }  

        /**
         * 釋放資源
         * @param rs
         * @param st
         * @param conn
         */
        public void free(ResultSet rs, Statement st, Connection conn) {  
            try {  
                if (rs != null)  
                    rs.close();  
            } catch (SQLException e) {  
                e.printStackTrace();  
            } finally {  
                try {  
                    if (st != null)  
                        st.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                } finally {  
                    if (conn != null)  
                        try {  
                            conn.close();  
                        } catch (SQLException e) {  
                            e.printStackTrace();  
                        }  
                }  
            }  
        }  

        public static void main(String[] args) throws SQLException {
        }
}

由於要使用fastjson 把從數據庫中查詢的數據解析成對象所以我們需要一個工具類實現數據解析。

/**
 * 工具類解析ResultSet
 * @author xiaoyu_pc
 */
public class GetType {
    @SuppressWarnings("unused")
    public void getType(ResultSet rs, ResultSetMetaData rsmd, JSONObject obj)
            throws SQLException {
        int total_rows = rsmd.getColumnCount();
        for (int i = 0; i < total_rows; i++) {
            String columnName = rsmd.getColumnLabel(i + 1);
//            if (obj.has(columnName)) {
//                columnName += "1";
//            }
            try {
                switch (rsmd.getColumnType(i + 1)) {
                case java.sql.Types.ARRAY:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getArray(columnName))?rs.getArray(columnName):"");
                    break;
                case java.sql.Types.BIGINT:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getInt(columnName))?rs.getInt(columnName):"");
                    break;
                case java.sql.Types.BOOLEAN:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getBoolean(columnName))?rs.getBoolean(columnName):"");
                    break;
                case java.sql.Types.BLOB:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getBlob(columnName))?rs.getBlob(columnName):"");
                    break;
                case java.sql.Types.DOUBLE:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getDouble(columnName))?rs.getDouble(columnName):"");
                    break;
                case java.sql.Types.FLOAT:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getFloat(columnName))?rs.getFloat(columnName):"");
                    break;
                case java.sql.Types.INTEGER:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getInt(columnName))?rs.getInt(columnName):"");
                    break;
                case java.sql.Types.NVARCHAR:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getNString(columnName))?rs.getNString(columnName):"");
                    break;
                case java.sql.Types.VARCHAR:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getString(columnName))?rs.getString(columnName):"");
                    break;
                case java.sql.Types.TINYINT:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getInt(columnName))?rs.getInt(columnName):"");
                    break;
                case java.sql.Types.SMALLINT:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getInt(columnName))?rs.getInt(columnName):"");
                    break;
                case java.sql.Types.DATE:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getDate(columnName))?rs.getDate(columnName):"");
                    break;
                case java.sql.Types.TIMESTAMP:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getTimestamp(columnName))?rs.getTimestamp(columnName):"");
                    break;
                default:
                    obj.put(columnName, !StringUtils.isEmpty(rs.getObject(columnName))?rs.getObject(columnName):"");
                    break;
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
}

然後我們來實現BaseDao的實現由於代碼太多我只介紹實現新增和查詢方法:

@Component
@Repository
public abstract class BaseDao<T>{

    public Class entityclass;

    public BaseDao (Class<T> entityclass){
        this.entityclass = entityclass;
    }

    /**
     * 新增
     * @param entityclass
     * @return
     * @throws NoSuchMethodException
     * @throws Exception
     * 目前只支持Interger 和 String 類型的字段
     */
    public boolean add(Object entityclass) throws NoSuchMethodException, Exception {
        Statement stat = null;
        ResultSet rs = null;
        PreparedStatement pstmt = null;
        DBHelper instance = DBHelper.getInstance();
        Connection conn = instance.getConnection();
//      Connection conn = new DBHelper().getConn();
        try {
            String values = "";
            //獲取傳入的實體類的類名
            String className = entityclass.getClass().getSimpleName();
            Field[] declaredFields = entityclass.getClass().getDeclaredFields();
            for(int j=0;j<declaredFields.length;j++){
                if(!declaredFields[j].getName().equals("serialVersionUID")){
                    if(j != declaredFields.length-1){
                        //自動拼接sql
                        values += "?"+",";
                    }else{
                        values += "?";
                    }
                }
            }
            //原型是 insert into "+className+" values(?,?,?,?....)
            String sql = "insert into "+className+" values("+values+")" ;
            //執行sql語句
            pstmt = (PreparedStatement) conn.prepareStatement(sql);
            for(int i=0;i<declaredFields.length;i++){
                System.out.println(declaredFields[i].getName());
                if(i > 0){
                    //如果類型是Integer
                    if (declaredFields[i].getGenericType().toString().equals("class java.lang.Integer")) {  
                        Method m = (Method) entityclass.getClass().getMethod(  
                                "get" + getMethodName(declaredFields[i].getName()));  
                        Integer val = (Integer) m.invoke(entityclass);
                        pstmt.setString(i,(val != null?Integer.toString(val):null));
                    }
                    //如果類型是String
                    if (declaredFields[i].getGenericType().toString().equals("class java.lang.String")) {
                        Method m = entityclass.getClass().getMethod("get"+ getMethodName(declaredFields[i].getName()));
                        String parmeter = (String) m.invoke(entityclass);
                        pstmt.setString(i,!StringUtils.isEmpty(parmeter)?parmeter:null);
                    }
                }
            }
            int issuccess = pstmt.executeUpdate();
            return issuccess > 0? true : false;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            instance.free(rs, stat, conn);
        }
        return false;
    }

    /**
     * 查詢所有
     * @param strwhere
     * @param strorder
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    @SuppressWarnings("unchecked")
    public List<T> findByAll(String strwhere,String strorder) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
        try {
             String className = entityclass.getSimpleName();  
             String sql="select * from "+className+"";
            if(!StringUtils.isEmpty(strwhere))
            {
                sql+=" where "+strwhere;
            }
            if(!StringUtils.isEmpty(strorder))
            {
                sql+=" order by "+strorder;
            }
            Statement stat = null;
            ResultSet rs = null;
            DBHelper instance = DBHelper.getInstance();
            Connection conn = instance.getConnection();
//          Connection conn = new DBHelper().getConn();
            List<T> list= new ArrayList<T>();
            try{
                GetType getType = new GetType();
                stat = conn.createStatement();
                rs = stat.executeQuery(sql);
                JSONArray array = new JSONArray();
                while(rs.next()){
                    JSONObject obj = new JSONObject();
                    ResultSetMetaData metaData = rs.getMetaData();
                    //傳result和JsonObject
                    getType.getType(rs, metaData, obj);
                    array.add(obj);  //把jsonobject添加到jsonArray中
                }
                Class<?> clazz = Class.forName(entityclass.getCanonicalName());
                list = (List<T>) JSON.parseArray(array.toJSONString(),clazz);
                System.out.println(""+list);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                instance.free(rs, stat, conn);
            }
            return list;
        } catch (SecurityException e1) {
            e1.printStackTrace();
        }
        return null;
    }


    /**
     * 把頭字母是小寫替換成大寫
     * @param fildeName
     * @return
     * @throws Exception
     */
    private static String getMethodName(String fildeName) throws Exception{  
        char[] charArray = fildeName.toCharArray();
        int asiiValue=(int) charArray[0];
        if(asiiValue >=97 && asiiValue<=122){
            byte[] items = fildeName.getBytes();  
            items[0] = (byte) ((char) items[0] - 'a' + 'A');  
            return new String(items);
        }else{
            return fildeName;  
        }
    }  
}

然後我們需要的是繼承這個實體類

用戶登錄接口AdminService

@Repository
public interface AdminService {

    /**
     * 用戶管理接口
     * 如果要添加新的方法
     * 比如: Admin findByName(String name);
     */
}

用戶登錄類 AdminServiceImpl

@Component
@Service
public class AdminServiceImpl extends BaseDao<Admin> implements AdminService {

    public AdminServiceImpl(Class<Admin> entityclass) {
        super(entityclass);
    }


}

我們需要一個Controller來測試這個類是否能用:

@Controller
public class AdminController { 

    private  AdminServiceImpl adminserviceimpl = new AdminServiceImpl(Admin.class);

    @ResponseBody
    @RequestMapping(value="/findAll")
    public List<Admin> findAll() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
        List<Admin> list;
        try {
            list = adminserviceimpl.findByAll(null,null);
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @ResponseBody
    @RequestMapping(value="/add")
    public boolean add() throws NoSuchMethodException, Exception{
        Admin admin = new Admin();
        admin.setAdmin_ID(5);
        admin.setAdmin_Name("張三");
        admin.setAdmin_Username("zhangsan");
        admin.setAdmin_Password("123");
        admin.setAdmin_Tel("");
        admin.setAdmin_Sex("");
        boolean isSuccess = adminserviceimpl.add(admin);
        System.out.println(isSuccess);
        return true;
    }

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