先贴代码:
1 package com.hongli.util;
2 import java.lang.reflect.Field;
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.PreparedStatement;
6 import java.sql.ResultSet;
7 import java.sql.ResultSetMetaData;
8 import java.sql.SQLException;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 public class DBconn {
14
15 public class JdbcUtils {
16 //数据库用户名
17 private static final String USERNAME = "root";
18 //数据库密码
19 private static final String PASSWORD = "yanzi";
20 //驱动信息
21 private static final String DRIVER = "com.mysql.jdbc.Driver";
22 //数据库地址
23 private static final String URL = "jdbc:mysql://localhost:3306/mydb";
24 private Connection connection;
25 private PreparedStatement pstmt;
26 private ResultSet resultSet;
27 public JdbcUtils() {
28 // TODO Auto-generated constructor stub
29 try{
30 Class.forName(DRIVER);
31 System.out.println("数据库连接成功!");
32
33 }catch(Exception e){
34
35 }
36 }
37
38 /**
39 * 获得数据库的连接
40 * @return
41 */
42 public Connection getConnection(){
43 try {
44 connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
45 } catch (SQLException e) {
46 // TODO Auto-generated catch block
47 e.printStackTrace();
48 }
49 return connection;
50 }
51
52
53 /**
54 * 增加、删除、改
55 * @param sql
56 * @param params
57 * @return
58 * @throws SQLException
59 */
60 public boolean updateByPreparedStatement(String sql, List<Object>params)throws SQLException{
61 boolean flag = false;
62 int result = -1;
63 pstmt = connection.prepareStatement(sql);
64 int index = 1;
65 if(params != null && !params.isEmpty()){
66 for(int i=0; i<params.size(); i++){
67 pstmt.setObject(index++, params.get(i));
68 }
69 }
70 result = pstmt.executeUpdate();
71 flag = result > 0 ? true : false;
72 return flag;
73 }
74
75 /**
76 * 查询单条记录
77 * @param sql
78 * @param params
79 * @return
80 * @throws SQLException
81 */
82 public Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException{
83 Map<String, Object> map = new HashMap<String, Object>();
84 int index = 1;
85 pstmt = connection.prepareStatement(sql);
86 if(params != null && !params.isEmpty()){
87 for(int i=0; i<params.size(); i++){
88 pstmt.setObject(index++, params.get(i));
89 }
90 }
91 resultSet = pstmt.executeQuery();//返回查询结果
92 ResultSetMetaData metaData = resultSet.getMetaData();
93 int col_len = metaData.getColumnCount();
94 while(resultSet.next()){
95 for(int i=0; i<col_len; i++ ){
96 String cols_name = metaData.getColumnName(i+1);
97 Object cols_value = resultSet.getObject(cols_name);
98 if(cols_value == null){
99 cols_value = "";
100 }
101 map.put(cols_name, cols_value);
102 }
103 }
104 return map;
105 }
106
107 /**查询多条记录
108 * @param sql
109 * @param params
110 * @return
111 * @throws SQLException
112 */
113 public List<Map<String, Object>> findModeResult(String sql, List<Object> params) throws SQLException{
114 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
115 int index = 1;
116 pstmt = connection.prepareStatement(sql);
117 if(params != null && !params.isEmpty()){
118 for(int i = 0; i<params.size(); i++){
119 pstmt.setObject(index++, params.get(i));
120 }
121 }
122 resultSet = pstmt.executeQuery();
123 ResultSetMetaData metaData = resultSet.getMetaData();
124 int cols_len = metaData.getColumnCount();
125 while(resultSet.next()){
126 Map<String, Object> map = new HashMap<String, Object>();
127 for(int i=0; i<cols_len; i++){
128 String cols_name = metaData.getColumnName(i+1);
129 Object cols_value = resultSet.getObject(cols_name);
130 if(cols_value == null){
131 cols_value = "";
132 }
133 map.put(cols_name, cols_value);
134 }
135 list.add(map);
136 }
137
138 return list;
139 }
140
141 /**通过反射机制查询单条记录
142 * @param sql
143 * @param params
144 * @param cls
145 * @return
146 * @throws Exception
147 */
148 public <T> T findSimpleRefResult(String sql, List<Object> params,
149 Class<T> cls )throws Exception{
150 T resultObject = null;
151 int index = 1;
152 pstmt = connection.prepareStatement(sql);
153 if(params != null && !params.isEmpty()){
154 for(int i = 0; i<params.size(); i++){
155 pstmt.setObject(index++, params.get(i));
156 }
157 }
158 resultSet = pstmt.executeQuery();
159 ResultSetMetaData metaData = resultSet.getMetaData();
160 int cols_len = metaData.getColumnCount();
161 while(resultSet.next()){
162 //通过反射机制创建一个实例
163 resultObject = cls.newInstance();
164 for(int i = 0; i<cols_len; i++){
165 String cols_name = metaData.getColumnName(i+1);
166 Object cols_value = resultSet.getObject(cols_name);
167 if(cols_value == null){
168 cols_value = "";
169 }
170 Field field = cls.getDeclaredField(cols_name);
171 field.setAccessible(true); //打开javabean的访问权限
172 field.set(resultObject, cols_value);
173 }
174 }
175 return resultObject;
176
177 }
178
179 /**通过反射机制查询多条记录
180 * @param sql
181 * @param params
182 * @param cls
183 * @return
184 * @throws Exception
185 */
186 public <T> List<T> findMoreRefResult(String sql, List<Object> params,
187 Class<T> cls )throws Exception {
188 List<T> list = new ArrayList<T>();
189 int index = 1;
190 pstmt = connection.prepareStatement(sql);
191 if(params != null && !params.isEmpty()){
192 for(int i = 0; i<params.size(); i++){
193 pstmt.setObject(index++, params.get(i));
194 }
195 }
196 resultSet = pstmt.executeQuery();
197 ResultSetMetaData metaData = resultSet.getMetaData();
198 int cols_len = metaData.getColumnCount();
199 while(resultSet.next()){
200 //通过反射机制创建一个实例
201 T resultObject = cls.newInstance();
202 for(int i = 0; i<cols_len; i++){
203 String cols_name = metaData.getColumnName(i+1);
204 Object cols_value = resultSet.getObject(cols_name);
205 if(cols_value == null){
206 cols_value = "";
207 }
208 Field field = cls.getDeclaredField(cols_name);
209 field.setAccessible(true); //打开javabean的访问权限
210 field.set(resultObject, cols_value);
211 }
212 list.add(resultObject);
213 }
214 return list;
215 }
216
217 /**
218 * 释放数据库连接
219 */
220 public void releaseConn(){
221 if(resultSet != null){
222 try{
223 resultSet.close();
224 }catch(SQLException e){
225 e.printStackTrace();
226 }
227 }
228 }
229
230 }
231
232 }一、小结:
1、public Connection getConnection() 获得数据库的连接
2、public boolean updateByPreparedStatement(String sql, List<Object>params)throws SQLException 更新数据库,包括增加记录、删除记录、改动某个记录三个功能。
3、public Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException 查询单条记录,传进去的是一个List<Object>参数填充占位符,返回的是一个Map<String, Object>.一个Map对应一条完整的记录,String对应属性名,Object是属性值。
4、public List<Map<String, Object>> findModeResult(String sql, List<Object> params) throws SQLException 查询多条记录,放在List里。
5、public <T> T findSimpleRefResult(String sql, List<Object> params,
Class<T> cls )throws Exception 利用反射查询单个记录。
6、 public <T> List<T> findMoreRefResult(String sql, List<Object> params,
Class<T> cls )throws Exception 利用反射查询多个记录。
二、操作数据库的一般性步骤如下:
(1)连接数据库,加载驱动: Class.forName(DRIVER); DRIVER = "com.mysql.jdbc.Driver";这本身就是反射!!
(2) 利用用户名和密码及数据库的名字连接,这一步才是真正的连接:
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
其中:String URL = "jdbc:mysql://localhost:3306/mydb";
(3)编写一个sql语句,其中的参数用?来代替,然后将参数写到List里。
执行:pstmt = connection.prepareStatement(sql); 然后将参数从list里取出来填充到pstmt里。
(4)如果是增、删、改执行:result = pstmt.executeUpdate(); 其中的result是执行完影响的数据库里的行数,也即几条记录。
如果是查询执行:resultSet = pstmt.executeQuery(); 返回的类型是ResultSet类型。
之后就是把resultSet 弄成Map或List<Map>传递出去,给查询者看。
三、关于查询操作,在得到resultSet后利用getMetaData得到表的结构信息,如:
(1)getColumnCount()得到有多少个列。
(2)String cols_name = metaData.getColumnName(i+1); 得到每个列的属性名称,如是id、username还是pswd.然后从Object cols_value = resultSet.getObject(cols_name);取出来,放到Map或List<Map>里。
四.关于查询里利用的反射操作,步骤如下:
(1) T resultObject = cls.newInstance(); 利用class文件的newInstance()方法创建一个实例。
(2)在通过getColumnCount()得到有多少个列之后,进入循环,
String cols_name = metaData.getColumnName(i+1);
Object cols_value = resultSet.getObject(cols_name);
读取每一列的属性名字和放的值。通过属性的名字cols_name进行反射:Field field = cls.getDeclaredField(cols_name);这样就得到了Field 等于类里的成员变量,field.setAccessible(true); //打开javabean的访问权限 在利用set方法将从数据库中查出来的cols_value通过JavaBean 也即定义的UserInfo这个类的 set方法赋进去。field.set(resultObject, cols_value);
五.一般意义上,要利用Java的反射需要以下步骤
(1)加载Class对象,这个一般有两种方式:Class cls1 = UserInfo.class 或
········Class cls2 = Class.forName("domain.UserInfo") 后者是利用包名+类名的方法。
(2)反射出来Class之后干啥事呢?一个类不外乎构造函数、成员变量、成员函数。所以得到Class之后就可以干这三件事。
···A、关于构造函数,获得Constructor 有四种方法:
·········· Constructor getConstructor(Class[] params)
············Constructor[] getConstructors()
············Constructor getDeclaredConstructor(Class[] params)
··········Constructor[] getDeclaredConstructors()
这四个函数,如果不传参数则是获得所有的构造函数,得到的是一个集合。
如果传特定的参数,则是寻找这个特定的构造函数,不带Declared是获得公共的public,带了Declared是可以获得私有构造函数。
得到构造函数后就可以利用反射创建实例了:
Constructor con1[] = cls1.getDeclaredConstructors();
con1[1].setAccessible(true);
Object obj1 = con1[1].newInstance(new Object[]{"tom"}); 如果直接调用clcs.newInstance()则是用默认的构造函数创建实例。
B、关于成员变量,同样有四种方法:
public Field getDeclaredField(String name) 获取任意指定名字的成员
public Field[] getDeclaredFields() 获取所有的成员变量
public Field getField(String name) 获取任意public成员变量
public Field[] getFields() 获取所有的public成员变量
本文封装的JdbcUtils类就是利用这种方式操作类里的私有成员变量,记得要setAccessible打开开关。如下:
Field field = cls.getDeclaredField(cols_name);
field.setAccessible(true); //打开javabean的访问权限
field.set(resultObject, cols_value);
C、关于成员函数,也有四种方法:
public Method[] getMethods() 获取所有的共有方法的集合
public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 ,
参数1:方法名 参数2:参数类型集合
public Method[] getDeclaredMethods() 获取所有的方法
public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法
下面是利用文中的UserInfo这个类写的一个完成的反射例子,拿到setUsername(String username)方法,然后反射。再拿到getUsername()方法再反射,然后打印出结果:
Class clcs = UserInfo.class;
try {
Object obj = clcs.newInstance();
Method f = clcs.getDeclaredMethod("setUsername", String.class);
f.invoke(obj, "yan123");
Method f2 = clcs.getDeclaredMethod("getUsername", null);
Object name = f2.invoke(obj, null);
System.out.println("反射得到的名字 = " + name); } catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}在反射方法的时候,Method f = clcs.getDeclaredMethod("setUsername", String.class);
原函数里的输入参数是什么类型,就写什么类型.class. 如原来的setXXX需要输入参数String,反射的时候就写String.class.
六. JavaBean是反射的一种,反射对构造函数之类的没任何要求,JavaBean要求这个类必须继承Serializable即可串行化,另外构造函数必须为public.
另外,就是JavaBean在得到某个field后可以直接调用set和get,而不必再反射得到method后再执行。
最后,反射是在程序运行的时候而非编译时!!!
















