反射應用

来源:http://www.cnblogs.com/letben/archive/2016/02/07/5184760.html
-Advertisement-
Play Games

一大段很坑爹的代碼,總之我自己也不想看第二遍了,但是還是多少有些可取之處的。 對於單表的增刪改查做的基本上通用了,並且希望在多表操作的時候也一樣好用,只不過後來沒時間繼續做了。對於多表的部分,想盡辦法在避免了。當時遇到的一個 比較嚴重的bug就是 主鍵id 那塊兒,出了點兒問題,後來就單獨設置了一個


一大段很坑爹的代碼,總之我自己也不想看第二遍了,但是還是多少有些可取之處的。

對於單表的增刪改查做的基本上通用了,並且希望在多表操作的時候也一樣好用,只不過後來沒時間繼續做了。對於多表的部分,想盡辦法在避免了。當時遇到的一個 比較嚴重的bug就是 主鍵id 那塊兒,出了點兒問題,後來就單獨設置了一個主鍵的欄位用以標識。這樣的代價就是 要多傳遞 一個 參數 進來。

開始用反射寫出對於單表操作,甚至部分多表以後,還是 挺自大的,直到看見了hibernate 可以 對中間表操作以後就慫了。但是老實講,這些東西還是比較有可取之處的。至少很不錯的拼接了資料庫查詢語句。用了一些反射。如果有興趣歡迎探討,當時在製作的時候還是寫了一些註釋的,希望不會那麼難看,當然這套東西針對 的 mysql資料庫。

有興趣可以看看。

 

這個應用主要是針對,資料庫存取數據的,畢竟我們在操作的時候不希望每次都寫一個 死的東西,來單獨進行增刪改查,那麼為了實現通用就要傳一個 通用的東西,反射能夠最大限度的滿足我們這個 需要,也為了最終實現,可復用可擴展,可維護,靈活性好這個終極目標,對於增刪該查的操作,只要傳遞當前類的對象,其他的dao層繼承了baseDao,然後就可以直接調用通過 addItem(Object) 或者 deleteItem(Object)就可以實現了。

【剛想起來

但是這段程式,並跑不起來,因為 下麵還有一層封裝的是jdbc,這裡面調用了預狀態通道,也就是連接資料庫的部分。在jdbc裡面再把剩餘的部分發上來吧。下麵這段代碼,講真,前不著村後不著店,就是一個 baseDao。不能針對業務層封裝進行持久化,也不能連接資料庫完成存取任務】

 

package com.venushalo.dao;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.letben.tag.PageBean;
import com.venushalo.util.JDBCTemplate;
/**
 * v 1.0 有三個 查詢方法,查詢所有用戶,根據id查詢一個 用戶,根據用戶名和密碼 查詢一個用戶
 * v 2.0 增加了 增刪改三個 方法
 * v 3.0 不斷做了各種修改,忘記都做了什麼了
 * v 4.0 就算目前這個 版本吧。
 * v 5.0 jdbc模板裡面,不能關閉資源,要在 這裡面關閉。
 * v 5.1 真實關閉資源。
 * v 5.2 得到 表中元組數量判定是否是 子表。
 * v 5.21 修複了一個小bug。分頁查詢結果為零時,返回1避免報錯。//事實上這個 bug應該由分頁來實現,並且也已經實現了
 * 
 * javaBean名:User.
 * @author Letben 
 * TaughtBy Salmon
 *
 */
