在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)
好吧,先附上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
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的时候会出现这个问题。好吧,直接处理掉就可以了,(看到代码标红处)。