泛型,注解,反射配合优化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;
    }

}
时间: 2024-12-30 01:57:07

泛型,注解,反射配合优化BaseDao的猜想的相关文章

框架学习前基础加强 泛型,注解,反射(泛型&注解)应用案例,IOC,Servlet3.0,动态代理,类加载器

泛型 1. 泛型类 :具有一个或多个类型变量的类,称之为泛型类! class A<T> { } 2. 在创建泛型类实例时,需要为其类型变量赋值 A<String> a = new A<String>(); * 如果创建实例时,不给类型变量赋值,那么会有一个警告! 3. 泛型方法 :具有一个或多个类型变量的方法,称之为泛型方法! class A<T> { public T fun(T t1) {} } fun()方法不是泛型方法!它是泛型类中的一个方法! pu

C# 之 反射性能优化

反射是一种很重要的技术,然而它与直接调用相比性能要慢很多,因此如何优化反射性能也就成为一个不得不面对的问题. 目前最常见的优化反射性能的方法就是采用委托:用委托的方式调用需要反射调用的方法(或者属性.字段). 目前最常见也就是二种方法:Emit, ExpressionTree .其中ExpressionTree可认为是Emit方法的简化版本, 所以Emit是最根本的方法,它采用在运行时动态构造一段IL代码来包装需要反射调用的代码, 这段动态生成的代码满足某个委托的签名,因此最后可以采用委托的方式

C# 之 反射性能优化3

阅读目录 开始 用Delegate优化反射的缺点 用Delegate优化反射的优点 用CodeDOM优化反射的优点 如何用好CodeDOM? 用CodeDOM优化反射的缺点 能不能不使用委托? 根据反射密集程度选择优化方法 CodeDOM优化的误区 反射优化的总结 在前二篇博客中,我分别介绍了二种优化反射的方法: 1. Delegate:委托. 2. CodeDOM:动态代码生成. 这是二种截然不同的方法,性能的差距也很大. 今天的博客将着重比较它们的优缺点,以及给出它们的使用建议. 回到顶部

泛型和反射

泛型和反射经常是一起工作的,所以就一次介绍吧. c# 是强类型语言,一般上函数的返回类型和参数的类型都是一早些好的,也就造成了很多时候不像js那样方便使用,不灵话. 所以呢就有了这个泛型,它可以让你的函数和参数在调用的时候才决定类型. public T abc<T>(T word) { return word; return default(T); //关键字default可以对引用类型返回nullAble,int类型返回0,初始化一个T的感觉啦 } abc<string>(&qu

用泛型和反射实现函数通用

使用泛型和反射机制事项函数的通用,写下来,欢迎吐槽 代码示例使用vb. net Imports System.Reflection Module Module1 Sub Main() Dim lst1 As List(Of Person) = New List(Of Person)() Dim lst2 As List(Of Person) = New List(Of Person)() Dim lstT As List(Of Person) = New List(Of Person)() Fo

Java高质量代码之 — 泛型与反射

在Java5后推出了泛型,使我们在编译期间操作集合或类时更加的安全,更方便代码的阅读,而让身为编译性语言的Java提供动态性的反射技术,更是在框架开发中大行其道,从而让Java活起来,下面看一下在使用泛型和反射需要注意和了解的事情? 1.Java的泛型是类型擦除的????? Java中的泛型是在编译期间有效的,在运行期间将会被删除,也就是所有泛型参数类型在编译后都会被清除掉.请看以下例子? Java代码??? publicstaticvoid?test(List??testParameter)?

应用Java泛型和反射导出CSV文件

项目中有需求要把数据导出为CSV文件,因为不同的类有不同的属性,为了代码简单,应用Java的泛型和反射,写了一个函数,完成导出功能. public <T> void saveFile(List<T> list, String outFile) throws IOException { if (list == null || list.isEmpty()) { return; } if (StringUtils.isEmpty(outFile)) { throw new Illega

实施 ORM 的两项要旨:泛型和反射

鄙人认为,实施 ORM 的两项要旨乃泛型和反射.下面开始看看怎么为 DAO 层添砖加瓦. 首先,在 DBAccess 基础上扩展 DBAccessORM 接口,形成基于 ORM 的数据调用. /** * 数据访问对象 * * @author Frank Cheung * */ public interface DBAccessORM extends DBAccess { /** * 查询单笔记录,返回实体 * * @param sql * 原生 SQL 语句 * @param clazz * P

java5核心基础泛型(2):泛型在反射中的应用

如何通过反射获取指定参数类型的构造函数? 贴代码如下: package highBasic.generic; /** * 泛型入门 */ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; public class GenericTest { public static void main(St