package com.dason.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
*定义一个访问数据库的接口,只提供方法,不提供实现
*
*@params <T> : 类类型参数:在查询时告诉方法返回的bean是什么类型,
* 也就是将结果集封装成什么类型的类
*
*/
public interface Dao<T> {
// 批量处理
void batch(Connection connection,String sql,Object [] ...args) throws SQLException;
// 查询一个值(返回的数据类型可以是任意类型,所以用泛型代替)
<E> E getForValue(Connection connection,String sql,Object...args) throws SQLException;
// 返回 T 类型对象的list 集合
List<T> getForList(Connection connection,String sql,Object...args) throws SQLException;
// 返回一个 T 类型的对象
T getBean(Connection connection,String sql,Object...args) throws SQLException;
// 更新操作
void update(Connection connection,String sql,Object...args) throws SQLException;
}
2. 编写实现类 JDBCDaoImpl
package com.dason.jdbc;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
/**
* JDBCDaoImpl 实现接口Dao ,提供方法的具体实现
*
*/
public class JDBCDaoImpl<T> implements Dao<T> {
// QueryRunner 类 是线程安全的,可作为全局变量
private QueryRunner queryRunner;
private Class<T> type;
@SuppressWarnings("unchecked")
//在子类构造中有一个隐式的 supper(),所以子类在
//实例化时都会链式调用父类构造方法初始化父类空间.
public JDBCDaoImpl() {
queryRunner = new QueryRunner();
//getGenericSuperclass:利用反射获取获得带有泛型参数的父类
//getActualTypeArguments():返回该类的泛型参数 的数组
type = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
@Override
public void batch(Connection connection, String sql, Object[]... args) throws SQLException {
queryRunner.batch(connection, sql, args);
}
@Override
public <E> E getForValue(Connection connection, String sql, Object... args) throws SQLException {
return (E) queryRunner.query(connection, sql, new ScalarHandler(), args);
}
@Override
public List<T> getForList(Connection connection, String sql, Object... args) throws SQLException {
return queryRunner.query(connection, sql, new BeanListHandler<>(type), args);
}
@Override
public T getBean(Connection connection, String sql, Object... args) throws SQLException {
return queryRunner.query(connection, sql, new BeanHandler<>(type), args);
}
@Override
public void update(Connection connection, String sql, Object... args) throws SQLException {
queryRunner.update(connection, sql, args);
}
}
3. 继承JDBCDaoImpl ,传入类类型参数
ackage com.dason.jdbc;
/**
*继承JDBCDaoImpl 并传入类类型参数
*
*/
public class UserDao extends JDBCDaoImpl<User>{
}
4. 单元测试
package com.dason.jdbc;
import static org.junit.Assert.*;
import java.sql.Connection;
import java.util.List;
import org.junit.Test;
public class UserDaoTest {
UserDao userDao = new UserDao();
@Test
public void testBatch() {
Connection connection = null;
String sql ="insert into user(id,name,email) values(?,?,?)";
try {
connection = JDBCTools.getConnection();
Object[][] rowData = {{3,"c","c@123"},{7,"g","g@123"}};
userDao.batch(connection, sql,rowData);
} catch (Exception e) {
e.printStackTrace();
} finally{
JDBCTools.releaseDB(null, null, connection);
}
}
@Test
public void testGetForValue() {
Connection connection = null;
String sql ="select * from user where id > ?";
try {
connection = JDBCTools.getConnection();
Object obj = userDao.getForValue(connection, sql, 3);
System.out.println(obj);
} catch (Exception e) {
e.printStackTrace();
} finally{
JDBCTools.releaseDB(null, null, connection);
}
}
@Test
public void testGetForList() {
Connection connection = null;
String sql ="select * from user where id > ?";
try {
connection = JDBCTools.getConnection();
List<User> users = userDao.getForList(connection, sql, 3);
System.out.println(users);
} catch (Exception e) {
e.printStackTrace();
} finally{
JDBCTools.releaseDB(null, null, connection);
}
}
@Test
public void testGetBean() {
Connection connection = null;
String sql ="select * from user where id > ?";
try {
connection = JDBCTools.getConnection();
User user = userDao.getBean(connection, sql, 3);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
} finally{
JDBCTools.releaseDB(null, null, connection);
}
}
@Test
public void testUpdate() {
Connection connection = null;
String sql ="delete from user where id = ?";
try {
connection = JDBCTools.getConnection();
userDao.update(connection, sql, 3);
} catch (Exception e) {
e.printStackTrace();
} finally{
JDBCTools.releaseDB(null, null, connection);
}
}
}
5. 获取泛型参数利用的反射技术: 反射之Type