泛型,注解,反射配合优化BaseDao的猜想
package test; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.sql.SQLException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.dbutils.QueryRunner; import org.junit.Test; import cn.itcast.tool.jdbc.TXQueryRunner; public class Demo2 { @Test public void fun1() throws Exception{ UserDao bd=new UserDao(); User user=new User(); user.setId("guodaxia"); user.setUsername("guozhen"); user.setPassword("961012gz"); user.setState(true); bd.add(user); } } class UserDao extends BaseDAO<User>{ } class BaseDAO<T>{ QueryRunner qr=new TXQueryRunner(); Class<T> beanClass; String id; public BaseDAO(){ beanClass=(Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } public int add(T bean) throws Exception{ /* * 首先我们思考,表名如何得到呢? * 我们假定将所有的bean类名都与表名相同,那样就变成了求类名 * * values里面的?个数是多少呢? * 我们又假定所有的bean的属性字段对应数据库表的字段,这样所有属性的个数就对应了?的个数 * * 参数的值如何得到呢? * 既然我们都得到了对应的bean属性,调用其中每个属性的的getXxx方法即可 * * 刚才我们简单地推出了sql语句和简单地推出了参数值,这样就可以执行我们的操作了。 * 但是我们的类名和表名,属性名和数据库字段名就一定会对应吗?比如我得表名是“db_user” * 我们可以使用配置文件达到效果,这里我们使用注解实现 * */ // String tableName=beanClass.getSimpleName(); String tableName=beanClass.getAnnotation(Table.class).value(); Field[] fields=beanClass.getDeclaredFields(); Map<String,Object> map=new LinkedHashMap<String, Object>();//这个是为了有序 for(Field f:fields){ Annotation[] anns=f.getAnnotations(); for(Annotation a:anns){ if(a.annotationType()==ID.class){ id=f.getAnnotation(ID.class).value();//这里只是针对简单的单个id的情况 map.put(id, f.getName()); break; }else if(a.annotationType()==Column.class){ map.put(f.getAnnotation(Column.class).value(), f.getName()); break; } } } String sql="insert into "+tableName+" values ("; // for(int i=0;i<fields.length;i++){ // sql=sql+"?"; // if(i<fields.length-1){ // sql=sql+","; // } // } for(int i=0;i<map.size();i++){ sql=sql+"?"; if(i<map.size()-1){ sql=sql+","; } } sql=sql+")"; System.out.println(sql); // String sql="insert into "+"标名"+" values ("+"几个?"+")"; // Object[] params={}; /* * 当字段类型为boolean类型的时候,其getXxx或者isXxx都有可能 * * */ // Object[] params=new Object[fields.length]; ArrayList<Object> params=new ArrayList<Object>(); // for(int i=0;i<fields.length;i++){ // Field f=fields[i]; // // String methodName="get"+f.getName().substring(0, 1).toUpperCase()+f.getName().substring(1); // Method method = null ; // try { // method = beanClass.getMethod(methodName); // } catch (NoSuchMethodException e) { // if(f.getType().getName().equals("boolean")){ // methodName="is"+f.getName().substring(0, 1).toUpperCase()+f.getName().substring(1); // method=beanClass.getMethod(methodName); // } // } // // params[i]=method.invoke(bean); // } Set<String> keys=map.keySet(); for(String key:keys){ String filedName=(String) map.get(key); Field f=beanClass.getDeclaredField(filedName); String methodName="get"+filedName.substring(0, 1).toUpperCase()+filedName.substring(1); Method method=null; try { method = beanClass.getMethod(methodName); } catch (NoSuchMethodException e) { if(f.getType().getName().equals("boolean")){ methodName="is"+filedName.substring(0, 1).toUpperCase()+filedName.substring(1); method=beanClass.getMethod(methodName); }else{ throw e; } } params.add(method.invoke(bean)); } System.out.println(params.toString()); return 0; // return qr.update(sql,params); } public int delete(String uuid) throws SQLException{ String sql=""; Object[] params={}; return qr.update(sql,params); } public int update(T bean) throws SQLException{ String sql=""; Object[] params={}; return qr.update(sql,params); } public T load(String uuid) throws SQLException{ String sql=""; Object[] params={}; return null; } public List<T> findAll(){ String sql=""; Object[] params={}; return null; } } package test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Column { String value(); } package test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ID { String value(); } package test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Table { String value(); } package test; @Table("tb_user") public class User { @ID("id") private String id; @Column("uname") private String username; @Column("pwd") private String password; @Column("state") private boolean state; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean isState() { return state; } public void setState(boolean state) { this.state = state; } public User() { super(); } public User(String id, String username, String password, boolean state) { super(); this.id = id; this.username = username; this.password = password; this.state = state; } }