一文搞懂反射泛型和反射注解以及通過注解方式寫一個BaseDao

反射泛型和反射注解概括起來就三步:

  • 自定義注解
  • 通過反射獲取注解值
  • 使用自定義注解

最終案例

通過自定義注解,將數(shù)據(jù)庫表與Java對象映射,在不需要配置文件的情況下,查詢出數(shù)據(jù)庫的記錄
分析:數(shù)據(jù)庫表有數(shù)據(jù)庫名,表名和字段几迄,所以在定義注解時這些都是必須的,但是在查詢時有通過主鍵查詢的方式冰评,那么如何知道哪個字段是主鍵呢映胁,這就需要來聲明一下,所以甲雅,還需要定義一個id注解用于標識某對象的某屬性對應著數(shù)據(jù)庫的主鍵解孙。此時就需要來說明一下什么是注解。

注解

什么是注解

  • 語法:@注解名稱
  • 注解的作用:替代xml配置文件
  • Servlet3.0中就可以不在使用web.xml文件抛人,而是所有配置文件都使用注解弛姜。
  • 注解是由框架來讀取的!

注解的使用妖枚!

  • 定義注解類(框架的工作)
  • 使用注解(我們的工作)
  • 讀取注解(反射讀取注解)(框架的工作)

注解其實也是一個類

如何定義注解類

class A{}定義類
interface A{}定義接口

@interface A{} 定義注解

  • 天下所有的注解都是Annotation的子類
    不用特意標記默認就是

如何使用注解

首先自定義一個注解:

//自定義注解類
package annotation;
@interface MyAnnotation {
//暫時不寫內(nèi)容廷臼,只是演示注解的使用
}

使用自定義MyAnnotation注解

package annotation;
@MyAnnotation//注解能放在類上
public class Demo1 {
    @MyAnnotation//注解能放在成員變量上
    private String name;
    
    @MyAnnotation//注解能放在構造器上
    public void Demo1(){
        
    }
    
    @MyAnnotation//注解能放在方法上
    public void test1(){
        
    }
    
    public void test2(@MyAnnotation String name){//注解能放在參數(shù)上
        //注解能放在局部變量上
        @MyAnnotation
        String username = "hello";
    }
    //但是注解不能放在方法的調用上
}

注解的作用目標

由上述使用注解的例子可以看出,注解的作用目標有一下幾種:

  • 方法
  • 構造器
  • 參數(shù)
  • 局部變量

注解的屬性(依賴文檔了解)

  • 定義屬性
    格式:類型 屬性名()
    例如:
//注解類
@interface MyAnno1{
    int age();//這是屬性不是方法
    String name();//括號后面不能跟{},也不能加參數(shù)荠商,因為這不是方法寂恬,而是注解的屬性
}
  • 使用注解時給屬性賦值
//使用屬性時,屬性必須要求有值
@MyAnno1(age=100,name="zhangsan")
  • 注解屬性的默認值
//注解類
@interface MyAnno2{
    int age() default 100;//這是屬性不是方法
    String name();
}
使用時:@MyAnno2(name="zhangsan")
也可以在給一個age值如:
@MyAnno2(age="999",name="zhangsan")
此時值會覆蓋默認值
  • 名為value的屬性的特權
在使用注解時莱没,如果只給名為value的屬性賦值初肉,那么可以不給出屬性的名稱直接給出值
例如:
//注解的特權
@interface MyAnno3{
    int value();
    String name() default "hello world";
}
使用注解時:
@MyAnno3(100)相當于給value的屬性賦值不用指定value
  • 注解屬性的類型
注解屬性有8中基本類型:
- String
- Enum
- Class
- 注解類型(和循環(huán)體的內(nèi)容是循環(huán)體是一個道理)
- 以上類型的一維數(shù)組類型 int[],(二維數(shù)組不行)
注意:Integer包裝類型不能使用

如何使用:
@interface MyAnno4{
    int a();
    String b();
    MyEnum c();
    Class d();
    MyAnno2 e();
    String[] f();
}
enum MyEnum{
    A,B,C
}

