JDBC优化及工具类封装
现有问题
ThreadLocal
为解决多线程程序的并发问题提供了一种新的思路,使用这个工具类可以很简洁地编写出优美的多线程程序,通常用在多线程中管理共享数据库连接、Session等 ThreadLocal用于保存某个线程共享变量,原因是Java中,每一个线程对象都有一个ThreadLocalMap<ThreadLocal,Object>,其key就是一个ThreadLocal,而Object即为该线程的共享变量 这个map通过ThreadLocal的set和get方法操作,对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不影响其他线程的变量 在进行对象跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束 线程间数据隔离 进行事务操作,用于存储线程事务信息 数据库连接,Session会话管理 ThreadLocal对象.get:获取ThreadLocal中当前线程共享变量的值 ThreadLocal对象.set:设置ThreadLocal中当前线程共享变量的值 ThreadLocal对象.remove:移除ThreadLocal中当前线程共享变量的值
package com. lotus. senior. utils ; import com. alibaba. druid. pool. DruidDataSourceFactory ; import javax. sql. DataSource ;
import java. io. InputStream ;
import java. sql. Connection ;
import java. sql. SQLException ;
import java. util. Properties ;
public class JDBCUtilV2 { private static DataSource dataSource; private static ThreadLocal < Connection > threadLocal = new ThreadLocal < > ( ) ; static { Properties properties = new Properties ( ) ; InputStream is = JDBCUtilV2 . class . getClassLoader ( ) . getResourceAsStream ( "db.properties" ) ; try { properties. load ( is) ; dataSource = DruidDataSourceFactory . createDataSource ( properties) ; } catch ( Exception e) { e. printStackTrace ( ) ; } } public static Connection getConnection ( ) { try { Connection connection = threadLocal. get ( ) ; if ( connection == null ) { connection = dataSource. getConnection ( ) ; threadLocal. set ( connection) ; } return connection; } catch ( SQLException e) { throw new RuntimeException ( e) ; } } public static void destory ( ) { try { Connection conn = threadLocal. get ( ) ; if ( conn != null ) { threadLocal. remove ( ) ; conn. close ( ) ; } } catch ( SQLException e) { e. printStackTrace ( ) ; } }
}
DAO封装
DAO概念
DAO(Data Access Object)数据访问对象 Java面向对象语言,数据在Java中通常以对象形式存在,一张表对应一个实体类,一张表的操作对应一个DAO对象 在Java操作数据库时,我们会将对同一张表的增删改查操作统一维护起来,维护的这个类即DAO层 DAO只关注数据库操作,供业务层Service调用,将职责划分清楚
BaseDAO概念
基本上每个数据表都应该有一个对应的DAO接口及实现类,发现对所有表的操作(增删改查)代码重复度很高,所以可以抽取公共代码,给这些DAO的实现类抽取一个公共的父类,复用基本操作,称为BaseDAO
BaseDAO搭建
public class BaseDAO { public int executeUpdate ( String sql, Object . . . params) { int row = 0 ; Connection conn = JDBCUtilV2 . getConnection ( ) ; PreparedStatement preparedStatement = null ; try { preparedStatement = conn. prepareStatement ( sql) ; if ( params != null && params. length > 0 ) { for ( int i = 0 ; i < params. length; i++ ) { preparedStatement. setObject ( i+ 1 , params[ i] ) ; } } row = preparedStatement. executeUpdate ( ) ; } catch ( SQLException e) { e. printStackTrace ( ) ; } finally { if ( preparedStatement != null ) { try { preparedStatement. close ( ) ; } catch ( SQLException e) { e. printStackTrace ( ) ; } } JDBCUtilV2 . destory ( ) ; } return row; } public < T > List < T > executeQuery ( Class < T > clazz, String sql, Object . . . params) throws SQLException , IllegalAccessException , InstantiationException , NoSuchFieldException { Connection conn = JDBCUtilV2 . getConnection ( ) ; PreparedStatement preparedStatement = conn. prepareStatement ( sql) ; if ( params != null && params. length > 0 ) { for ( int i = 0 ; i < params. length; i++ ) { preparedStatement. setObject ( i+ 1 , params[ i] ) ; } } ResultSet rs = preparedStatement. executeQuery ( ) ; ResultSetMetaData metaData = rs. getMetaData ( ) ; int columnCount = metaData. getColumnCount ( ) ; List < T > list = new ArrayList < > ( ) ; while ( rs. next ( ) ) { T t = clazz. newInstance ( ) ; for ( int i = 1 ; i <= columnCount; i++ ) { Object value = rs. getObject ( i) ; String fieldName = metaData. getColumnLabel ( i) ; Field field = clazz. getDeclaredField ( fieldName) ; field. setAccessible ( true ) ; field. set ( t, value) ; } list. add ( t) ; } rs. close ( ) ; preparedStatement. close ( ) ; JDBCUtilV2 . destory ( ) ; return list; } public < T > T executeQueryBean ( Class < T > clazz, String sql, Object . . . params) throws SQLException , IllegalAccessException , InstantiationException , NoSuchFieldException { List < T > list = this . executeQuery ( clazz, sql, params) ; if ( list == null || list. size ( ) == 0 ) { return null ; } return list. get ( 0 ) ; }
} package com. lotus. senior. dao ; import com. lotus. senior. pojo. Employee ; import java. util. List ;
public interface EmployeeDao { List < Employee > selectAll ( ) ; Employee selectByEmpId ( Integer empId) ; int insert ( Employee employee) ; int update ( Employee employee) ; int delete ( Integer empId) ;
}
package com. lotus. senior. dao. impl ; import com. lotus. senior. dao. BaseDAO ;
import com. lotus. senior. dao. EmployeeDao ;
import com. lotus. senior. pojo. Employee ; import java. sql. SQLException ;
import java. util. List ; public class EmployeeDaoImpl extends BaseDAO implements EmployeeDao { @Override public List < Employee > selectAll ( ) { String sql = "select emp_id empId,emp_name empName,emp_salary empSalary,emp_age empAge from t_emp" ; try { return executeQuery ( Employee . class , sql, null ) ; } catch ( Exception e) { throw new RuntimeException ( e) ; } } @Override public Employee selectByEmpId ( Integer empId) { String sql = "select emp_id empId,emp_name empName,emp_salary empSalary,emp_age empAge from t_emp where emp_id = ?" ; try { Employee employee = executeQueryBean ( Employee . class , sql, empId) ; return employee; } catch ( Exception e) { throw new RuntimeException ( e) ; } } @Override public int insert ( Employee employee) { try { String sql = "insert into t_emp(emp_name,emp_salary,emp_age)values(?,?,?)" ; return executeUpdate ( sql, employee. getEmpName ( ) , employee. getEmpSalary ( ) , employee. getEmpAge ( ) ) ; } catch ( Exception e) { throw new RuntimeException ( e) ; } } @Override public int update ( Employee employee) { try { String sql = "update t_emp set emp_salary = ? where emp_id = ?" ; return executeUpdate ( sql, employee. getEmpSalary ( ) , employee. getEmpId ( ) ) ; } catch ( Exception e) { throw new RuntimeException ( e) ; } } @Override public int delete ( Integer empId) { try { String sql = "delete from t_emp where emp_id = ?" ; return executeUpdate ( sql, empId) ; } catch ( Exception e) { throw new RuntimeException ( e) ; } }
}