核心提示: 首先创建数据库表,插入2条测试数据 DAOpackage com.godinsec;import java.sql.Connection;import java.sql.SQLException...

首先创建数据库表,插入2条测试数据

DAO
package com.godinsec; import java.sql.Connection; import java.sql.SQLException; import java.util.List; /** * 访问数据的DAO接口 T:DAO处理的实体类的类型 */ public interface DAO{ /** * 批量处理的方法 */ void batch(Connection connection, String sql, Object[]... args) throws SQLException; /** * 返回具体的一个值:总人数,某个人的信息,平均工资 */ E getForValue(Connection connection, String sql, Object... args) throws SQLException; /** * 返回一个T的集合 * * @return */ List getForList(Connection connection, String sql, Object... args) throws SQLException; /** * 返回一个T的对象 * * @return */ T get(Connection connection, String sql, Object... args) throws SQLException; /** * 增、删、改操作 */ void update(Connection connection, String sql, Object... args) throws SQLException; /** * 查询方法 */ }
JDBCDAO
package com.godinsec; import java.sql.Connection; import java.sql.SQLException; 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; public class JDBCDAOimplements DAO { //QueryRunner是线程安全的 private QueryRunner queryRunner = null; private Class type; public JDBCDAO(){ queryRunner = new QueryRunner(); type = ReflectionUtils.getSuperGenericType(getClass()); } @Override public void batch(Connection connection, String sql, Object[]... args) throws SQLException { queryRunner.batch(connection, sql, args); } //已经实现 @Override public E getForValue(Connection connection, String sql, Object... args) throws SQLException { return (E) queryRunner.query(connection, sql, new ScalarHandler(), args); } //已经实现 @Override public List getForList(Connection connection, String sql, Object... args) throws SQLException { return queryRunner.query(connection, sql, new BeanListHandler<>(type), args); } //已经实现 @Override public T get(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); } }
CustomerDao
package com.godinsec; public class CustomerDao extends JDBCDAO{ }
接下来看一个bean类Customer
private Integer id; private String name; private String email; private Date birth;
最后看测试类的方法吧CustomerDaoTest
1、获取某个字段的值
@Test public void testGetForValue() { Connection connection = null; try { connection = JdbcTools.getConnection(); String sql = "select id,name,email,birth from customer where name = ?"; Object result = customerDao.getForValue(connection, sql, "aaa"); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } finally { JdbcTools.releaseDB(null, null, null, connection); } }
输出如下
1

2、获取某个对象
@Test public void testGet() { Connection connection = null; try { connection = JdbcTools.getConnection(); String sql = "select id,name,email,birth from customer where id=?"; Customer customer = customerDao.get(connection, sql, 1); System.out.println(customer); } catch (Exception e) { e.printStackTrace(); } finally { JdbcTools.releaseDB(null, null, null, connection); } }
输出如下:
Customer [id=1, name=aaa, email=aaa, birth=2016-10-05]
3、获取某个对象集合列表
@Test public void testGetForList() { Connection connection = null; try { connection = JdbcTools.getConnection(); String sql = "select id,name,email,birth from customer"; Listcustomers = customerDao.getForList(connection, sql); System.out.println(customers); } catch (Exception e) { e.printStackTrace(); } finally { JdbcTools.releaseDB(null, null, null, connection); } }
[Customer [id=1, name=aaa, email=aaa, birth=2016-10-05], Customer [id=2, name=bbb, email=bbb, birth=2016-10-26]]
4、对数据库进行增删改操作
@Test public void testUpdate() { Connection connection = null; try { connection = JdbcTools.getConnection(); String sql = "insert into customer values(?,?,?,?)"; // 使用其方法 customerDao.update(connection, sql, 10, "ccc", "ccc", "2011-10-20"); } catch (Exception e) { e.printStackTrace(); } finally { JdbcTools.releaseDB(null, null, null, connection); } }
再次查询数据库,记录增加一条

最后还有一个数据库工具类,以及一个反射工具类
JdbcTools
package com.godinsec; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class JdbcTools { // 开始事务 public static void beginTx(Connection connection) { if (connection != null) { try { connection.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } } } // 回滚事务 public static void rollback(Connection connection) { if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 提交事务 public static void commit(Connection connection) { if (connection != null) { try { connection.commit(); } catch (SQLException e) { e.printStackTrace(); } } } // 使用数据库链接池来获取数据库链接--私有静态 private static DataSource dataSource = null; // 数据库连接池只需要初始化一次就够了,因为一个项目只需要一个连接池就够了 static { dataSource = new ComboPooledDataSource("helloc3p0"); } public static Connection getConnection() throws Exception { return dataSource.getConnection(); } // 获取连接 public static Connection getConnection1() throws Exception { String user = "root"; String password = "root"; String jdbcUrl = "jdbc:mysql:///mydatabase"; String driverClass = "com.mysql.jdbc.Driver"; Class.forName(driverClass); Connection connection = DriverManager.getConnection(jdbcUrl, user, password); return connection; } // 关闭资源 public static void releaseDB(ResultSet resultSet, PreparedStatement preparedStatement, Statement statement, Connection connection) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { // 数据库链接池的connection对象并不是真的进行关闭 // 而是把链接归还到数据库连接池中 connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
ReflectionUtils
package com.godinsec; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * 反射的 Utils 函数集合 * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数 * @author Administrator * */ public class ReflectionUtils { /** * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型 * 如: public EmployeeDao extends BaseDao* @param clazz * @param index * @return */ @SuppressWarnings("unchecked") public static Class getSuperClassGenricType(Class clazz, int index){ Type genType = clazz.getGenericSuperclass(); if(!(genType instanceof ParameterizedType)){ return Object.class; } Type [] params = ((ParameterizedType)genType).getActualTypeArguments(); if(index >= params.length || index < 0){ return Object.class; } if(!(params[index] instanceof Class)){ return Object.class; } return (Class) params[index]; } /** * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型 * 如: public EmployeeDao extends BaseDao * @param * @param clazz * @return */ @SuppressWarnings("unchecked") public static Class getSuperGenericType(Class clazz){ return getSuperClassGenricType(clazz, 0); } /** * 循环向上转型, 获取对象的 DeclaredMethod * @param object * @param methodName * @param parameterTypes * @return */ public static Method getDeclaredMethod(Object object, String methodName, Class[] parameterTypes){ for(Class superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){ try { //superClass.getMethod(methodName, parameterTypes); return superClass.getDeclaredMethod(methodName, parameterTypes); } catch (NoSuchMethodException e) { //Method 不在当前类定义, 继续向上转型 } //.. } return null; } /** * 使 filed 变为可访问 * @param field */ public static void makeAccessible(Field field){ if(!Modifier.isPublic(field.getModifiers())){ field.setAccessible(true); } } /** * 循环向上转型, 获取对象的 DeclaredField * @param object * @param filedName * @return */ public static Field getDeclaredField(Object object, String filedName){ for(Class superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){ try { return superClass.getDeclaredField(filedName); } catch (NoSuchFieldException e) { //Field 不在当前类定义, 继续向上转型 } } return null; } /** * 直接调用对象方法, 而忽略修饰符(private, protected) * @param object * @param methodName * @param parameterTypes * @param parameters * @return * @throws InvocationTargetException * @throws IllegalArgumentException */ public static Object invokeMethod(Object object, String methodName, Class [] parameterTypes, Object [] parameters) throws InvocationTargetException{ Method method = getDeclaredMethod(object, methodName, parameterTypes); if(method == null){ throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]"); } method.setAccessible(true); try { return method.invoke(object, parameters); } catch(IllegalAccessException e) { System.out.println("不可能抛出的异常"); } return null; } /** * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter * @param object * @param fieldName * @param value */ public static void setFieldValue(Object object, String fieldName, Object value){ Field field = getDeclaredField(object, fieldName); if (field == null) throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]"); makeAccessible(field); try { field.set(object, value); } catch (IllegalAccessException e) { System.out.println("不可能抛出的异常"); } } /** * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter * @param object * @param fieldName * @return */ public static Object getFieldValue(Object object, String fieldName){ Field field = getDeclaredField(object, fieldName); if (field == null) throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]"); makeAccessible(field); Object result = null; try { result = field.get(object); } catch (IllegalAccessException e) { System.out.println("不可能抛出的异常"); } return result; } }
c3p0-config.xml
root root com.mysql.jdbc.Driver jdbc:mysql:///mydatabase 5 5 5 10 20 5