@MyAnno4(
    a=100,
    b="hello",
    c=MyEnum.A,
    d=String.class,
    e=@MyAnno2(name = "zhangsan"),
    f={"hello","world"}
)
public class Demo3 {

}
當給數(shù)組類型的屬性賦值時,可以省略大括號
如f="hello"

注解的作用目標限定以及保存策略限定

讓一個注解他的作用目標只能在類上不能在方法上饰躲,這就叫做目標的限定

  • 在定義注解時給注解添加注解叫做@Target
@Target(value={ElementType.TYPE,ElementType.ANNOTATION_TYPE,ElementType.METHOD,ElementType.FIELD})
@interface MyAnno1{
    
}

保留策略

  • 源代碼文件(SOURCE):注解只在源代碼中存在牙咏,在編譯時就別忽略了(無法反射)
  • 字節(jié)碼文件(CLASS):注解在源代碼中存在,編譯時會把注解信息放到class中存在嘹裂,但JVM在類時會被忽略加載注解(無法反射)
  • JVM中(RUNTIME):注解在源代碼妄壶,字節(jié)碼文件中存在,并且在JVM加載類時會把注解加載到JVM內(nèi)存中(它是唯一可以反射的注解)

限定注解的而保留策略

@Retention(RetentionPolicy.RUNTIME)//保留策略
@interface MyAnno1{
    
}

讀取注解

反射泛型信息:

Class --> Type getGenericSuperclass()
Type --> ParameterizedType,把Type強轉為ParameterizedType類型
ParameterizedType --> 參數(shù)化類型 = A<String>
ParameterizedType :Type[]  getActualTypeArguments(),A<String>中的String
Type[]就是Class[],我們就得到了類型參數(shù)了!

通過上述描述的步驟既可以獲的類型參數(shù)

public class Demo1 {
    @Test
    public void fun1(){
        new B();//執(zhí)行得到java.lang.String
    }
}
class A<T> {
    public A() {
        /*
         * 在這里獲取子類傳遞的泛型信息寄狼,要得到一個Class
         */
//      Class clazz = this.getClass();//得到子類的類型
//      Type type = clazz.getGenericSuperclass();//獲取傳遞給父類參數(shù)化類型
//      ParameterizedType pType=(ParameterizedType)type;//它就是A<String>
//      Type[] types = pType.getActualTypeArguments();//它就是一個Class數(shù)組
//      Class c = (Class)types[0];
//      System.out.println(c.getName());//String或Integer
        
        //將上面注釋的內(nèi)容變成一句話
        Class c = (Class)((ParameterizedType)(this.getClass().
                getGenericSuperclass())).getActualTypeArguments()[0];
        System.out.println(c.getName());
    }
}
class B extends A<String> {
    
}
class C extends A<Integer> {
    
}

反射注解

上面講述了如何通過反射來得到類的類型盯拱,那么要通過反射得到注解,要求注解的保留策略必須是RUNTIME

反射注解需要從作用目標開始反射

  • 類上的注解例嘱,需要使用Class來獲取
  • 方法上的注解需要Method來獲取
  • 構造器上的注解需要Constructor來獲取
  • 成員山谷的需要使用Field來獲取

一下?lián)碛锌梢垣@取注解的方法:

  • Class:
  • Method、Constructor宁舰、Field有共同的父類:AccessibleObject
    它們都有一個方法:
  • Annotation getAnnotation(Class),返回目標上指定類型的注解
  • Annotation[] getAnnoations(),返回目標注解上所有的注解

定義一個注解MyAnno1 拼卵,在定義一個類A來使用注解

@MyAnno1(name="A類",age=20,sex="男")
class A{
    @MyAnno1(name="test1方法",age=10,sex="女")
    public void test(){
        
    }
}
@Retention(RetentionPolicy.RUNTIME)//注意聲明保留策略,否則獲取不到
@interface MyAnno1 {
    String name();
    int age();
    String sex();
}