public class BaseDao {
    /*
     * 得到列表,查詢某一個id都是十分必要的。
     * 可以做login的,
     * id的,
     * allObject全部列表的。
     * 修改的話,就aoe修改。
     * 刪除做一個@deprecated。表示不建議使用。
     * insert?
     * 
     * 用就用,不用就放裡面,他只是一個方法。
     * 
     * */
    protected JDBCTemplate jt;
    /**
     * 構造方法,得到JDBC模板
     */
    public BaseDao(){
        jt = new JDBCTemplate();
    }
    /**
     * 沒有實現
     * 因為不建議刪除所以我們這樣寫了一句話,以強調,你確定要刪除,但是我們仍然允許使用。
     * 最好提供一個重載,利用id
     * TODO
     * @param object
     * @return
     */
    @Deprecated
    public boolean deleteItem(Object object){
        return false;
    }
    /**
     * sql = "delete from c對應的表 where idInTable=id";
     * sql = "delete from user_tb where user_id=1";
     * 可是這樣都不知道從哪個表裡面刪,還需要傳一個Class
     * 因為不建議刪除所以我們這樣寫了一句話,以強調,你確定要刪除,但是我們仍然允許使用。
     * @param id
     * @return
     */
    @Deprecated
    public boolean deleteItem(Class c,String id,String primaryIdInTable){
        
        //sql = "delete from user_tb where user_id=?";
        String tableName = getTableName(c);
        String sql = "delete from "+tableName+" where "+primaryIdInTable+"=?";
        List params = new ArrayList();
        params.add(id);
        System.out.println(sql.toString());
        boolean flag = jt.updateData(sql, params);
        jt.closeRes();
        return flag;
    }
    /**
     * 更新一個對象,只要傳入一個對象。這是 那個 有bug的方法啊!!!,如果 id不重覆的話 這樣修改 是可以的。
     * 消除了外鍵關鍵字的bug。
     * 並未考慮到如果當前對象不存在的情況。
     * @param object
     * @return
     */
    public boolean updateItem(Object object){//傳一個對象,就能夠修改對象的值,當然前提是,這個對象是完整的。
        
        //update user_tb set user_name=?,user_password=?,user_type=?,user_age=?,user_address where user_id=?
        //看來需要修改addItem裡面的方法了。因為感覺這個不能,在用list一個一個添加了。  試試看
        StringBuffer sql = new StringBuffer("update ");
        Class c = object.getClass();
        String tableName = getTableName(c);
        sql.append(tableName+" set ");//update user_tb set 
        //拼出來需要屬性,這樣的話就得拿到 資料庫中的列名,也就是對應bean中的 屬性名。
        Method[] methods = c.getMethods();
        List fieldNames = new ArrayList();
        List fieldValues = new ArrayList();
        for (Method method : methods) {
            String methodName = method.getName();
            if(methodName.startsWith("get")&&!methodName.equalsIgnoreCase("getclass")){//從object屬性裡面取得值。不過是用get好還是 set好?針對於修改來講,我認為是set好,因為那個getAllPrice()方法,allPrice並非是一個可以被設置的值。一定要取到可以被設置的方法。
                String fieldName = methodName.substring(3);//屬性名
                fieldNames.add(fieldName);
                try {
                    fieldValues.add(method.invoke(object, new Object[]{}));//不過,還是有bug那就只能不允許getAllPrice()的出現或者 自定義標簽來實現,後面慢慢再想辦法。
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        String fieldId = null;
        String fieldIdValue = null;
        int commaCount=0;
        int fieldCount = fieldNames.size();
        for(int i=0;i<fieldCount;i++){
            {    
                // 拼接字元串方法一。
                //這個在不同的版本裡面這個 計數的方式 不一樣!!!,不是不一樣因為讀取的順序是隨機的
                //所以有時候就讀到了帶id的方法,有時候沒有讀到,結果是,有時候就多一個 有時候就少一個。
                if(!fieldNames.get(i).toString().contains("id")&&i<fieldNames.size()-2){//如果該欄位不包含id,前面的欄位,加","
                    sql.append(fieldNames.get(i)+"='"+fieldValues.get(i)+"',");
                }else if(!fieldNames.get(i).toString().contains("id")&&i==fieldNames.size()-2){//最後一個要被修改的欄位
                    sql.append(fieldNames.get(i)+"='"+fieldValues.get(i)+"'");
                }else{
                    //sql.append(" where "+fieldNames.get(i)+"='"+fieldValues.get(i)+"'");
                    //update user_tb set  where User_id='1'User_name='lifei',User_type='1',User_age='23',User_address='北京',User_password='111111'
                    fieldId=fieldNames.get(i).toString();
                    fieldIdValue = fieldValues.get(i).toString();
                    //本來在下麵想再遍歷一次的,但是覺得這樣的話,代價稍微小一點。減輕了一次遍歷。
                }
                /*update user_tb set User_address='北京',User_password='111111', where User_id='1'User_type='1',User_name='lifei' where User_age='23'
                如果直接上面那種寫法不穩定
                update user_tb set User_address='北京',User_password='111111',User_type='1',User_name='lifei',User_age='23'*/
                
            }
            //上面的方法不穩定,換一個可行的方法,這個 不靠譜的概率太大了。
            /*{//拼接字元串方法二
                //終於知道為啥了!!!這裡面有一個 posi_id這個 id是一個bug。所以 有必要傳一個idInTable
                if(!fieldNames.get(i).toString().equalsIgnoreCase(idInTable)){//不包含id就說明是普通的要被更改的屬性。
                    sql.append(fieldNames.get(i)+"='"+fieldValues.get(i)+"'");
                        if(commaCount<fieldCount-2){
                            //System.out.println("commaCount:"+commaCount+"  fieldCount: "+fieldCount);
                            sql.append(",");
                            //System.out.println(sql.toString());
                            commaCount++;
                        }
                    
                }else{
                    fieldId=fieldNames.get(i).toString();
                    fieldIdValue = fieldValues.get(i).toString();
                }
            }*/
        }
        sql.append(" where "+fieldId+"='"+fieldIdValue+"'");
        //穩定了
        String string = sql.toString();
        System.out.println(string);
        boolean flag = jt.updateData(string, null);
        jt.closeRes();
        return flag;
    }
    
    /**
     * 更新一個對象,只要傳入一個對象。
     * 消除了外鍵關鍵字的bug。
     * 一定要使用這個 方法!!!!!!!!!!!!!!
     * 並未考慮到如果當前對象不存在的情況。
     * @param object
     * @return
     */
    public boolean updateItem(Object object,String primaryIdInTable){//傳一個對象,就能夠修改對象的值,當然前提是,這個對象是完整的。
        
        //update user_tb set user_name=?,user_password=?,user_type=?,user_age=?,user_address where user_id=?
        //看來需要修改addItem裡面的方法了。因為感覺這個不能,在用list一個一個添加了。  試試看
        StringBuffer sql = new StringBuffer("update ");
        Class c = object.getClass();
        String tableName = getTableName(c);
        sql.append(tableName+" set ");//update user_tb set 
        //拼出來需要屬性,這樣的話就得拿到 資料庫中的列名,也就是對應bean中的 屬性名。
        Method[] methods = c.getMethods();
        List fieldNames = new ArrayList();
        List fieldValues = new ArrayList();
        for (Method method : methods) {
            String methodName = method.getName();
            if(methodName.startsWith("get")&&!methodName.equalsIgnoreCase("getclass")){//從object屬性裡面取得值。不過是用get好還是 set好?針對於修改來講,我認為是set好,因為那個getAllPrice()方法,allPrice並非是一個可以被設置的值。一定要取到可以被設置的方法。
                String fieldName = methodName.substring(3);//屬性名
                fieldNames.add(fieldName);
                try {
                    fieldValues.add(method.invoke(object, new Object[]{}));//不過,還是有bug那就只能不允許getAllPrice()的出現或者 自定義標簽來實現,後面慢慢再想辦法。
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        String fieldId = null;
        String fieldIdValue = null;
        int commaCount=0;
        int fieldCount = fieldNames.size();
        for(int i=0;i<fieldCount;i++){
            /*{    
                // 拼接字元串方法一。
                //這個在不同的版本裡面這個 計數的方式 不一樣!!!,不是不一樣因為讀取的順序是隨機的
                //所以有時候就讀到了帶id的方法,有時候沒有讀到,結果是,有時候就多一個 有時候就少一個。
                if(!fieldNames.get(i).toString().contains("id")&&i<fieldNames.size()-2){//如果該欄位不包含id,前面的欄位,加","
                    sql.append(fieldNames.get(i)+"='"+fieldValues.get(i)+"',");
                }else if(!fieldNames.get(i).toString().contains("id")&&i==fieldNames.size()-2){//最後一個要被修改的欄位
                    sql.append(fieldNames.get(i)+"='"+fieldValues.get(i)+"'");
                }else{
                    //sql.append(" where "+fieldNames.get(i)+"='"+fieldValues.get(i)+"'");
                    //update user_tb set  where User_id='1'User_name='lifei',User_type='1',User_age='23',User_address='北京',User_password='111111'
                    fieldId=fieldNames.get(i).toString();
                    fieldIdValue = fieldValues.get(i).toString();
                    //本來在下麵想再遍歷一次的,但是覺得這樣的話,代價稍微小一點。減輕了一次遍歷。
                }
                update user_tb set User_address='北京',User_password='111111', where User_id='1'User_type='1',User_name='lifei' where User_age='23'
                如果直接上面那種寫法不穩定
                update user_tb set User_address='北京',User_password='111111',User_type='1',User_name='lifei',User_age='23'
                
            }*/
            //上面的方法不穩定,換一個可行的方法,這個 不靠譜的概率太大了。
            {//拼接字元串方法二
                //終於知道為啥了!!!這裡面有一個 posi_id這個 id是一個bug。所以 有必要傳一個idInTable
                if(!fieldNames.get(i).toString().equalsIgnoreCase(primaryIdInTable)){//不包含id就說明是普通的要被更改的屬性。
                    sql.append(fieldNames.get(i)+"='"+fieldValues.get(i)+"'");
                        if(commaCount<fieldCount-2){
                            //System.out.println("commaCount:"+commaCount+"  fieldCount: "+fieldCount);
                            sql.append(",");
                            //System.out.println(sql.toString());
                            commaCount++;
                        }
                    
                }else{
                    fieldId=fieldNames.get(i).toString();
                    fieldIdValue = fieldValues.get(i).toString();
                }
            }
        }
        sql.append(" where "+fieldId+"='"+fieldIdValue+"'");
        //穩定了
        String string = sql.toString();
        //System.out.println(string);
        boolean flag = jt.updateData(string, null);
        jt.closeRes();
        return flag;
    }
    /**
     * 向資料庫中添加一個對象。添加對象的時候id一定要重新獲取對嘛?對的!
     * @param object
     * @return
     */
    public boolean addItem(Object object){
        
        
        Class c = object.getClass();
        /*String className = c.getName();
        String tableName = className.substring(className.lastIndexOf(".")+1);*/
        String tableName = getTableName(object.getClass());
        //insert into user_tb () values ();
        StringBuffer sql = new StringBuffer("insert into ");//後置空格
        sql.append(tableName+" ");
        List fieldsNames =new ArrayList();
        List fieldsValues = new ArrayList();
        //對應添加值
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            String methodName = method.getName();
            if(methodName.startsWith("get")&&!methodName.equalsIgnoreCase("getClass")){
                String fieldName = methodName.substring(3);
                fieldsNames.add(fieldName);
                try {
                fieldsValues.add(method.invoke(object, new Object[]{}));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        //組拼
        sql.append("(");
        //value
        for(int i=0;i<fieldsNames.size();i++){//前面這裡還不能加"'"
            if(i==fieldsNames.size()-1){
                sql.append(fieldsNames.get(i));
            }else{
                sql.append(fieldsNames.get(i)+",");
            }
        }
        sql.append(")");
        sql.append(" values ");
        sql.append("(");
        for(int i=0;i<fieldsValues.size();i++){//這裡記得加"'"
            //Unknown column '北京' in 'field list'
            //sql:insert into user_tb (User_address,User_password,User_id,User_name,User_type,User_age) values (北京,111111,3,shenxiuhua,1,23)
            //這是一個多正常的語句。看都不知道哪裡出了問題。所以不管怎麼樣,一定要讓這句話首先在資料庫裡面跑一遍,如果能跑說明沒有問題。
            if(i==fieldsNames.size()-1){
                sql.append("'"+fieldsValues.get(i)+"'");
            }else {
                sql.append("'"+fieldsValues.get(i)+"',");
            }
            
        }
        /*
         *TODO
         * 這種方式是行得通的,上面獲得參數個數,然後每添加一個,就計數+1,然後拼對應數量的"?",上面這種方式,也是可取的。 
        List params = new ArrayList(); 
        for (Object fieldValue : fieldsValues) {
            params.add(fieldValue);
        }*/
        sql.append(")");
        String sqlString = sql.toString();
        System.out.println(sqlString);
        boolean flag = jt.updateData(sqlString, null);
        jt.closeRes();
        return flag;
    }
    
    /**
     * 再添加新用戶的時候,得到 這個對象應該得到的id。
     * @param object 
     */
    protected int getObjectId(Object object,String primaryIdInTable) {
        Class c = object.getClass();
        String tableName = getTableName(c);
        String sql = "select max("+primaryIdInTable+") from "+tableName;
        System.out.println(sql);
        ResultSet resultSet = jt.query(sql, null);
        int lastId = 1;
        try {
            if(resultSet.next()){
                lastId = resultSet.getInt(1);
            }
        } catch (SQLException e) {
            System.out.println("獲得 當前表最後一個對象的id時 出現異常");
            e.printStackTrace();
        }finally{
            jt.closeRes();
        }
        return lastId+1;
    }
    
    /**
     * 通過 用戶名和密碼得到對象
     * sql = "select * from "+tableName+" where "+nameInTable+"=? and "+passwordInTable+"=?";
     * sql = "select * from user_tb where user_name=? and user_password=?";
     * 
     * @param c 對應的 javaBean的名字
     * @param name 用戶名
     * @param password 密碼
     * @param nameInTable 對應資料庫表中name的欄位名稱
     * @param passwordInTable 對應資料庫表中password的欄位名稱
     * @return
     */
    public Object loginByNAP(Class c,String name,String password,String nameInTable,String passwordInTable){
        String tableName = getTableName(c);
        String sql = "select * from "+tableName+" where "+nameInTable+"=? and "+passwordInTable+"=?";
        //System.out.println(sql);
        List params = new ArrayList();
        params.add(name);
        params.add(password);
        ResultSet resultSet = jt.query(sql, params);
        Object object = null;
        try {
            if(resultSet.next()){
                    object = setValueForObject(object, c, resultSet);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        jt.closeRes();
        return object;
    }
    
    /**
     * 通過一個 字元串形式表現的 表,得到  對應 類  對象的所有信息。 
     * @param string
     * @param c
     * @return
     */
    public List getAllObjectsInfoByClass(String string, Class c){
        
        ResultSet resultSet = jt.query(string, null);
        List list = new ArrayList();//被返回的對象。
        Object object = null;//得到的每一個對象存儲在這裡。
        try {
            //得到該類的對象,並給該類的對象賦值。
            while(resultSet.next()){//如果查到一條結果,報出sql異常
                object = setValueForObject(object, c, resultSet);
                list.add(object);
                object= null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            jt.closeRes();
        }
        return list;
    }
    /**
     * 得到資料庫中的所有元素
     * @param c
     * @return
     */
    public List getAllObjects(Class c){
        String tableName = getTableName(c);
        String sql="select * from "+tableName;
//        List params = new ArrayList();
//        params.add(tableName);
        //無論怎麼樣都要用預狀態通道,因為安全性更高(能夠防止sql註入),執行效率更高。
        ResultSet resultSet = jt.query(sql, null);
        List list = new ArrayList();//被返回的對象。
        Object object = null;//得到的每一個對象存儲在這裡。
        try {
            //得到該類的對象,並給該類的對象賦值。
            while(resultSet.next()){//如果查到一條結果,報出sql異常
                object = setValueForObject(object, c, resultSet);
                list.add(object);
                object= null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            jt.closeRes();
        }
        return list;
    }
    
    public List getAllObjects(Class c,String whereClause){
        String tableName = getTableName(c);
        String sql="select * from "+tableName+" "+whereClause;
//        List params = new ArrayList();
//        params.add(tableName);
        //無論怎麼樣都要用預狀態通道,因為安全性更高(能夠防止sql註入),執行效率更高。
        ResultSet resultSet = jt.query(sql, null);
        List list = new ArrayList();//被返回的對象。
        Object object = null;//得到的每一個對象存儲在這裡。
        try {
            //得到該類的對象,並給該類的對象賦值。
            while(resultSet.next()){//如果查到一條結果,報出sql異常
                object = setValueForObject(object, c, resultSet);
                list.add(object);
                object= null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            jt.closeRes();
        }
        return list;
    }
    /**
     * 通過id查找到對應用戶,
     * sql ="select * from "+tableName+" where "+idInTable+"=?";
     * sql ="select * from user_tb where user_id=?";
     * @param c javaBean.class
     * @param id  要被查找的id
     * @param idInTable 在資料庫表中id對應的名字。
     * @return
     */
    public Object getObjectById(Class c,String id,String primaryIdInTable){
        String tableName = getTableName(c);
        String sql ="select * from "+tableName+" where "+primaryIdInTable+"=?";
        List params = new ArrayList();
        params.add(id);
        ResultSet resultSet = jt.query(sql, params);
        Object object = null;
        try {
            if(resultSet.next()){
                //為屬性添加值
                object = setValueForObject(object, c, resultSet);
            }else{
                System.out.println("該記錄不存在");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            jt.closeRes();
        }
        return object;
    }
    
    /**
     * 根據類型名獲得表名,私有方法不對外暴露
     * @param c
     * @return
     */
    private String getTableName(Class c) {
        String tableName=null;
        //這個名稱轉換做一個私有的函數。給如一個類名,給出一個表名
        String className = c.getName();
        //先實現,在優化!寫多了自然優化了
        //先考慮一個單詞的情況,切詞技術~還更麻煩
        //System.out.println("類全名,大概是一個:com.letben.bean.User 的形式:"+className);
        //字元串兒這裡的操作大都是包含頭的不包含尾的操作,所以取得最後一個“.”的位置後,+1,就能渠道對應的javaBean的名字。
        String beanName = className.substring(className.lastIndexOf(".")+1);//User
        //全部變小寫
        beanName = beanName.toLowerCase();//user
        //字元串兒拼接
        tableName = beanName+"_tb";//user_tb
        return tableName;
    } 
    
    
    /**
     * 內部方法,用來實現對象參數的設置。
     * @param object
     * @param c
     * @param resultSet
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     * @throws SQLException
     */
    private Object setValueForObject(Object object,Class c,ResultSet resultSet) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SQLException {
        //就新建一個c類對象的實例
        object= c.newInstance();//初始化異常,非法許可權異常
        //註意體會c.getDeclaredMethods();與c.getMethods();的區別。
        Method[] methods = c.getMethods();//得到所有public的方法。
        for (Method method : methods) {//遍歷所有方法
            String methodName = method.getName();//得到當前遍歷的方法的名字
            if(methodName.startsWith("set")){//如果方法是以set開頭的。說明這個類的對象在初始化時需要這麼一個對象的設置
                //這裡跟取值那個地方有點兒不同,在取值的時候註意排除,getClass的方法
                //記不記得後面有通過反射,拿到根本不需要設置的屬性的名比如allPrice,我們只是寫了一個getAllPrice的方法。
                //後面跟的必然是屬性名:
                String fieldName = methodName.substring(3);//把前面3個截掉。
                Class[] parameterTypes = method.getParameterTypes();//得到當前方法,所需參數的名字們。
//                System.out.println(methodName);
                if(parameterTypes[0] == String.class){
                    method.invoke(object, new Object[]{resultSet.getString(fieldName)});//會報非法參數異常和調用目標異常
                    /*String s =null;
                    s="";
                    System.out.println(s.getClass());
                    System.out.println(String.class);
                    這兩個結果是一致的。
                    */
                }else if(parameterTypes[0]==int.class){//註意int.class!=Integer.class
                    //int.class         ->        int
                    //Integer.class     ->        class java.lang.Integer
                    method.invoke(object, new Object[]{resultSet.getInt(fieldName)});
                }else if(parameterTypes[0]==double.class){
                    method.invoke(object, new Object[]{resultSet.getDouble(fieldName)});
                }else{
                    System.out.println("還有屬性沒有考慮到。屬性名稱為:   "+method.getName()+"   。參數類型為:   "+parameterTypes[0]);
                }
            }
        }//for完一圈兒,說明對象已經完整賦過值了
        return object;
        /*
         * 
        簡體版
        object = c.newInstance();//初始化異常,非法許可權異常
                    //接下來就是對應賦值
                    //跟c.getDeclaredMethods()的區別?
                    Method[] methods = c.getMethods();
                    for (Method method : methods) {
                        String methodName = method.getName();
                        if(methodName.startsWith("set")){
                            String fieldName = methodName.substring(3);
                            Class[] parameterTypes = method.getParameterTypes();//我們的get就都只有一個參數
                            if(parameterTypes[0]==String.class){
                                method.invoke(object, new Object[]{resultSet.getString(fieldName)});
                            }else if(parameterTypes[0]==int.class){
                                method.invoke(object, new Object[]{resultSet.getInt(fieldName)});
                            }else{
                                System.out.println("未考慮到的屬性");
                            }
                        }
                    }
         */
    }
    
    /**
     * 為了邏輯刪除後面加一個 whereClause,也可以傳 null
     * 單表傳遞類名,得到數量。
     * @param c
     * @param whereClause
     * @return
     */
    public int getAllObjectsCount(Class c,String whereClause) {
        String tableName = getTableName(c);
        String sql=null;
        if(whereClause==null){
            sql = "select count(*) from "+tableName;
        }else {
            sql = "select count(*) from "+tableName+" "+whereClause;
        }
        System.out.println(sql);
        ResultSet resultSet = jt.query(sql, null);
        int count = 0;
        try {
            if(resultSet.next()){
                count = resultSet.getInt(1);
            }
        } catch (SQLException e) {
            System.out.println("查詢所有元組數量時,出現異常");
            e.printStackTrace();
        }finally{
            jt.closeRes();
        }
        return count;
    }
    
    
    /**
     * 多表查詢元組總數量。
     * @param childTableName
     * @param whereClause
     * @param isChildTable
     * @return
     */
    public int getAllObjectsCount(String childTableName,String whereClause,boolean isChildTable) {
        String sql =null;
        if(isChildTable){
            sql = "select count(*) from ("+childTableName+") alias "+whereClause;
        }else {
            sql = "select count(*) from "+childTableName+" "+whereClause;
        }
        System.out.println(sql);
        ResultSet resultSet = jt.query(sql, null);
        int count = 0;
        try {
            if(resultSet.next()){
                count = resultSet.getInt(1);
            }
        } catch (SQLException e) {
            System.out.println("查詢所有元組數量時,出現異常");
            e.printStackTrace();
        }finally{
            jt.closeRes();
        }
        return count;
    }
    
    /** 
     * 分頁得到條目信息。 select alias.* from ( "+childTableName+" ) alias limit 0,3
     * @param childTableName  子表
     * @param c    子表對應的javabean
     * @param pageBean 分頁情況
     * @param isChildName 是否是子表
     * @return
     */
    public List getAllInfosByPage(String childTableName,
            Class c, PageBean pageBean,boolean isChildTable) {
        String sql=null;
        if(isChildTable){
            sql = "select alias.* from ( "+childTableName+" ) alias limit "+(pageBean.getCurrentPage()-1)*pageBean.getPageSize()+" ,"+pageBean.getPageSize()+" ";
        }else{
            sql = "select alias.* from  "+childTableName+"  alias limit "+(pageBean.getCurrentPage()-1)*pageBean.getPageSize()+" ,"+pageBean.getPageSize()+" ";
        }
        System.out.println(sql);
        ResultSet resultSet = jt.query(sql, null);
        Object object=null;
        try {
            object = c.newInstance();
        } catch (InstantiationException | IllegalAccessException e1) {
            System.out.println("分頁查詢時 創建對象出現異常");
            e1.printStackTrace();
        }
        List objects = new ArrayList();
        try {
            while(resultSet.next()){
                object = setValueForObject(object, c, resultSet);
                objects.add(object);
                object = null;    
            }
        } catch (Exception e) {
            System.out.println("分頁獲取信息時 出現異常");
            e.printStackTrace();
        }finally{
            jt.closeRes();
        }
        return objects;
    }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 丙申年把真假美猴王囚禁在容器中跑 ASP.NET Core 1.0¶警告您當前查看的頁面是未經授權的轉載! 如果當前版本排版錯誤,請前往查看最新版本:http://www.cnblogs.com/qin-nz/p/aspnetcore-run-on-mono-in-year-of-monkey.ht...
  • 之前就是說過“一個項目有很多重要的步驟以及功能”,那我們現在就來看看對於KTV項目來說;後臺是處於什麼樣的重要作用! 首先就得瞭解KTV後臺的一些功能了: 1.歌曲管理 、歌手管理 、設置資源路徑 2.新增歌手、歌手查詢、新增歌曲、歌曲查詢、更改歌曲路徑以及退出點歌系統 一.後臺登錄界面 01.判斷
  • continue和break可以改變迴圈的執行流程,但在多重迴圈中,這兩條語句無法直接從內層迴圈跳轉到外層迴圈。在C語言中,可以通過goto語句實現多重迴圈的跳轉,但在非迴圈結構中使用goto語句會使程式的結構紊亂,可讀性變差。因此Java就發明瞭一種帶標簽的continue和break語句,實際上...
  • 數據類型內置函數用法int 關於內置方法是非常的多這裡呢做了一下總結 (1)__abs__(...)返回x的絕對值 #返回x的絕對值!!!都是雙下劃線 x.__abs__() <==> abs(x) 例如: #!/usr/bin/python print "abs(-45) : ", abs(-45
  • pycharm開發django工程(二) 項目需求: 1. 從mongodb中讀取數據,並顯示到網頁中 2. 在網頁顯示的每一頁加入分頁符 首先使用pycharm的企業版新建一個django的虛擬工程(參考我的上一個博客),這是初始的顯示效果 這是原始的html文件,css文件在本文的最後,至於圖片...
  • 1.continue 語句的作用 終止本次迴圈的執行,即跳過當前一次迴圈中continue語句後尚未執行的語句,然後進行下一次迴圈條件的判斷。 2.break 語句的作用 (1)當break在迴圈體內時,強行終止整個迴圈的執行,即結束整個迴圈過程,不再判斷執行迴圈的條件是否成立,直接轉向迴圈體下麵的
  • 《微型電腦原理與介面技術(第2版)》馮博琴 吳寧 主編-清華大學出版社——做筆記用 一、8088/8086的14個16位寄存器: //----------------------------------------------------------------------------------
  • 1、定位系統問題 依據 GC日誌 堆轉儲快照(heapdump/hprof文件) 線程快照(threaddump/javacore文件) 運行日誌 異常堆棧 分析依據的工具 jps:顯示指定系統內的所有JVM進程 jstat:收集JVM各方面的運行數據 jinfo:顯示JVM配置信息 jmap:形成
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...