BeanUtils Date

Posted 啄木鸟伍迪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BeanUtils Date相关的知识,希望对你有一定的参考价值。

在jdbc封装(基础的CRUD)的时候(查询一条数据,查询多条数据,更新。。。。)经常会用到一个BeanUtil来设置属性值,当对象中存在Date类型的时候,会报错:如下:

2017-11-03 13:47:01 13   ERROR [main] org.apache.commons.beanutils.PropertyUtils     - Method invocation failed.
java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:1773)
    at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:1759)
    at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1648)
    at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:1677)
    at org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:1022)
    at org.apache.commons.beanutils.BeanUtils.setProperty(BeanUtils.java:313)
    at com.voice.Test.Dao2.transforMapListToBeanList(Dao2.java:111)
    at com.voice.Test.Dao2.getForList(Unknown Source)
    at com.voice.Test.TestAllTest.test(TestAllTest.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

好吧,先附上代码:

import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

/**
 * java类的属性
 * 1)在javaEE中,java的类的属性通过getter,setter来定义:get(或者set)方法,去除get(或者set)后,后字母小写即为java类的属性;以前那个那个属性叫做成员变量
 * 操作java类的属性有一个工具包:beanutils   a.setProperty  b.getProperty
 * 
 * dao:data access object
 * why:实现功能模块化,有利于代码维护和升级
 * what:访问信息的类,包含了CRUD(creat read update  delete);DAO可以被子类继承或者直接使用
 * how:适用jdbc编写 DAO 可能会包含的方法
 *insert update deleted都可以通过以下
 *void update(Strig sql ,Object...args)
 *
 *查询一条纪录:
 *<T> T get(Class<T>clazz,String sql,Object...args)
 *
 *查询多条数据
 *<T> List<T> getForList(Class<t>clazz,String sql,Object...args)
 *
 *返回某个字段都值或者是统计的值(一共有多少条纪录)
 *<E> E getForValue(String sql,Object...args)
 */
public class Dao2 {

	
	public void update(String sql,Object...args) throws Exception{
		Connection con = null;
		PreparedStatement p = null;
		ResultSet r = null;
		try {
			con = JdbcTools.getConnection();
			p = con.prepareStatement(sql);
			for(int i=0;i<args.length;i++){
				p.setObject(i+1, args[i]);
			}
			p.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			JdbcTools.releaseDB(r, p, con);
		}
	}
	 //查询一条纪录:
	public <T> T get(Class<T>clazz,String sql,Object...args) throws Exception{
		List<T> result = getForList(clazz, sql, args);
		if(result.size()>0){
			return result.get(0);
		} 
		return null;
	 }
	 
	 //查询多条数据
	public <T> List<T> getForList(Class<T>clazz,String sql,Object...args) throws Exception{
		List<T> list = new ArrayList<>();	
		Connection con = null;
		PreparedStatement p = null;
		ResultSet r = null;
		try {
			//1. 得到结果集
			con = JdbcTools.getConnection();
			p = con.prepareStatement(sql);
			for(int i=0;i<args.length;i++){
				p.setObject(i+1, args[i]);
			}
			r = p.executeQuery();
			//1. 处理结果集得到 map对应的list,其中一个map对象就是一条纪录,key是字段名
			List<Map<String, Object>> values = handelResultSetToMapList(r);
			//1. 把map的list转为clazz对应的list,map的key是clazz的propertyName,而map的value是clazz对应的对象的value
			list = transforMapListToBeanList(clazz, values);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			JdbcTools.releaseDB(r, p, con);
		}
		
		 return list;
	 }
	private <T> List<T> transforMapListToBeanList(Class<T> clazz, List<Map<String, Object>> values)
			throws InstantiationException, IllegalAccessException, InvocationTargetException {
		List<T> result = new ArrayList<>();
		T bean = null;
		if(values.size()>0){
			for(Map<String,Object> entry:values){
				bean = clazz.newInstance();
				for(Map.Entry<String, Object> entry1:entry.entrySet()){
					String propertyName = entry1.getKey();
					Object propertyValue = entry1.getValue();
					if("addTime".equals(propertyName)){
						SimpleDateFormat format = new SimpleDateFormat("yyyy-M-dd HH:mm:ss"); 
				        try {
				        	propertyValue =format.parse(propertyValue+"");
						} catch (ParseException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}
					BeanUtils.setProperty(bean, propertyName, propertyValue);
				}
				//把object对象放入
				result.add(bean);
			}
		}
		return result;
	}
	/**
	 *处理结果集,得到Map的一个List其中,一个map对象对应一条纪录
	 */
	private List<Map<String, Object>> handelResultSetToMapList(ResultSet r) throws Exception, SQLException {
		List<Map<String,Object>> values = new ArrayList<>();
		List<String> lable = getCloumLable(r);
		//7.处理resultset ,使用while
		while(r.next()){
			Map<String,Object> map = new HashMap<String,Object>();
			//11.填充的map对象放入5准备的List中
			for(String name:lable){
				Object obj = r.getObject(name);
				map.put(name, obj);					
			}
			values.add(map);
		}
		return values;
	}
	 //返回某个字段都值或者是统计的值(一共有多少条纪录)
	public <E> E getForValue(String sql,Object...args) throws Exception{
		//得到结果集,该结果集只有一行且只有一列
		Connection con = null;
		PreparedStatement p = null;
		ResultSet r = null;      
		try {
			con = JdbcTools.getConnection();
			p = con.prepareStatement(sql);
			for(int i=0;i<args.length;i++){
				p.setObject(i+1, args[i]);
			}
			r = p.executeQuery();
			//取得结果集
			if(r.next()){
				return (E) r.getObject(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			JdbcTools.releaseDB(r, p, con);
		}
		
	
		 return null;
	 }
	
	/**
	 *获取结果集的ColumLable 对应的list(得到数据库字段名) 
	 */
	 public List<String> getCloumLable(ResultSet rs) throws Exception{
		 List<String> list = new ArrayList<>();
		 ResultSetMetaData  a = rs.getMetaData();
		 for(int i=0;i<a.getColumnCount();i++){
			 String name = a.getColumnLabel(i+1);
			 list.add(name);
		 }
		 return list;
	 }
}

 

很奇怪?难道都不行么?所有的转换都不行,还是只是时间不行?(看到代码标红处,好像不显示颜色,就是 transforMapListToBeanList方法那里!有个日期转换的!)我Debug的时候发现Date类型的属性时,类型是TimeStamp.这个到现在还不是为啥,普通的Date类型,Debug的时候类型是Date,,百度了一下,说就是有Date的时候会出现这个问题。好吧,直接处理掉就可以了,(看到代码标红处)。

以上是关于BeanUtils Date的主要内容,如果未能解决你的问题,请参考以下文章

BeanUtils.copyProperties方法,当属性Date为null解决

使用BeanUtils设置属性转换String到Date类型

求教一个java中BeanUtils转换器的问题

bootspring???????????????Date??????????????????????????????????????????????????????????????????(代码片段

带有神秘附加字符的 Javascript Date getTime() 代码片段

BeanUtils解决日期问题