通過下面的代碼來演示如何獲得作用在A類上的注解

public class Demo2 {
       @Test
    public void test1(){
        /*
         * 1.得到作用目標
         */
        Class<A> c = A.class;
        /*
         * 2.獲取指定類型的注解
         */
        MyAnno1 myAnno1 = c.getAnnotation(MyAnno1.class);
        System.out.println(myAnno1);//結果@demo2.MyAnno1(name=A類, age=20, sex=男)
    }

    @Test
    public void test2() throws NoSuchMethodException, SecurityException{
        /*
         * 1.得到作用目標
         */
        Class<A> c = A.class;
        Method method = c.getMethod("test");
        
        /*
         * 2.獲取指定類型的注解(獲取方法上的注解)
         */
        MyAnno1 myAnno1 = method.getAnnotation(MyAnno1.class);
        System.out.println(myAnno1.name()+ ", " + myAnno1.age() + ", " +myAnno1.sex());
    }
}

通過上述內(nèi)容蛮艰,我們了解了什么是如何通過反射獲取類型參數(shù)腋腮,以及什么是注解,注解該如何通過反射獲取壤蚜,那么作為練習即寡,下面就完成通過注解來寫一個BaseDao的實驗

完成注解案例

首先我們根據(jù)實驗的分析,創(chuàng)建注解類

/**  
* <p>Title: Table</p>  
* <p>Description: Table 注解類用于標識哪個對象對應數(shù)據(jù)庫的哪一張表袜刷,作用在類上</p>  
* @author guqin  
* @date 2018年9月23日  
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String value();
}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**  
* <p>Title: Column</p>  
* <p>Description: 該注解類用于將數(shù)據(jù)庫字段映射到java對象屬性上</p>  
* @author guqin  
* @date 2018年9月23日  
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String value();
}
/**  
* <p>Title: ID</p>  
* <p>Description: ID注解類用于在對象屬性上標識哪一個字段是數(shù)據(jù)庫主鍵</p>  
* @author guqin  
* @date 2018年9月23日  
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface ID {
    String value();
}

為什么沒有數(shù)據(jù)庫名的注解呢聪富,眾所周知,連接數(shù)據(jù)庫需要指定庫名著蟹,用戶名和密碼才能訪問墩蔓,這些信息都是配置在外部的配置文件中的,比如JDBC萧豆、Hibernate或者其他奸披,于此同時還會使用數(shù)據(jù)庫連接池比如DBCP、C3P0連接池等涮雷,那么數(shù)據(jù)庫名及用戶名密碼就會配置在這些的配置文件當中阵面,比如可以寫一個jdbc.properties,所以是不需要指定庫名的注解的而且這中信息還是多個對象公用的。
下面以查詢user表為例來映射一個User對象:

import guqing.basedao.Column;
import guqing.basedao.ID;
import guqing.basedao.Table;

/**  
* <p>Title: User</p>  
* <p>Description: </p>  
* @author guqin  
* @date 2018年9月23日  
*/
@Table("user")//它的值表示當前類對應的表
public class User {
    @ID("u_id")//當前屬性對應的列明样刷,而且說明這個列是主鍵列
    private String uid;
    
    @Column("uname")
    private String username;
    
    @Column("password")
    private String password;
    
    @Column("state")
    private boolean state;
    
    @Column("price")
    private double price;
    
    //get set方法省略
}

完成了以上工作之后仑扑,現(xiàn)在就需要:

  • 獲取注解的信息
  • 拼接sql語句查詢數(shù)據(jù)庫
  • 映射結果集

獲取注解信息

package guqing.basedao;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**  
* <p>Title: MatchField</p>  
* <p>Description: 該類用于字段匹配,將數(shù)據(jù)庫字段與java對象屬性映射 </p>  
* @author guqin  
* @date 2018年9月26日  
*/
public class MatchField {
    private static String primary;//數(shù)據(jù)庫主鍵
    private static String primaryName;//標有@ID注解的對象屬性名
    
