偶然间听说jdbctemplate,spring对jdbc的封装查询。小T(我)之前一直使用的ibaties。spring使用都没有迈过3.0这个槛,所以听说
这门技术时,想学习下,练练手。在写jdbctemplate的查询时觉得代码量有些大。所以尝试着学习ibaties等ORM框架进行了一下单
表的简单封装。以下纯属于个人理解,如果不对,请各位看客指出来。我也好学习进步。
首先了解spring的jdbcTemplate。
这张图是jdbcTemplate的一段查询代码。 RowMapper为spring中的一个抽象接口,此处匿名内部类实现该接口,mapRow这个
方法则将ResultSet中的值进行处理。
而我的思路
思路:利用java反射机制进行实例化,并且找到对应方法设置属性。然后返回。
代码如下:
package com.mrt.base;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import org.springframework.jdbc.core.RowMapper;
@SuppressWarnings("unchecked")
public class MyMapper implements RowMapper{
String classPath;
String[] fields;
/**
* 初实话类路径
* 初始化属性数组
* @param classPath_
* @param fields
*/
public MyMapper(String classPath_,String[] fields){
this.classPath = classPath_;
this.fields = fields;
}
/**
* 获取类所有属性及其类型
*/
public HashMap<String,Class<?>> init(){
try {
HashMap<String,Class<?>> fieldHashMap=new HashMap<String,Class<?>>();
Class<?> cls = Class.forName(classPath);
Field[] fieldlist = cls.getDeclaredFields();
for (int i = 0; i < fieldlist.length; i++) {
Field fld = fieldlist[i];
fieldHashMap.put(fld.getName(), fld.getType());
}
return fieldHashMap;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* 拼装get方法
* @return
*/
@SuppressWarnings("unused")
private String getGetMethod(String fieldName){
String field = "get";
field = field+toUpperCaseFirstOne(fieldName);
return field;
}
/**
* 拼装set方法
* @return
*/
private String getSetMethod(String fieldName){
String field = "set";
field = field+toUpperCaseFirstOne(fieldName);
return field;
}
/**
* 首字母转化小写
* @param s
* @return
*/
@SuppressWarnings("unused")
private static String toLowerCaseFirstOne(String s) {
if (Character.isLowerCase(s.charAt(0))) {
return s;
} else {
return (new StringBuilder()).append(
Character.toLowerCase(s.charAt(0))).append(s.substring(1))
.toString();
}
}
/**
* 首字母转化为大写
* @param s
* @return
*/
private static String toUpperCaseFirstOne(String s) {
if (Character.isUpperCase(s.charAt(0))) {
return s;
} else {
return (new StringBuilder()).append(
Character.toUpperCase(s.charAt(0))).append(s.substring(1))
.toString();
}
}
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Class<?> cls = null;
Object obj_ = null;
try {
cls = Class.forName(classPath);
obj_ = cls.newInstance();
HashMap<String, Class<?>> map = this.init();
for (int i = 0; i < fields.length; i++) {
String methodName = this.getSetMethod(fields[i]);
Object obj = rs.getObject(fields[i]);
cls.getDeclaredMethod(methodName, map.get(fields[i])).invoke(obj_,obj);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return obj_;
}
}
在MyMapper这个类中,实例化需要传入classPath、fields.分别表示:类路径和需要查询的字段对应的属性的数组。类路径是为了反射找到该类。而属性数字则是为了为对应属性赋值。开始有考虑直接传入一个查询的表字段的字符串,逗号分隔的。而根据表字段名下划线(_)作为分隔,将字段处理成对应属性。例如: user_id------>userId、user_name------>userName。有兴趣朋友可以试试。
以下是查询代码
@SuppressWarnings("unchecked")
@Override
public List<User> getAllUser() {
String sql = "SELECT user_id AS userId,user_name AS userName,user_pwd AS userPwd,user_real_name AS userRealName,user_type AS userType FROM tb_user";
String [] fields = {"userId","userName","userPwd","userRealName","userType"};
List<User> users = this.getJdbcTemplate().query(sql,new MyMapper("com.mrt.pojo.User", fields));
return users;
}
要注意的是查询sql中,表字段都as成了类属性。
就这样简单封装查询就OK了。请看客宽恕有网友说有车还去造轮子的做法............当然,想交流的话可以加QQ1254037817