成都java开发培训
达内成都高升桥中心

13658085802

热门课程

Java中ResultSet数据自动填充到类中&类实例填充PreparedStatement

  • 时间:2016-08-26 11:42
  • 发布:成都Java培训
  • 来源:企业笔试题

需求:

(1)提取ResultSet中值到一个类中挺麻烦的,需要new一个变量,使用对应成员的Set方法赋值,能不能根据类的Class,直接提取出ResultSet中的数据,最后返回实例化的类?

(2)可以用PreparedStatement预编译带变量的sql语句,在execute之前需要将变量值填充进去,一个一个设置太麻烦了,能不能提供一个类变量,使用类成员变量的值自动填充PreparedStatement?

这样的功能许多开源的框架可以实现,但是不想因为这么一点点的需求去学习那么庞大的一套框架,于是自己实现了一下,总结下自己的实现思路。

实现这套框架下面两个问题是必须考虑到的:

数据库表的字段名称可能和类的成员名称不一样。举个例子数据库表中经常有这样的命名modify_time,在类中很少会使用下划线,一般倾向于modifyTime这样的命名方式。

预编译的sql语句中变量的顺序和类中成员变量的顺序可能会不同。

怎么将类成员的值对应到预编译好的PreparedStatement中对应的变量上。

解决问题1和问题2的方法是为类成员提供别名,使用java中的Annotation(标注)机制,标注接口如下:

1 @Target(ElementType.FIELD)

2 @Retention(RetentionPolicy.RUNTIME)

3 public @interface Column {

4     String value();

5 }

标注的例子:

public class Work extends WorkAbstraction{
        
    @Column(value = "coop_type")
    private Integer coopType;
        
    private String subtitle;
    private String coworker;
    private String tutor;
        
    @Column(value = "create_time")
    private String createTime;
        
    @Column(value = "modify_time")
    private String modifyTime;
    private String content;
}

在数据库中有一个work表,有一个字段名是modify_time,对应实体类Work中相应字段被命名为modifyTime,使用@Column(value = "modify_time")为属性modifyTime提供别名modify_time,对于没有别名的属性,默认其和ResultSet中的列名称相同。

仅仅提供别名是不够的,从ResultSet中可以获取到查询结果的列名称字段,此时如果想要将ResultSet中的数据填充到某个class中,还需要一个数据结构:

HashMap<Class<?>,HashMap<String,Field>> mappingPools;

HashMap的主键是数据类的Class,HashMap的Value还是一个Map,HashMap<String,Field>,该Map的主键是类中成员变量的别名,value是java反射类型Field,利用java反射机制就可以很容易通过Field向数据类填充数据。

接下来的问题就是已知class,怎么解析出上面的HashMap结构,代码如下:

public class BeanMappingPool {
    private static Lock lock = new ReentrantLock();
    private static HashMap<Class<?>,HashMap<String,Field>> mappingPools;
    static{
        mappingPools = new HashMap<Class<?>,HashMap<String,Field>>();
    };
    public static HashMap<String,Field> GetFieldsMap(Class<?> objClass){
        if(mappingPools.get(objClass) != null)
            return mappingPools.get(objClass);
        lock.lock();
        if(mappingPools.get(objClass) != null){
            lock.unlock();
            return mappingPools.get(objClass);
        }
        HashMap<String,Field> pools = new HashMap<String,Field>();
        for(;objClass != Object.class; objClass = objClass.getSuperclass())
            for(Field f: objClass.getDeclaredFields()){
                f.setAccessible(true);
                Column col = f.getAnnotation(Column.class);
                if(col != null)
                    pools.put(col.value(), f);
                else
                    pools.put(f.getName(), f);
            }
        mappingPools.put(objClass, pools);
        lock.unlock();
        return pools;
    }
}
上一篇:HibernateTemplate类的用法
下一篇:超轻量级DI容器框架Google Guice与Spring框架的区别

2016 年热门编程语言岗位需求及薪资分析

大公司喜欢问的Java集合类面试题

世界著名程序员职场建议

选择城市和中心
贵州省

广西省

海南省