    //通過單例設計模式颂斜,返回唯一實例
    private static MatchField matchField = new MatchField();
    //私有構造方法夫壁,對外提供獲取該對象的方法來拿到唯一靜態(tài)實例
    private MatchField(){}
    
    /**
    * @Title: getMatchFieldInstance  
    * @Description: 獲取該對象的句柄  
    * @param @return
    * @return MatchField
    * @throws
     */
    public static MatchField getMatchFieldInstance() {
        return matchField;
    }
    
    /**
    * @Title: MappingField2Map  
    * @Description: 字段映射方法,返回一個Map沃疮,key=對象屬性名 ,value=數(shù)據(jù)庫字段名
    * @param @param beanClass
    * @param @return
    * @return Map<String,String>
    * @throws
     */
    public Map<String,String> MappingField2Map(Class<?> beanClass){
        Map<String,String> fieldMapping = new HashMap<String,String>();
        
        //反射獲取到主鍵的值
        Field[] fields = beanClass.getDeclaredFields();
        for(Field field : fields){//遍歷之
            ID id = field.getAnnotation(ID.class);
            Column column = field.getAnnotation(Column.class);
            if(id!=null) {
                //拿到至關重要的數(shù)據(jù)庫主鍵字段與@ID注解的對象屬性名盒让,將其放到Map中形成映射鍵值對
                primary = id.value();
                primaryName = field.getName();
                fieldMapping.put(primaryName, primary);//對象的成員變量名-->表字段名
                
            } else if(column!=null) {
                //拿到其他普通數(shù)據(jù)庫字段與普通字段對應的java對象屬性,同樣放到Map中形成映射關聯(lián)
                fieldMapping.put(field.getName(), column.value());
                
            } else {
                //如果都不是那么默認就是字段名-->對應數(shù)據(jù)庫字段名
                //也就是對象屬性可以不標識注解表示與數(shù)據(jù)庫字段同名
                //也可以自己再改進一下比如設置默認值或者駝峰命名等
                //甚至還可以寫一個xml配置文件用于配置數(shù)據(jù)庫字段與對象屬性的映射
                //然后讀取配置文件的內(nèi)容司蔬,這就比較類似于hibernate邑茄,總之自由發(fā)揮吧
                fieldMapping.put(field.getName(), field.getName());
            }
        }
        
        //如果用戶忘記注解主鍵那么拋出異常
        if(primaryName==null||primary==null){
            throw new RuntimeException("syntax error:unknown primary key columns,"
                    + " try again after annotating the primary key in the Javabean with @ID(value)");
        }
        //返回數(shù)據(jù)庫字段與對象屬性映射關系的Map
        return fieldMapping;
    }
    
    /**
    * @Title: precursorSelectSql  
    * @Description: 通過上面的MappingField2Map方法拼湊查詢語句的前半部分 
    * @param @param beanClass
    * @param @return
    * @return String
    * @throws
     */
    public String precursorSelectSql(Class<?> beanClass){
        //通過beanClass得到字段映射Map
        Map<String,String> mappingField = MappingField2Map(beanClass);
        
        //拿到javaBean所有成員變量
        Field[] fields = beanClass.getDeclaredFields();
        
        //創(chuàng)建查詢語句前驅
        StringBuilder sb = new StringBuilder("select ");
        //拼湊sql語句
        for(int i=0;i<fields.length;i++){
            sb.append("`"+mappingField.get(fields[i].getName())+"`");//通過鍵獲得表的字段名稱
            sb.append(" as "+"`"+fields[i].getName()+"`");
            if(i<fields.length-1){
                sb.append(",");//最后一個不加逗號
            }
        }
        sb.append(" ");
        return sb.toString();
    }

    /**
    * @Title: getBeanPrimaryName  
    * @Description: 返回javabean中作為主鍵的成員變量名稱  
    * @param @return
    * @return String
    * @throws
     */
    public String getBeanPrimaryName(){
        return primaryName;
    }
}

