需求:
(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; } }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索resultset的...
, string
, private
, 变量
, 成员变量的使用问题
, resultset
, 一个
成员
java 自动填充网页、java resultset、java resultset 遍历、java resultset 行数、java.sql.resultset,以便于您获取更多的相关知识。