最近一个同学用jdbc做了一个java项目,感觉里面有好多将查询语句封装到javaBean里的代码,比如下面这个
if (resultSet != null) {
while (resultSet.next()) {
TeaEntity teaEntity=new TeaEntity();
teaEntity.setCreateTime(resultSet.getDate("createTime")); teaEntity.setImageurl(resultSet.getString("imageurl")); teaEntity.setIntroduce(resultSet.getString("introduce")); teaEntity.setPrice(new BigDecimal(resultSet.getString("price")));
teaEntity.setState(new Integer(resultSet.getString("state")));
teaEntity.setTeaId(resultSet.getInt("teaId"));
teaEntity.setTeaName(resultSet.getString("teaName"));
teaEntity.setType(resultSet.getInt("type"));
teaEntity.setUpdateTime(resultSet.getDate("updateTime"));
teaList.add(teaEntity);
}
}
类似的地方还有很多,代码很杂糅,
于是制作一个工具类 如下:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.beanutils.ConvertUtils;
/**
* 将结果集resultSet映射成为javabean(前提是javaBean中的属性名称和数据库中的字段名称一样)
* @author wzh
*
*/
public class ColumnToFieldMappingUtil {
/**
* 将结果集resultSet映射成为javabean
* @param rs 数据库查询数据的结果集
* @param clazz 需要映射成为的javaBean的class
* @return 一个携带javaBean的List
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static List<Object> ColumnToField(ResultSet rs,Class clazz) throws Exception{
Object obj=clazz.newInstance();
Field[] fields=clazz.getDeclaredFields();
List<Object> list=new ArrayList<Object>();
while(rs.next()){
for(Field f:fields){
String name=f.getName();
Class type=f.getType();
Method method=null;
try {
method=clazz.getMethod("set"+name.replaceFirst(name.substring(0, 1),
name.substring(0, 1).toUpperCase()), type);
ConvertUtils.register(new MyConvert(), Date.class);
Object qqq=ConvertUtils.convert(rs.getString(name),type);
System.out.println(qqq);
method.invoke(obj,ConvertUtils.convert(rs.getString(name),type));
} catch (Exception e) {
e.printStackTrace();
}
}
list.add(obj);
}
return list;
}
}
当然里面有一个自定义的日期类型转换器,因为ConvertUtils是无法自动转化日期类型的。日期类型转换器代码如下:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.beanutils.Converter;
/**
* 自定义时间格式转换器
*/
public class MyConvert implements Converter{
@Override
public Object convert(Class type, Object value) {
if(value==null) return null;
if(!type.toString().equals("class java.util.Date")) return (String)value;
String str=(String)value;
SimpleDateFormat smDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date=smDateFormat.parse(str);
return date;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
利用这两个类就可以将resultSet实现动态映射到javaBean中了。
但是这样还有一个缺点,就是如果javaBean中的属性名称和数据库内的字段名称不一致,那就该属性的映射就会失败。
考虑一番后决定使用注解的方式解决这个问题,能在javaBean中的属性上标记一个@column的注解就能映射到数据库的相应的字段。实现过程如下:
1.自定义一个注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
/**
* 映射的列名
* @return
*/
String value();
}
2.更改上面的ColumnToFieldMappingUtil类,我们新建一个类,类名为NewColumnToFieldMappingUtil。代码如下:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.beanutils.ConvertUtils;
import com.hdzx.yl.annotation.Column;
/**
* 将结果集resultSet映射成为javabean(前提是javaBean中的属性名称和数据库中的字段名称一样)
* @author wzh
*
*/
public class NewColumnToFieldMappingUtil {
/**
* 将结果集resultSet映射成为javabean
* @param rs 数据库查询数据的结果集
* @param clazz 需要映射成为的javaBean的class
* @return 一个携带javaBean的List
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static List<Object> ColumnToField(ResultSet rs,Class clazz) throws Exception{
Object obj=clazz.newInstance();
Field[] fields=clazz.getDeclaredFields();
List<Object> list=new ArrayList<Object>();
while(rs.next()){
for(Field f:fields){
//得到字段名
String name=f.getName();
//默认情况下列名等于javaBean里的属性的值
String columnName=new String(name);
//得到字段类型
Class type=f.getType();
//判断字段上是否有注解
if(f.isAnnotationPresent(Column.class)){
//获取字段上column注解的值,并附值给列名
columnName=f.getAnnotation(Column.class).value();
}
Method method=null;
try {
//反射得到javaBean每个字段的set方法
method=clazz.getMethod("set"+name.replaceFirst(name.substring(0, 1),
name.substring(0, 1).toUpperCase()), type);
//注册时间类型转换器
ConvertUtils.register(new MyConvert(), Date.class);
//调用set方法为对象设置值
method.invoke(obj,ConvertUtils.convert(rs.getString(columnName),type));
} catch (Exception e) {
e.printStackTrace();
}
}
list.add(obj);
}
return list;
}
}
动态将resultSet查询出的结果集封装到JavaBean,就这样就完成了。
现在看一下测试效果
/**
* 测试数据库中取出的结果集是否能正常反射到javabean
* @throws Exception
*/
@Test
public void testResultSet() throws Exception{
Connection connection=DBUtil.getConnection();
String str="select * from user";
PreparedStatement preparedStatement=connection.prepareStatement(str);
ResultSet rs=preparedStatement.executeQuery();
List users=NewColumnToFieldMappingUtil.ColumnToField(rs, UserEntity.class);
System.out.println(users);
}
输出结果:
好了,教程就倒这里。O(∩_∩)O~