1 自定义JDBC的框架
1.1 UserDao的CRUD的编写已经总结出规律
// 进行增删改查
// 增
public void insert(User user) throws SQLException {
Connection conn = ConnectionUtil.getConnection();
String sql = "insert into user(username,psw) values(?,?)";
PreparedStatement psmt = conn.prepareStatement(sql);
psmt.setString(1, user.getUserName());
psmt.setString(2, user.getPassword());
psmt.executeUpdate();
ConnectionUtil.close(conn, psmt, null);
}
// 删除
public void delete(int id) throws SQLException {
Connection conn = ConnectionUtil.getConnection();
String sql = "delete from user where id=?";
PreparedStatement psmt = conn.prepareStatement(sql);
psmt.setInt(1, id);
psmt.executeUpdate();
ConnectionUtil.close(conn, psmt, null);
}
// 总结增删改:
// 一样地方获取连接,释放资源,获得PreparedStatement,执行executeUpdate
// 不一样的地方,sql语句不一样,设置参数也不一样
// 更新
public void update(int id, String name) throws SQLException {
Connection conn = ConnectionUtil.getConnection();
String sql = "update user set username=? where id=?";
PreparedStatement psmt = conn.prepareStatement(sql);
psmt.setString(1, name);
psmt.setInt(2, id);
psmt.executeUpdate();
ConnectionUtil.close(conn, psmt, null);
}
// 总结查询单个:一样地方获取连接,释放资源,获得PreparedStatement,executeQuery
// 不一样的地方,sql语句不一样,设置参数也不一样,返回值不一样
// 查询
public User query(int id) throws SQLException {
Connection conn = ConnectionUtil.getConnection();
String sql = "select * from user where id=?";
PreparedStatement psmt = conn.prepareStatement(sql);
psmt.setInt(1, id);
ResultSet rs = psmt.executeQuery();
User user = new User();
if (rs.next()) {
String username = rs.getString(2);
String psw = rs.getString(3);
user.setId(id);
user.setUserName(username);
user.setPassword(psw);
}
ConnectionUtil.close(conn, psmt, rs);
return user;
}
// 总结查询列表:一样地方获取连接,释放资源,获得PreparedStatement,executeQuery
// 不一样的地方,sql语句不一样,设置参数也不一样,返回值列表不一样
// 查询
public List<User> getAllUser() throws SQLException {
Connection conn = ConnectionUtil.getConnection();
String sql = "select * from user";
PreparedStatement psmt = conn.prepareStatement(sql);
ResultSet rs = psmt.executeQuery();
List<User> users=new ArrayList<User>();
while (rs.next()) {
User user = new User();
String username = rs.getString(2);
String psw = rs.getString(3);
user.setId(rs.getInt(1));
user.setUserName(username);
user.setPassword(psw);
users.add(user);
}
ConnectionUtil.close(conn, psmt, rs);
return users;
}
1.2 总结增删改
1.2.1 一样地方获取连接,释放资源,获得PreparedStatement,执行executeUpdate
1.2.2 不一样的地方,sql语句不一样,设置参数也不一样
1.3 总结查询单个
1.3.1 一样地方获取连接,释放资源,获得PreparedStatement,executeQuery
1.3.2 不一样的地方,sql语句不一样,设置参数也不一样,返回值不一样
1.4 总结查询列表
1.4.1 一样地方获取连接,释放资源,获得PreparedStatement,executeQuery
1.4.2 不一样的地方,sql语句不一样,设置参数也不一样,返回值列表不一样
1.5 元数据的学习
* DataBaseMetaData
@Test
public void test1() throws Exception {
//DatabaseMetaData
Connection conn = ConnectionUtils.getConnection();
DatabaseMetaData metaData = conn.getMetaData();
String productName=metaData.getDatabaseProductName();
String productVersion=metaData.getDatabaseProductVersion();
String driverName=metaData.getDriverName();
String driverVersion=metaData.getDriverVersion();
String url=metaData.getURL();
String username=metaData.getUserName();
System.out.println(productName);
System.out.println(productVersion);
System.out.println(driverName);
System.out.println(driverVersion);
System.out.println(url);
System.out.println(username);
ConnectionUtils.close(conn, null);
}
* ParameterMetaData
/ 测试元数据(ParameterMetaData)
@Test
public void test16() throws SQLException {
Connection conn = ConnectionUtil.getConnection();
// 1 获得ParameterMetaData
String sql="select * from user where id=?";
PreparedStatement psmt = conn.prepareStatement(sql);
psmt.setInt(1, 5);
ParameterMetaData parameterMetaData = psmt.getParameterMetaData();
int parameterCount = parameterMetaData.getParameterCount();
System.out.println(parameterCount);
// 这个Mysql驱动不支持
//java.sql.SQLException: Parameter metadata not available for the given statement
// int parameterType = parameterMetaData.getParameterType(1);
// String parameterClassName = parameterMetaData.getParameterClassName(1);
// String parameterTypeName = parameterMetaData.getParameterTypeName(1);
// System.out.println(parameterType);
// System.out.println(parameterClassName);
// System.out.println(parameterTypeName);
ConnectionUtil.close(conn, psmt, null);
}
#将db.properties文件放在任意资源管理文件夹下,程序编译的时候会自动放入项目的类路径下(classpath),方便查找
#key=value格式编写 不要多余的符号
#oracle
#driver=oracle.jdbc.OracleDriver
#url=jdbc:oracle:thin:@127.0.0.1:1521:xe
#username=scott
#pwd=tiger
#mysql
#早期的数据库版本需要指定设置发送连接数据时候的编码
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/etc0102?useUnicode=true&characterEncoding=utf-8&generateSimpleParameterMetadata=true
username=root
pwd=root
* ResultSetMetaData
// 测试元数据(ResultSetMetaData)
@Test
public void test17() throws SQLException {
Connection conn = ConnectionUtil.getConnection();
// 1 获得ParameterMetaData
String sql="select * from user where id=?";
PreparedStatement psmt = conn.prepareStatement(sql);
psmt.setInt(1, 3);
ResultSet rs = psmt.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
System.out.println("columnCount:"+columnCount);
for(int i=0;i<columnCount;i++) {
String columnName = metaData.getColumnName(i+1);
String columnTypeName = metaData.getColumnTypeName(i+1);
System.out.println("columnName:"+columnName);
System.out.println("columnTypeName:"+columnTypeName);
}
ConnectionUtil.close(conn, psmt, null);
}
1.6 封装JDBC框架
* JdbcUtils
* public static void update(String sql,Object[] params)
* public static Object query(String sql,Object[] params,ResultSetHandler rsh)
* 定义ResultSetHandler接口
* public Object handler(ResultSet rs)
* BeanResultSetHandler
* ListResultSetHandler(作业)
* Map....
// CUD:封装
public static void update(String sql, Object[] params) {
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = ConnectionUtil.getConnection();
stmt = conn.prepareStatement(sql);
ParameterMetaData parameterMetaData = stmt.getParameterMetaData();
int paramCount = parameterMetaData.getParameterCount();
if (params != null && paramCount != params.length) {
throw new IllegalAnnotationException("参数的个数不对");
}
for (int i = 0; i < paramCount; i++) {
stmt.setObject(i + 1, params[i]);
}
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
ConnectionUtil.close(conn, stmt, null);
}
}
// 进行增删改查
// 增
public void insert(User user) throws SQLException {
String sql = "insert into user(username,psw) values(?,?)";
Object[] params = { user.getUsername(), user.getPsw() };
JdbcUtils.update(sql, params);
}
// 删除
public void delete(int id) throws SQLException {
String sql = "delete from user where id=?";
Object[] params = { id };
JdbcUtils.update(sql, params);
}
// 总结增删改:
// 一样地方获取连接,释放资源,获得PreparedStatement,执行executeUpdate
// 不一样的地方,sql语句不一样,设置参数也不一样
// 更新
public void update(int id, String name) throws SQLException {
String sql = "update user set username=? where id=?";
Object[] params = { name, id };
JdbcUtils.update(sql, params);
}
// Q:查询
public static Object query(String sql, Object[] params, ResultSetHandler rsh) {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs=null;
try {
conn = ConnectionUtil.getConnection();
stmt = conn.prepareStatement(sql);
ParameterMetaData parameterMetaData = stmt.getParameterMetaData();
int paramCount = parameterMetaData.getParameterCount();
if (params != null && paramCount != params.length) {
throw new IllegalAnnotationException("参数的个数不对");
}
for (int i = 0; i < paramCount; i++) {
stmt.setObject(i + 1, params[i]);
}
rs = stmt.executeQuery();
return rsh.handler(rs);
} catch (Exception e) {
e.printStackTrace();
} finally {
ConnectionUtil.close(conn, stmt, rs);
}
return null;
}
import java.sql.ResultSet;
public interface ResultSetHandler {
public Object handler(ResultSet rs);
}
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
// BeanResultSetHandler
public class BeanResultSetHandler implements ResultSetHandler {
Class<?> clss;
public BeanResultSetHandler(Class<?> clss) {
this.clss = clss;
}
@Override
public Object handler(ResultSet rs) {
try {
if (!rs.next()) {
return null;
}
ResultSetMetaData metaData = rs.getMetaData();
Object obj = clss.newInstance();
// 获得由多少列
int columnCount = metaData.getColumnCount();
for (int i = 0; i < columnCount; i++) {
// 获得列的名字
String columnName = metaData.getColumnName(i+1);
// 获得值
Object value = rs.getObject(columnName);
Field field = clss.getDeclaredField(columnName);
// 暴力反射打开私有
field.setAccessible(true);
field.set(obj, value);
}
return obj;
} catch (Exception e) {
e.printStackTrace();
} finally {
ConnectionUtil.close(null, null, rs);
}
return null;
}
}
备注:
* http://www.cnblogs.com/xdp-gacl/p/4006830.html
2 使用ApacheJDBC的框架(DBUtils)
2.1 下载jar和源码( https://commons.apache.org/proper/commons-dbutils/)
2.2 导入jar
2.3 CRUD 测试
2.3.1 测试CUD
// 测试插入
@Test
public void test1() throws SQLException {
// 没有传递数据库连接池
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "insert into user(username,psw) values(?,?)";
Object[] params = { "xiaobai", "123" };
queryRunner.update(conn, sql, params);
}
// 测试删除
@Test
public void test2() throws SQLException {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "delete from user where id=?";
Object id = 4;
queryRunner.update(conn, sql, id);
}
@Test
public void test3() throws SQLException {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "update user set username=? where id=?";
Object[] params = { "xiaoxiao", 5 };
queryRunner.update(conn, sql, params);
}
2.3.2 源码的解析
* QueryRunner
构造器
批处理
查询
CUD
2.3.3 查询
* 单个查询
@Test
public void test4() throws SQLException {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "select * from user where id=?";
User user = queryRunner.query(conn, sql, new BeanHandler<User>(User.class), 6);
System.out.println(user);
}
* 列表查询
// 列表的查询
@Test
public void test5() throws SQLException {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "select * from user";
List<User> users = queryRunner.query(conn, sql, new BeanListHandler<User>(User.class));
System.out.println(users);
}
2.3.4 批处理
// 测试批处理
@Test
public void test6() throws SQLException {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "insert into user(username,psw) values(?,?)";
Object[][] params = new Object[10][];
for (int i = 0; i < 10; i++) {
params[i]=new Object[] {"xiaochengyan"+i,"123"};
}
queryRunner.batch(conn, sql, params);
}
2.4 ResultSetHandler的子类的测试
2.4.1 子类分析
- ArrayHandler:
- ArrayListHandler:
- BeanHandler:
- BeanListHandler:
- ColumnListHandler:
- KeyedHandler(name):
- MapHandler:
- MapListHandler:
- BeanMapHandler:
- ScalarHandler:
2.4.2 子类源码的分析
* ArrayHandler
总结;数组的长度,就是列个数,数组值,列的值,适应查询出一条数据
* ArrayListHandler
父类:AbstractListHandler
总结;列表装了(数组的长度,就是列个数,数组值,列的值)适应查询出多条数据
2.4.3 测试这个子类的用
// ArrayHandler
@Test
public void test7() throws SQLException {
QueryRunner qr = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "select * from user where id=?";
Object result[] = (Object[]) qr.query(conn, sql, new ArrayHandler(), 5);
System.out.println(Arrays.asList(result)); // list toString()
}
// ArrayListHandler
@Test
public void test8() throws SQLException {
QueryRunner qr = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "select * from user";
List<Object[]> list = (List<Object[]>) qr.query(conn, sql, new ArrayListHandler());
for (Object[] objs : list) {
System.out.println(Arrays.asList(objs));
}
}
// BeanHandler
// BeanListHandler
//ColumnListHandler
@Test
public void test9() throws SQLException {
QueryRunner qr = new QueryRunner();
Connection conn = ConnectionUtil.getConnection();
String sql = "select * from user";
List list = (List) qr.query(conn,sql, new ColumnListHandler("username"));
System.out.println(list);
}
备注:
* http://www.cnblogs.com/xdp-gacl/p/4007225.html
* https://commons.apache.org/proper/commons-dbutils/