一、元数据
元数据:数据库、表、列的定义信息
1、DataBaseMetaData对象
getURL():返回一个String类对象,代表数据库的URL。
getUserName():返回连接当前数据库管理系统的用户名。
getDatabaseProductName():返回数据库的产品名称。
getDatabaseProductVersion():返回数据库的版本号。
getDriverName():返回驱动驱动程序的名称。
getDriverVersion():返回驱动程序的版本号。
isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
1 /**
2 * 获取数据库的元数据
3 * @throws SQLException
4 */
5 @Test
6 public void test1() throws SQLException{
7 Connection con = JdbcUtils_DBCP.getConnection();
8
9 //获取数据库的元数据
10 DatabaseMetaData meta = con.getMetaData();
11 //获取数据库的版本
12 System.out.println(meta.getDatabaseMajorVersion());
13 //获取数据库的产品名称
14 System.out.println(meta.getDatabaseProductName());
15 //获取数据库默认的隔离级别
16 System.out.println(meta.getDefaultTransactionIsolation());
17
18 /**
19 * 结果:
20 * 5
21 MySQL
22 2
23 *
24 */
25 }
2、 ParameterMetaData对象
PreparedStatement . getParameterMetaData()
获得代表PreparedStatement元数据的ParameterMetaData对象。
Select * from user where name=? And password=?
ParameterMetaData对象
getParameterCount()
获得指定参数的个数
getParameterType(int param)
获得指定参数的sql类型
1 /**
2 * 获取参数元数据
3 * @throws SQLException
4 */
5 @Test
6 public void test2() throws SQLException{
7 Connection con = JdbcUtils_DBCP.getConnection();
8 String sql = "insert into account(name,money) values(?,?)";
9 //预编译sql语句
10 PreparedStatement ps = con.prepareStatement(sql);
11 //获取参数元数据
12 ParameterMetaData meta = ps.getParameterMetaData();
13
14 //获取参数的个数 结果:2
15 System.out.println(meta.getParameterCount());
16
17 //获取参数的类型
18 System.out.println(meta.getParameterType(1));
19 }
20
3、ResultSetMetaData对象
ResultSet. getMetaData()
获得代表ResultSet对象元数据的ResultSetMetaData对象。
ResultSetMetaData对象
getColumnCount()
返回resultset对象的列数
getColumnName(int column)
获得指定列的名称
getColumnTypeName(int column)
获得指定列的类型
1 /*
2 * 获取结果集元数据
3 */
4
5 @Test
6 public void test3() throws SQLException{
7 Connection con = JdbcUtils_DBCP.getConnection();
8 String sql = "select * from account";
9 //预编译sql语句
10 PreparedStatement ps = con.prepareStatement(sql);
11 ResultSet rs = ps.executeQuery();
12
13 //获取元数据
14 ResultSetMetaData meta = rs.getMetaData();
15 System.out.println(meta.getColumnCount());
16 System.out.println(meta.getColumnName(1));
17 System.out.println(meta.getColumnName(2));
18 System.out.println(meta.getColumnName(3));
19
20 //结果:id name money
21 }
二、对JDBC进行优化
1、对增、删、改进行优化
所有实体的CUD操作代码基本相同,仅仅发送给数据库的SQL语句不同而已,因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句。
1 //优化JDBC的增、删、改
2 /**
3 *
4 * @param sql 接受参数
5 * @param params 参数 替换掉sql语句的?号
6 * @throws SQLException
7 */
8 public static void create_delete_update(String sql,Object params[]) throws SQLException{
9 Connection con = null;
10 PreparedStatement st = null;
11 ResultSet result = null;
12
13 try{
14 con = getConnection();
15 st = con.prepareStatement(sql);
16
17 //把sql的?号替换掉
18 for(int i=0;i<params.length;i++){
19
20 //因为不清楚表的列数据是什么类型,所以用Object
21 st.setObject(i+1,params[i]);
22 }
23
24 st.executeUpdate();
25
26 }finally{
27 release(con, st, result);
28 }
29 }
2、对查找进行优化
1 //优化sql查询
2 public static Object query(String sql,Object params[],ResultSetHandler handler) throws SQLException{
3 Connection con = null;
4 PreparedStatement st = null;
5 ResultSet rs = null;
6 try{
7 con = getConnection();
8 st = con.prepareStatement(sql);
9 //替代问号
10 for(int i=0;i<params.length;i++){
11 st.setObject(i+1, params[i]);
12 }
13
14 //执行
15 rs = st.executeQuery();
16
17 //由于不知道调用者怎么处理结果集,所有由调用者调用时传入一个处理器对象,调用处理器对象的处理方法
18 return handler.handler(rs);
19 }finally{
20 release(con, st, rs);
21 }
22 }
23
24 }
25
26
27 //暴露接口
28 interface ResultSetHandler{
29 public Object handler(ResultSet rs);
30 }
31
32 //实现把结果封装到bean里面,适用于查找一条数据
33 class BeanHandler implements ResultSetHandler{
34 Class clazz;
35 public BeanHandler(Class clazz){
36 this.clazz = clazz;
37 }
38
39 //处理方法,把数据封装到javabean
40 public Object handler(ResultSet rs) {
41 try {
42 if(!rs.next()){
43 return null;
44 }
45
46 //创建封装结果的bean对象
47 Object bean = clazz.newInstance();
48
49 //得到结果集数的元数据,已获取结果集的信息
50 ResultSetMetaData meta = rs.getMetaData();
51
52 //得到结果集的列数
53 int count = meta.getColumnCount();
54
55 //for循环赋值给bean对象
56 for(int i=0;i<count;i++){
57 String name = meta.getColumnName(i+1);
58 Object value = rs.getObject(name);
59
60 //反射出bean上与列名相应的属性
61 Field f = bean.getClass().getDeclaredField(name);
62 //由于属性是私有的,要把属性设置成可见的
63 f.setAccessible(true);
64 //设置属性
65 f.set(bean, value);
66 }
67
68 return bean;
69 } catch (Exception e) {
70 throw new RuntimeException(e);
71 }
72 }
73 }
74
75 //把结果封装到一个集合里面去
76 class BeanListHandler implements ResultSetHandler{
77 Class clazz;
78 public BeanListHandler(Class clazz){
79 this.clazz = clazz;
80 }
81
82 public Object handler(ResultSet rs){
83 List list = new ArrayList();
84 try{
85 while(rs.next()){
86 //创建bean对象
87 Object bean = clazz.newInstance();
88 ResultSetMetaData meta = rs.getMetaData();
89
90 //获取列数
91 int count = meta.getColumnCount();
92 for(int i=0;i<count;i++){
93 //列名
94 String name = meta.getColumnName(i+1);
95 Object value = rs.getObject(name);
96 Field f = bean.getClass().getDeclaredField(name);
97 f.setAccessible(true);
98 f.set(bean, value);
99 }
100 list.add(bean);
101 }
102 }catch(Exception e){
103 throw new RuntimeException(e);
104 }
105 return list;
106 }
107 }
3、完整代码
1 package com.utils;
2 import java.io.InputStream;
3 import java.lang.reflect.Field;
4 import java.sql.Connection;
5 import java.sql.DriverManager;
6 import java.sql.PreparedStatement;
7 import java.sql.ResultSet;
8 import java.sql.ResultSetMetaData;
9 import java.sql.SQLException;
10 import java.sql.Statement;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Properties;
14 import javax.sql.DataSource;
15 import org.apache.commons.dbcp.BasicDataSourceFactory;
16
17 public class DButils {
18
19 //数据库连接池
20 private static DataSource ds = null;
21 static{
22 try{
23 //读取配置文件
24 InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
25 Properties prop = new Properties();
26 prop.load(in);
27 BasicDataSourceFactory factory = new BasicDataSourceFactory();
28 //创建连接池
29 ds = factory.createDataSource(prop);
30 }catch(Exception e){
31 throw new ExceptionInInitializerError(e);
32 }
33 }
34
35
36 //获取连接
37 public static Connection getConnection() throws SQLException{
38
39 return ds.getConnection();
40 }
41
42 //释放资源
43 public static void release(Connection con,Statement st,ResultSet result){
44 if(result!=null){
45 try {
46 result.close();
47 } catch (Exception e) {
48 e.printStackTrace();
49 }
50 result = null;
51 }
52
53 if(st!=null){
54 try {
55 st.close();
56 } catch (Exception e) {
57 e.printStackTrace();
58 }
59 st = null;
60 }
61
62 if(con!=null){
63 try {
64 con.close();
65 } catch (Exception e) {
66 e.printStackTrace();
67 }
68
69 }
70 }
71
72
73 //优化JDBC的增、删、改
74 /**
75 *
76 * @param sql 接受参数
77 * @param params 参数 替换掉sql语句的?号
78 * @throws SQLException
79 */
80 public static void create_delete_update(String sql,Object params[]) throws SQLException{
81 Connection con = null;
82 PreparedStatement st = null;
83 ResultSet result = null;
84
85 try{
86 con = getConnection();
87 st = con.prepareStatement(sql);
88
89 //把sql的?号替换掉
90 for(int i=0;i<params.length;i++){
91
92 //因为不清楚表的列数据是什么类型,所以用Object
93 st.setObject(i+1,params[i]);
94 }
95
96 st.executeUpdate();
97
98 }finally{
99 release(con, st, result);
100 }
101 }
102
103
104 //优化sql查询
105 public static Object query(String sql,Object params[],ResultSetHandler handler) throws SQLException{
106 Connection con = null;
107 PreparedStatement st = null;
108 ResultSet rs = null;
109 try{
110 con = getConnection();
111 st = con.prepareStatement(sql);
112 //替代问号
113 for(int i=0;i<params.length;i++){
114 st.setObject(i+1, params[i]);
115 }
116
117 //执行
118 rs = st.executeQuery();
119
120 //由于不知道调用者怎么处理结果集,所有由调用者调用时传入一个处理器对象,调用处理器对象的处理方法
121 return handler.handler(rs);
122 }finally{
123 release(con, st, rs);
124 }
125 }
126
127 }
128
129
130 //暴露接口
131 interface ResultSetHandler{
132 public Object handler(ResultSet rs);
133 }
134
135 //实现把结果封装到bean里面,适用于查找一条数据
136 class BeanHandler implements ResultSetHandler{
137 Class clazz;
138 public BeanHandler(Class clazz){
139 this.clazz = clazz;
140 }
141
142 //处理方法,把数据封装到javabean
143 public Object handler(ResultSet rs) {
144 try {
145 if(!rs.next()){
146 return null;
147 }
148
149 //创建封装结果的bean对象
150 Object bean = clazz.newInstance();
151
152 //得到结果集数的元数据,已获取结果集的信息
153 ResultSetMetaData meta = rs.getMetaData();
154
155 //得到结果集的列数
156 int count = meta.getColumnCount();
157
158 //for循环赋值给bean对象
159 for(int i=0;i<count;i++){
160 String name = meta.getColumnName(i+1);
161 Object value = rs.getObject(name);
162
163 //反射出bean上与列名相应的属性
164 Field f = bean.getClass().getDeclaredField(name);
165 //由于属性是私有的,要把属性设置成可见的
166 f.setAccessible(true);
167 //设置属性
168 f.set(bean, value);
169 }
170
171 return bean;
172 } catch (Exception e) {
173 throw new RuntimeException(e);
174 }
175 }
176 }
177
178 //把结果封装到一个集合里面去
179 class BeanListHandler implements ResultSetHandler{
180 Class clazz;
181 public BeanListHandler(Class clazz){
182 this.clazz = clazz;
183 }
184
185 public Object handler(ResultSet rs){
186 List list = new ArrayList();
187 try{
188 while(rs.next()){
189 //创建bean对象
190 Object bean = clazz.newInstance();
191 ResultSetMetaData meta = rs.getMetaData();
192
193 //获取列数
194 int count = meta.getColumnCount();
195 for(int i=0;i<count;i++){
196 //列名
197 String name = meta.getColumnName(i+1);
198 Object value = rs.getObject(name);
199 Field f = bean.getClass().getDeclaredField(name);
200 f.setAccessible(true);
201 f.set(bean, value);
202 }
203 list.add(bean);
204 }
205 }catch(Exception e){
206 throw new RuntimeException(e);
207 }
208 return list;
209 }
210 }
211
212
213
214
215
测试:
1 package com.utils;
2
3 import java.sql.SQLException;
4 import java.util.Iterator;
5 import java.util.List;
6
7 import org.junit.Test;
8
9 import com.domain.Account;
10
11 public class Demo {
12
13 //测试添加
14 @Test
15 public void testAdd() throws SQLException{
16 Account a = new Account();
17 a.setName("陈海宏");
18 a.setMoney(30);
19 add(a);
20 }
21
22 @Test
23 //测试删除
24 public void testDelete() throws SQLException{
25 delete(1);
26 }
27
28 @Test
29 //测试更改
30 public void testUpdate() throws SQLException{
31 Account a = new Account();
32 a.setId(2);
33 a.setName("王五");
34 a.setMoney(30);
35 update(a);
36 }
37
38 @Test
39 //测试查找单项记录
40 public void testFind() throws SQLException{
41 Account a = find(7);
42 System.out.println(a.getName());
43 }
44
45
46
47
48 //测试查找单记录
49 @Test
50 public void testGetAll() throws SQLException{
51 List list = getAll();
52 //对集合进行迭代
53 Iterator it = list.iterator();
54 while(it.hasNext()){
55 Account a = (Account) it.next();
56 System.out.println(a.getId()+"+"+a.getName()+"+"+a.getMoney());
57
58 }
59 }
60
61
62
63 //添加
64 public void add(Account a) throws SQLException{
65
66 //准备sql语句
67 String sql = "insert into account(name,money) values(?,?)";
68 //替换?的参数数据
69 Object params[] = {a.getName(),a.getMoney()};
70 DButils.create_delete_update(sql, params);
71
72 }
73
74 //删除
75 public void delete(int id) throws SQLException{
76
77 //准备sql语句
78 String sql = "delete from account where id=?";
79 //替换?的参数数据
80 Object params[] = {id};
81 DButils.create_delete_update(sql, params);
82 }
83
84 //更新
85 public void update(Account a) throws SQLException{
86 String sql = "update account set name = ?,money = ? where id=?";
87 Object params[] = {a.getName(),a.getMoney(),a.getId()};
88 DButils.create_delete_update(sql, params);
89 }
90
91 //查找单项记录
92 public Account find(int i) throws SQLException{
93 String sql = "select * from account where id=?";
94 Object params[] = {i};
95 return (Account) DButils.query(sql, params,new BeanHandler(Account.class));
96 }
97
98 //查找所有记录
99 public List getAll() throws SQLException{
100 String sql = "select * from account";
101 Object params[] = {};
102 return (List) DButils.query(sql, params,new BeanListHandler(Account.class));
103 }
104 }