反射泛型和反射注解概括起來(lái)就三步:
- 自定義注解
- 通過(guò)反射獲取注解值
- 使用自定義注解
最終案例
通過(guò)自定義注解,將數(shù)據(jù)庫(kù)表與Java對(duì)象映射,在不需要配置文件的情況下,查詢出數(shù)據(jù)庫(kù)的記錄
分析:數(shù)據(jù)庫(kù)表有數(shù)據(jù)庫(kù)名,表名和字段,所以在定義注解時(shí)這些都是必須的,但是在查詢時(shí)有通過(guò)主鍵查詢的方式,那么如何知道哪個(gè)字段是主鍵呢,這就需要來(lái)聲明一下,所以,還需要定義一個(gè)id注解用于標(biāo)識(shí)某對(duì)象的某屬性對(duì)應(yīng)著數(shù)據(jù)庫(kù)的主鍵。此時(shí)就需要來(lái)說(shuō)明一下什么是注解。
注解
什么是注解
- 語(yǔ)法:
@注解名稱 - 注解的作用:替代
xml配置文件 - Servlet3.0中就可以不在使用
web.xml文件,而是所有配置文件都使用注解。 - 注解是由框架來(lái)讀取的!
注解的使用!
- 定義注解類(框架的工作)
- 使用注解(我們的工作)
- 讀取注解(反射讀取注解)(框架的工作)
注解其實(shí)也是一個(gè)類
如何定義注解類
class A{}定義類
interface A{}定義接口
@interface A{} 定義注解
- 天下所有的注解都是Annotation的子類
不用特意標(biāo)記默認(rèn)就是
如何使用注解
首先自定義一個(gè)注解:
//自定義注解類
package annotation;
@interface MyAnnotation {
//暫時(shí)不寫內(nèi)容,只是演示注解的使用
}
使用自定義MyAnnotation注解
package annotation;
@MyAnnotation//注解能放在類上
public class Demo1 {
@MyAnnotation//注解能放在成員變量上
private String name;
@MyAnnotation//注解能放在構(gòu)造器上
public void Demo1(){
}
@MyAnnotation//注解能放在方法上
public void test1(){
}
public void test2(@MyAnnotation String name){//注解能放在參數(shù)上
//注解能放在局部變量上
@MyAnnotation
String username = "hello";
}
//但是注解不能放在方法的調(diào)用上
}
注解的作用目標(biāo)
由上述使用注解的例子可以看出,注解的作用目標(biāo)有一下幾種:
- 類
- 方法
- 構(gòu)造器
- 參數(shù)
- 局部變量
- 包
注解的屬性(依賴文檔了解)
- 定義屬性
格式:類型 屬性名()
例如:
//注解類
@interface MyAnno1{
int age();//這是屬性不是方法
String name();//括號(hào)后面不能跟{},也不能加參數(shù),因?yàn)檫@不是方法,而是注解的屬性
}
- 使用注解時(shí)給屬性賦值
//使用屬性時(shí),屬性必須要求有值
@MyAnno1(age=100,name="zhangsan")
- 注解屬性的默認(rèn)值
//注解類
@interface MyAnno2{
int age() default 100;//這是屬性不是方法
String name();
}
使用時(shí):@MyAnno2(name="zhangsan")
也可以在給一個(gè)age值如:
@MyAnno2(age="999",name="zhangsan")
此時(shí)值會(huì)覆蓋默認(rèn)值
- 名為value的屬性的特權(quán)
在使用注解時(shí),如果只給名為value的屬性賦值,那么可以不給出屬性的名稱直接給出值
例如:
//注解的特權(quán)
@interface MyAnno3{
int value();
String name() default "hello world";
}
使用注解時(shí):
@MyAnno3(100)相當(dāng)于給value的屬性賦值不用指定value
- 注解屬性的類型
注解屬性有8中基本類型:
- String
- Enum
- Class
- 注解類型(和循環(huán)體的內(nèi)容是循環(huán)體是一個(gè)道理)
- 以上類型的一維數(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 {
}
當(dāng)給數(shù)組類型的屬性賦值時(shí),可以省略大括號(hào)
如f="hello"
注解的作用目標(biāo)限定以及保存策略限定
讓一個(gè)注解他的作用目標(biāo)只能在類上不能在方法上,這就叫做目標(biāo)的限定
- 在定義注解時(shí)給注解添加注解叫做@Target
@Target(value={ElementType.TYPE,ElementType.ANNOTATION_TYPE,ElementType.METHOD,ElementType.FIELD})
@interface MyAnno1{
}
保留策略
- 源代碼文件(SOURCE):注解只在源代碼中存在,在編譯時(shí)就別忽略了(無(wú)法反射)
- 字節(jié)碼文件(CLASS):注解在源代碼中存在,編譯時(shí)會(huì)把注解信息放到class中存在,但JVM在類時(shí)會(huì)被忽略加載注解(無(wú)法反射)
- JVM中(RUNTIME):注解在源代碼,字節(jié)碼文件中存在,并且在JVM加載類時(shí)會(huì)把注解加載到JVM內(nèi)存中(它是唯一可以反射的注解)
限定注解的而保留策略
@Retention(RetentionPolicy.RUNTIME)//保留策略
@interface MyAnno1{
}
讀取注解
反射泛型信息:
Class --> Type getGenericSuperclass()
Type --> ParameterizedType,把Type強(qiáng)轉(zhuǎn)為ParameterizedType類型
ParameterizedType --> 參數(shù)化類型 = A<String>
ParameterizedType :Type[] getActualTypeArguments(),A<String>中的String
Type[]就是Class[],我們就得到了類型參數(shù)了!
通過(guò)上述描述的步驟既可以獲的類型參數(shù)
public class Demo1 {
@Test
public void fun1(){
new B();//執(zhí)行得到j(luò)ava.lang.String
}
}
class A<T> {
public A() {
/*
* 在這里獲取子類傳遞的泛型信息,要得到一個(gè)Class
*/
// Class clazz = this.getClass();//得到子類的類型
// Type type = clazz.getGenericSuperclass();//獲取傳遞給父類參數(shù)化類型
// ParameterizedType pType=(ParameterizedType)type;//它就是A<String>
// Type[] types = pType.getActualTypeArguments();//它就是一個(gè)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> {
}
反射注解
上面講述了如何通過(guò)反射來(lái)得到類的類型,那么要通過(guò)反射得到注解,要求注解的保留策略必須是RUNTIME
反射注解需要從作用目標(biāo)開始反射
- 類上的注解,需要使用Class來(lái)獲取
- 方法上的注解需要Method來(lái)獲取
- 構(gòu)造器上的注解需要Constructor來(lái)獲取
- 成員山谷的需要使用Field來(lái)獲取
一下?lián)碛锌梢垣@取注解的方法:
- Class:
- Method、Constructor、Field有共同的父類:AccessibleObject
它們都有一個(gè)方法: - Annotation getAnnotation(Class),返回目標(biāo)上指定類型的注解
- Annotation[] getAnnoations(),返回目標(biāo)注解上所有的注解
定義一個(gè)注解MyAnno1 ,在定義一個(gè)類A來(lái)使用注解
@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();
}
通過(guò)下面的代碼來(lái)演示如何獲得作用在A類上的注解
public class Demo2 {
@Test
public void test1(){
/*
* 1.得到作用目標(biāo)
*/
Class<A> c = A.class;
/*
* 2.獲取指定類型的注解
*/
MyAnno1 myAnno1 = c.getAnnotation(MyAnno1.class);
System.out.println(myAnno1);//結(jié)果@demo2.MyAnno1(name=A類, age=20, sex=男)
}
@Test
public void test2() throws NoSuchMethodException, SecurityException{
/*
* 1.得到作用目標(biāo)
*/
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());
}
}
通過(guò)上述內(nèi)容,我們了解了什么是如何通過(guò)反射獲取類型參數(shù),以及什么是注解,注解該如何通過(guò)反射獲取,那么作為練習(xí),下面就完成通過(guò)注解來(lái)寫一個(gè)BaseDao的實(shí)驗(yàn)
完成注解案例
首先我們根據(jù)實(shí)驗(yàn)的分析,創(chuàng)建注解類
/**
* <p>Title: Table</p>
* <p>Description: Table 注解類用于標(biāo)識(shí)哪個(gè)對(duì)象對(duì)應(yīng)數(shù)據(jù)庫(kù)的哪一張表,作用在類上</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ù)庫(kù)字段映射到j(luò)ava對(duì)象屬性上</p>
* @author guqin
* @date 2018年9月23日
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
/**
* <p>Title: ID</p>
* <p>Description: ID注解類用于在對(duì)象屬性上標(biāo)識(shí)哪一個(gè)字段是數(shù)據(jù)庫(kù)主鍵</p>
* @author guqin
* @date 2018年9月23日
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface ID {
String value();
}
為什么沒(méi)有數(shù)據(jù)庫(kù)名的注解呢,眾所周知,連接數(shù)據(jù)庫(kù)需要指定庫(kù)名,用戶名和密碼才能訪問(wèn),這些信息都是配置在外部的配置文件中的,比如JDBC、Hibernate或者其他,于此同時(shí)還會(huì)使用數(shù)據(jù)庫(kù)連接池比如DBCP、C3P0連接池等,那么數(shù)據(jù)庫(kù)名及用戶名密碼就會(huì)配置在這些的配置文件當(dāng)中,比如可以寫一個(gè)jdbc.properties,所以是不需要指定庫(kù)名的注解的而且這中信息還是多個(gè)對(duì)象公用的。
下面以查詢user表為例來(lái)映射一個(gè)User對(duì)象:
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")//它的值表示當(dāng)前類對(duì)應(yīng)的表
public class User {
@ID("u_id")//當(dāng)前屬性對(duì)應(yīng)的列明,而且說(shuō)明這個(gè)列是主鍵列
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語(yǔ)句查詢數(shù)據(jù)庫(kù)
- 映射結(jié)果集
獲取注解信息
package guqing.basedao;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* <p>Title: MatchField</p>
* <p>Description: 該類用于字段匹配,將數(shù)據(jù)庫(kù)字段與java對(duì)象屬性映射 </p>
* @author guqin
* @date 2018年9月26日
*/
public class MatchField {
private static String primary;//數(shù)據(jù)庫(kù)主鍵
private static String primaryName;//標(biāo)有@ID注解的對(duì)象屬性名
//通過(guò)單例設(shè)計(jì)模式,返回唯一實(shí)例
private static MatchField matchField = new MatchField();
//私有構(gòu)造方法,對(duì)外提供獲取該對(duì)象的方法來(lái)拿到唯一靜態(tài)實(shí)例
private MatchField(){}
/**
* @Title: getMatchFieldInstance
* @Description: 獲取該對(duì)象的句柄
* @param @return
* @return MatchField
* @throws
*/
public static MatchField getMatchFieldInstance() {
return matchField;
}
/**
* @Title: MappingField2Map
* @Description: 字段映射方法,返回一個(gè)Map,key=對(duì)象屬性名 ,value=數(shù)據(jù)庫(kù)字段名
* @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) {
//拿到至關(guān)重要的數(shù)據(jù)庫(kù)主鍵字段與@ID注解的對(duì)象屬性名,將其放到Map中形成映射鍵值對(duì)
primary = id.value();
primaryName = field.getName();
fieldMapping.put(primaryName, primary);//對(duì)象的成員變量名-->表字段名
} else if(column!=null) {
//拿到其他普通數(shù)據(jù)庫(kù)字段與普通字段對(duì)應(yīng)的java對(duì)象屬性,同樣放到Map中形成映射關(guān)聯(lián)
fieldMapping.put(field.getName(), column.value());
} else {
//如果都不是那么默認(rèn)就是字段名-->對(duì)應(yīng)數(shù)據(jù)庫(kù)字段名
//也就是對(duì)象屬性可以不標(biāo)識(shí)注解表示與數(shù)據(jù)庫(kù)字段同名
//也可以自己再改進(jìn)一下比如設(shè)置默認(rèn)值或者駝峰命名等
//甚至還可以寫一個(gè)xml配置文件用于配置數(shù)據(jù)庫(kù)字段與對(duì)象屬性的映射
//然后讀取配置文件的內(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)");
}
//返回?cái)?shù)據(jù)庫(kù)字段與對(duì)象屬性映射關(guān)系的Map
return fieldMapping;
}
/**
* @Title: precursorSelectSql
* @Description: 通過(guò)上面的MappingField2Map方法拼湊查詢語(yǔ)句的前半部分
* @param @param beanClass
* @param @return
* @return String
* @throws
*/
public String precursorSelectSql(Class<?> beanClass){
//通過(guò)beanClass得到字段映射Map
Map<String,String> mappingField = MappingField2Map(beanClass);
//拿到j(luò)avaBean所有成員變量
Field[] fields = beanClass.getDeclaredFields();
//創(chuàng)建查詢語(yǔ)句前驅(qū)
StringBuilder sb = new StringBuilder("select ");
//拼湊sql語(yǔ)句
for(int i=0;i<fields.length;i++){
sb.append("`"+mappingField.get(fields[i].getName())+"`");//通過(guò)鍵獲得表的字段名稱
sb.append(" as "+"`"+fields[i].getName()+"`");
if(i<fields.length-1){
sb.append(",");//最后一個(gè)不加逗號(hào)
}
}
sb.append(" ");
return sb.toString();
}
/**
* @Title: getBeanPrimaryName
* @Description: 返回javabean中作為主鍵的成員變量名稱
* @param @return
* @return String
* @throws
*/
public String getBeanPrimaryName(){
return primaryName;
}
}
其實(shí)有了數(shù)據(jù)庫(kù)字段與對(duì)象屬性的映射就可以比較方便的完成查詢更新刪除添加等操作了,都是寫平湊sql語(yǔ)句的活。缺點(diǎn)是只能進(jìn)行簡(jiǎn)單屬性的映射。
下面就是通過(guò)上面的映射方式寫的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;//通過(guò)父類獲取子類類型
private String primaryName;//Dao主鍵字段名稱
private String tablename;//表名稱
private Map<String,String> mappingField;//存儲(chǔ)字段映射
//獲取到MappingField對(duì)象
private MatchField matchField = MatchField.getMatchFieldInstance();
//構(gòu)造方法
@SuppressWarnings("unchecked")
public BaseDao(){
//通過(guò)父類獲取子類類型
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(幾個(gè)?)";
//通過(guò)反射將類中屬性的個(gè)數(shù)清楚就是問(wèn)號(hào)的個(gè)數(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: 通過(guò)主鍵查詢
* @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 {
//查詢語(yǔ)句的前半部分 + 用戶自定義的后半部分查詢語(yǔ)句
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ù)個(gè)數(shù)沒(méi)給夠]");
}
return qr.query(querySql, new BeanListHandler<T>(beanClass));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Title: getGetMethodString
* @Description: 通過(guò)成員變量屬性名稱獲取到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語(yǔ)句的前半部分
StringBuilder firstHalfSql = new StringBuilder("update "+"`"+tablename+"`");//前綴
StringBuilder setSql = new StringBuilder();//后綴
Object primaryValue = null;
//先在第一個(gè)占位符也就是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;//略過(guò)主鍵
}
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語(yǔ)句的參數(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;
}
}