其實有了數(shù)據(jù)庫字段與對象屬性的映射就可以比較方便的完成查詢更新刪除添加等操作了,都是寫平湊sql語句的活俊啼。缺點是只能進行簡單屬性的映射肺缕。
下面就是通過上面的映射方式寫的BaseDao可以參考下一:

package guqing.basedao;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import cn.itcast.jdbc.TxQueryRunner;

/**  
* <p>Title: BaseDao1</p>  
* <p>Description: </p>  
* @author guqin  
* @date 2018年9月23日  
*/
public class BaseDao<T> {
    private QueryRunner qr = new TxQueryRunner();
    private Class<T> beanClass;//通過父類獲取子類類型
    private String primaryName;//Dao主鍵字段名稱
    private String tablename;//表名稱
    private Map<String,String> mappingField;//存儲字段映射
    //獲取到MappingField對象
    private MatchField matchField = MatchField.getMatchFieldInstance();
    
    //構造方法
    @SuppressWarnings("unchecked")
    public BaseDao(){
        //通過父類獲取子類類型
        beanClass = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        
        //先獲取字段映射Map
        mappingField = matchField.MappingField2Map(beanClass);
        //再獲取主鍵名稱
        primaryName = matchField.getBeanPrimaryName();
        
        //獲取到表名稱
        Table table = beanClass.getAnnotation(Table.class);
        if(table!=null){
            tablename = table.value();
            
        } else {
            String clazzSimpleName = beanClass.getSimpleName();
            tablename = clazzSimpleName.substring(0, 1).toLowerCase() + clazzSimpleName.substring(1);
        }
    }
    
