一、元数据
元数据:数据库、表、列的定义信息
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 }