使用的是MySQL數據庫,首先導入驅動類,然后根據數據庫URL和用戶名密碼獲得數據的鏈接。由于使用的是MySQL數據庫,它的URL一般為,jdbc:mysql://主機地址:端口號/庫名。
下面是封裝的具體類,用到了泛型和反射,不過還存在些問題,就是對使用的泛型對象有些限制,只能用于泛型類對象屬性名與數據庫表中列名相同的對象,而且初始化對象的方法必須為set+屬性名的方法。本來想通過返回值類型,參數列表來確定該屬性初始化方法的,然而可能是目前學到的還是太少,只學了三周,所以并沒有實現,感覺這個方法還是很low,以后還要繼續完善。本來看到網上有用beanUtils包,利用map將查詢的一列存起來,直接轉化成該對象的,但是就是想試試新學到的反射。而且最后的垃圾回收器并不能如同C++的析構函數一樣,所以關閉數據庫鏈接的地方也需要改善。
實現代碼:
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
public class Consql { private static Consql consql= null ;//單例設計模式 private Connection conn= null ;//數據庫鏈接 private final String url;//數據庫url private final String username;//數據庫用戶名 private final String password ;//數據庫密碼 //驅動類的加載 static {//以靜態代碼塊的形式加載驅動類,靜態代碼塊只在類加載的時候執行一次 try { Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } //構造函數 private Consql(String url,String username,String password ) throws SQLException{ this.url = url; this.username = username; this. password = password ; open ();//創建連接 } private Connection open () throws SQLException { try {//驅動器獲取數據庫鏈接 conn=DriverManager.getConnection(url, username, password ); } catch (SQLException e) { // TODO Auto-generated catch block //e.printStackTrace(); throw e; } return conn; } /** * 帶限制條件查找 * @param sql 帶占位符?的sql語句 * @param t 返回相關類型對象的類(T.class) * @param params 替換占位符的數據,為動態數組 * @ return ArrayList<T> * @throws SQLException */ public <T> ArrayList<T> select (String sql,Class<T> t,Object...params) throws SQLException {//獲取T類所有 public 方法 Method[] declaredMethods = t.getDeclaredMethods(); //創建一個盛放該類型對象集合 ArrayList<T> arrayList=new ArrayList<>(); try (PreparedStatement pStatement=conn.prepareStatement(sql);) { for ( int i=0;i<params.length;i++) { pStatement.setObject(i+1, params[i]); } try(ResultSet rSet=pStatement.executeQuery();) { ResultSetMetaData rData=rSet.getMetaData(); //獲取查詢到結果表的列數 int columnCount = rData.getColumnCount(); while (rSet. next ()) { T a=t.newInstance();//創建泛型類實例 for ( int i=0;i<columnCount;i++) {//獲得方數組里的 set 方法,這里造成了局限性,只能數據庫表列名與對象名一致,且只能是 set 方法 String aString= "set" +rData.getColumnName(i+1); for (Method method : declaredMethods) { if(method.getParameterCount()==1&&method.getReturnType().toString().equals( "void" )&&method.getName().equalsIgnoreCase(aString)) {//這里存在問題,前兩個判斷條件基本沒用,主要是最初不想用上面拼串的方式來判斷是不是調用該參數的方法 method.setAccessible( true ); //利用反射調用該方法 method.invoke(a, rSet.getObject(i+1)); break; } } } arrayList. add (a); } } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException 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(); } } catch (SQLException e) { // TODO Auto-generated catch block throw e; } return arrayList; } /** * 數據插入 * @param sql 帶占位符?的sql語句 * @param params 替換占位符的數據,動態數組 * @throws SQLException */ public void insert (String sql,Object...params) throws SQLException { try(PreparedStatement pStatement=conn.prepareStatement(sql);) { for ( int i=0;i<params.length;i++) { pStatement.setObject(i+1, params[i]); } pStatement.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block throw e; } } /** * 數據更新 * @param sql 帶占位符?的sql語句 * @param params 替換占位符的數據,動態數組 * @throws SQLException */ public void update (String sql,Object...params) throws SQLException { try(PreparedStatement pStatement=conn.prepareStatement(sql);) { for ( int i=0;i<params.length;i++) { pStatement.setObject(i+1, params[i]); } pStatement.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block throw e; } } /** * 帶限制條件刪除 * @param sql 帶占位符?的sql語句 * @param params 替換占位符的數據,動態數組 * @throws SQLException */ public void delete (String sql,Object...params) throws SQLException { try(PreparedStatement pStatement=conn.prepareStatement(sql);) { for ( int i=0;i<params.length;i++) { pStatement.setObject(i+1, params[i]); } pStatement.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block throw e; } } /** * 刪除全部,不帶有限制 * @param sql * @throws SQLException */ public void deleteall(String sql) throws SQLException { try(PreparedStatement pStatement=conn.prepareStatement(sql);) { pStatement.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block throw e; } } /** * 無限制條件查找 * @param sql * @param t 泛型類T.class * @ return ArrayList<T> * @throws SQLException */ public <T> ArrayList<T> select (String sql,Class<T> t) throws SQLException { Method[] declaredMethods = t.getDeclaredMethods(); ArrayList<T> arrayList=new ArrayList<>(); try (PreparedStatement pStatement=conn.prepareStatement(sql);) { try(ResultSet rSet=pStatement.executeQuery();) { ResultSetMetaData rData=rSet.getMetaData(); int columnCount = rData.getColumnCount(); while (rSet. next ()) { T a=t.newInstance(); for ( int i=0;i<columnCount;i++) { String aString= "set" +rData.getColumnName(i+1); for (Method method : declaredMethods) { if(method.getName().equalsIgnoreCase(aString)) { method.setAccessible( true ); method.invoke(a, rSet.getObject(i+1)); break; } } } arrayList. add (a); } } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException 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(); } } catch (SQLException e) { // TODO Auto-generated catch block throw e; } return arrayList; } /** * 返回表中數據行數 * @param tableName 數據庫表名 * @ return 行數 * @throws SQLException */ public int count (String tableName) throws SQLException { String sql= "select count(*) from " +tableName; try(PreparedStatement pStatement=conn.prepareStatement(sql); ResultSet rsSet=pStatement.executeQuery(); ) { if(rsSet. next ()) { return rsSet.getInt(1); } } catch (SQLException e) { // TODO Auto-generated catch block throw e; } return 0; } /** * 判斷數據是否存在 * @param sql 帶占位符?的sql語句 * @param params 替換占位符的數據,動態數組 * @ return boolean * @throws SQLException */ public boolean isExist(String sql,Object...params) throws SQLException { try(PreparedStatement pStatement=conn.prepareStatement(sql);) { for ( int i=0;i<params.length;i++) { pStatement.setObject(i+1, params[i]); } try(ResultSet rsSet=pStatement.executeQuery();) { if(rsSet. next ()) { return true ; } } finally { } } catch (SQLException e) { // TODO Auto-generated catch block throw e; } return false ; } /** * 創建實例 * @param url 數據庫url * @param username 用戶名 * @param password 密碼 * @ return consql對象 * @throws SQLException */ public static Consql getnewInstance(String url,String username,String password ) throws SQLException { if(consql== null ) consql=new Consql(url, username, password ); return consql; } //垃圾回收,貌似并不能達到析構函數的效果 protected void finalize() throws Throwable { if(conn!= null ) { conn. close (); } super.finalize(); } } |
以上就是詳解JDBC數據庫鏈接及相關方法的封裝的實例詳解,如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
原文鏈接:http://www.cnblogs.com/PersistWp/p/7398111.html