    public void save(T bean) throws SQLException{
        //String sql ="insert into 表名 values(幾個?)";
        
        //通過反射將類中屬性的個數(shù)清楚就是問號的個數(shù)
        Field[] fields = beanClass.getDeclaredFields();

        //獲取成員變量上的注解
        List<Object> params = new LinkedList<Object>();
        
        String sql ="insert into " + "`"+tablename +"`"+" values(";
        //拼湊sql字符串
        for(int i=0;i<fields.length;i++){
            sql += "?";
            //拼湊參數(shù)
            try {
                params.add(beanClass.getMethod(getGetMethodString(fields[i].getName())).invoke(bean));
            } catch (Exception e) {
                
                try {
                    Object param = beanClass.getMethod(getIsMethodString(fields[i].getName())).invoke(bean);
                    if(param=="false"){
                        params.add(0);
                    }else if(param=="true"){
                        params.add(1);
                    }else{
                        params.add(param);
                    }
                    
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
            if(i < fields.length-1){
                sql +=",";
            }
        }
        sql += ")";
        
        qr.update(sql,params.toArray());
    }
    
    
    /**
    * @Title: update  
    * @Description: 更新方法  
    * @param @param bean
    * @return void
    * @throws
     */
    public void update(T bean){
        try {
            Map<String,Object[]> updateSqlParam = bean2UpdateSql(bean);
            
            /*
             * update car_number_track set ...+where cid=cid子句
             */
            qr.update((String) updateSqlParam.get("sql")[0], updateSqlParam.get("params"));
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    
    /**
    * @Title: baseDelete  
    * @Description: 根據(jù)主鍵刪除  
    * @param @param id
    * @param @return
    * @return Boolean
    * @throws
     */
     public void deleteById(Object id){
         try{
            String sql = "delete from " + "`" + tablename +"`"+ " where " + mappingField.get(primaryName) +"=?";
            
            qr.update(sql,id);
         } catch (Exception e) {
             e.printStackTrace();
            throw new RuntimeException(e);
         }
     }     
        
     
     /**
     * @Title: get  
     * @Description: 通過主鍵查詢  
     * @param @param id
     * @param @return
     * @return T
     * @throws
      */
     public T get(Object id) {
         try {
            String preSelectSql =  matchField.precursorSelectSql(beanClass);
            preSelectSql = preSelectSql + "from " + "`" + tablename +"`" + " where " + mappingField.get(primaryName)+"=?";
            
            return qr.query(preSelectSql, new BeanHandler<T>(beanClass),id);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
     }
     
     /**
     * @Title: list  
     * @Description: 查詢方法  
     * @param @return
     * @return List<T>
     * @throws
      */
     public List<T> list(){
        try {
            //查詢語句的前半部分 + 用戶自定義的后半部分查詢語句
            String querySql = matchField.precursorSelectSql(beanClass) + Query.getThatSql();
            
            if(querySql.contains(":")||querySql.contains("?")){
                throw new RuntimeException("Syntax error: the number of parameters is insufficient."
                        + " Please try again after checking[大哥參數(shù)個數(shù)沒給夠]");
            }
            
            return qr.query(querySql, new BeanListHandler<T>(beanClass));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
     }

    /**
    * @Title: getGetMethodString  
    * @Description: 通過成員變量屬性名稱獲取到set方法  
    * @param @param fieldName
    * @param @return
    * @return String
    * @throws
     */
    private String getGetMethodString(String fieldName) {
        String getMethodString = "get" + fieldName.substring(0, 1).toUpperCase() +
                fieldName.substring(1);
        return getMethodString;
    }
    
    private String getIsMethodString(String fieldName) {
        String getMethodString = "is" + fieldName.substring(0, 1).toUpperCase() +
                fieldName.substring(1);
        return getMethodString;
    }

    private Map<String,Object[]> bean2UpdateSql(T bean){
        List<Object> params = new ArrayList<Object>();
        Map<String,Object[]> updateSqlParams = new HashMap<String,Object[]>();
        
        //給出sql語句的前半部分
        StringBuilder firstHalfSql = new StringBuilder("update "+"`"+tablename+"`");//前綴
        StringBuilder setSql = new StringBuilder();//后綴
        
        Object primaryValue = null;
        //先在第一個占位符也就是cid出添加參數(shù)
        setSql.append(" set "+"`"+mappingField.get(primaryName)+"`"+"=?");
        try {
            primaryValue = beanClass.getMethod(getGetMethodString(primaryName)).invoke(bean); 
            params.add(primaryValue);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } 
        
        /*
         * 1.判斷條件,完成sql中追加where子句
         * 2.創(chuàng)建ArrayList授帕,保存參數(shù)
         */
        Field[] fields = beanClass.getDeclaredFields();
        for(Field field : fields){
            if(field.getName().equals(primaryName)){
                continue;//略過主鍵
            }
            Column column = field.getAnnotation(Column.class);
            try {
                String returnType = beanClass.getMethod(getGetMethodString(field.getName())).getGenericReturnType().getTypeName();
                Object getMethod = beanClass.getMethod(getGetMethodString(field.getName())).invoke(bean);
            
                if(returnType.contains("String")||returnType.contains("Integer")){
                    String param = (String) getMethod;
                    if(param!=null && !param.trim().isEmpty() && param!="null" && column!=null){
                        setSql.append(","+"`"+column.value()+"`"+"=?");
                        params.add(param);
                        
                    } else if(param!=null && !param.trim().isEmpty() && param!="null" && column==null) {
                        setSql.append(","+"`"+ mappingField.get(field.getName()) +"`"+"=?");
                        params.add(param);
                    }
                }else if(returnType.contains("double")){
                    double param =  (double)getMethod;
                    if(param!=0.0 && column!=null){
                        setSql.append(","+"`"+column.value()+"`"+"=?");
                        params.add(param);
                        
                    } else if(column==null) {
                        setSql.append(","+"`"+ mappingField.get(field.getName()) +"`"+"=?");
                        params.add(param);
                    }
                }else if(returnType.contains("int")){
                    int param = (int) getMethod;
                    if(param!=0 && column!=null){
                        setSql.append(","+"`"+column.value()+"`"+"=?");
                        params.add(param);
                        
                    } else if(column==null) {
                        setSql.append(","+"`"+ mappingField.get(field.getName()) +"`"+"=?");
                        params.add(param);
                    }
                } else if(returnType.contains("boolean")){
                    Object param =  (Object)getMethod;
                    if(column!=null && param!=null && !param.equals("null")){
                        setSql.append(","+"`"+column.value()+"`"+"=?");
                        params.add((boolean)param);
                        
                    } else if(param==null){
                        continue;
                    }else{
                        setSql.append(","+"`"+ mappingField.get(field.getName()) +"`"+"=?");
                        params.add((boolean)param);
                    }
                }
            } catch (Exception e) {
                try {
                    String returnType = beanClass.getMethod(getIsMethodString(field.getName())).getGenericReturnType().getTypeName();
                    Object getMethod = beanClass.getMethod(getIsMethodString(field.getName())).invoke(bean);
                    
                    if(returnType.contains("boolean")){
                        Object param =  (Object)getMethod;
                        if(column!=null && param!=null && !param.equals("null")){
                            setSql.append(","+"`"+column.value()+"`"+"=?");
                            params.add((boolean)param);
                            
                        } else if(param==null){
                            continue;
                        }else{
                            setSql.append(","+"`"+ mappingField.get(field.getName()) +"`"+"=?");
                            params.add((boolean)param);
                        }
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
            
        }
        /*
         * 追加where語句的參數(shù)
         */
        String finalSql = firstHalfSql.append(setSql).append(" where "+
                        "`"+mappingField.get(primaryName)+"`"+"=?").toString();
        params.add(primaryValue);
        
        String[] sql = {finalSql};
        
        updateSqlParams.put("sql",sql);
        updateSqlParams.put("params", params.toArray());
        
        return updateSqlParams;
    }
    
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末同木,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子跛十,更是在濱河造成了極大的恐慌彤路,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芥映,死亡現(xiàn)場離奇詭異洲尊,居然都是意外死亡,警方通過查閱死者的電腦和手機奈偏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門坞嘀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惊来,你說我怎么就攤上這事丽涩。” “怎么了裁蚁?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵内狸,是天一觀的道長。 經(jīng)常有香客問我厘擂,道長昆淡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任刽严,我火速辦了婚禮昂灵,結果婚禮上避凝,老公的妹妹穿的比我還像新娘。我一直安慰自己眨补,他們只是感情好管削,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撑螺,像睡著了一般含思。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上甘晤,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天含潘,我揣著相機與錄音,去河邊找鬼线婚。 笑死遏弱,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的塞弊。 我是一名探鬼主播漱逸,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼游沿!你這毒婦竟也來了饰抒?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤诀黍,失蹤者是張志新(化名)和其女友劉穎循集,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔗草,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年疆柔,在試婚紗的時候發(fā)現(xiàn)自己被綠了咒精。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡旷档,死狀恐怖模叙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鞋屈,我是刑警寧澤范咨,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站厂庇,受9級特大地震影響渠啊,放射性物質發(fā)生泄漏。R本人自食惡果不足惜权旷,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一替蛉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦躲查、人聲如沸它浅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姐霍。三九已至,卻和暖如春典唇,著一層夾襖步出監(jiān)牢的瞬間镊折,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工蚓聘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留腌乡,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓夜牡,卻偏偏與公主長得像与纽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子塘装,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1. 簡介 1.1 什么是 MyBatis 急迂? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,527評論 0 4
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應的列上鍵入重復值時蹦肴,會觸發(fā)此異常僚碎。 O...
    我想起個好名字閱讀 5,333評論 0 9
  • MyBatis 理論篇 [TOC] 什么是MyBatis ?MyBatis是支持普通SQL查詢,存儲過程和高級映射...
    有_味閱讀 2,908評論 0 26
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,109評論 1 32
  • http://app.yiyiwawa.com/app_share_myreading.aspx?hbid=243...
    劉家洋洋閱讀 153評論 0 0