JDBC資料庫連線池連線資料庫及資料庫操作DAO層設計通用更新及查詢方法(一)
該篇文章介紹了資料庫連線池獲取資料庫連線以及資料庫操作的基本使用,然後主要提供了java專案案例中dao層的一種設計,利用反射的原理定義了通用的查詢方法可以對應所有的表和例項。文章中的每段程式碼都提供了詳細的註釋及邏輯步驟
首先匯入資料庫連線的所需要的jar包:
mysql資料庫連線驅動:mysql-connector-java-5.1.47-bin.jar
資料庫連線池使用到的jar包:commons-dbcp2-2.4.0.jar
可能還需要的jar包:commons-logging-1.2.jar commons-pool2-2.6.0.jar
然後準備配置檔案:
在src下建立dbcp.properties檔案
檔案內容:
#資料庫驅動 driverClassName=com.mysql.jdbc.Driver #資料庫連線地址 埠號 資料庫名 url=jdbc:mysql://localhost:3306/text #資料庫使用者名稱 username=root #密碼 password=123456 #連線池最大資料庫連線數 0表示無限制 maxActive=30 #最大空閒數 0表示無限制 maxIdle=10 #最大建立連線的等待時間,如果超過改時間接到異常,-1表示無限制 maxWait=1000 #超過removeAbandonTimeout時間後是否進行無用連線的回收預設為false removeAbandoned=true #超出時間限制,回收沒有使用的連線 預設300秒 removeAbandonedTimeout=180
一、通過資料庫連線池獲取資料庫連線並設計工具類獲取資料庫連線和關閉連線
工具類JDBCTool
class JDBCTool{
public static Connection getConnection(){} //獲取資料庫的連線
public static void colseAll(Connection connection,Statement statement,ResultSet resultSet){} //關閉所有連線
}
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
/**
* @author Administrator
*資料庫連線工具 獲取和關閉資料連線
*/
public class JDBCTools {
/**
* 通過資料庫連線池 獲取資料庫連結
* @throws Exception
*/
private static Properties properties = new Properties(); //屬性集配置資訊物件
private static DataSource dataSource = null; //資料來源物件
//靜態程式碼塊載入驅動
static{
//獲取配置檔案的流物件
InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("dbcp.properties");
try {
//載入配置問價獲取配置資訊
properties.load(inStream);
//獲取資料原物件
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取資料庫連線物件
public static Connection getConnection() throws Exception{
return dataSource.getConnection();
}
/**
* 關閉資料所有連線
* @param connection
* @param statement
* @param set
*/
public static void colseAll(Connection connection,Statement statement,ResultSet resultSet){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
二、定義一個工具類方法利用反射為例項物件的屬相賦值
//obj例項物件 fieldName屬性名 value屬性值
public static void setFielValue(Object obj,String fieldName,Object value){}
public class ReflectionUtils {
public static void setFielValue(Object obj,String fieldName,Object value ) throws Exception{
//獲取類的class物件
Class clazz = obj.getClass();
//獲取屬性物件
Field f = clazz.getDeclaredField(fieldName);
//設定屬性為可設定
f.setAccessible(true);
//設定屬性值
f.set(obj, value);
}
}
三、定義一個介面DaoFun定義所有的功能
public interface DaoFun {
/**
*//資料庫更新操作,sql可以是update,insert,delete的預編譯語句,可變引數為預編譯語句中佔位符的值
* @param sql
* @param args
*/
void updata(String sql,Object ... args);
/**
*//查詢單條記錄 返回對應的例項物件 ,clazz為對應例項類的class物件,SQL為select的預編譯語句,可變引數是對應的佔位符的值
* @param clazz
* @param sql
* @param args
*/
<T> T getObject(Class<T> clazz,String sql,Object ... args );
/**
* //查詢多條記錄,返回對應例項物件的集合,clazz為對應例項類的class物件,SQL為select的預編譯語句,可變引數是對應的佔位符的值
* @param clazz
* @param sql
* @param args
*/
<T> List<T> getObjectList(Class<T> clazz, String sql,Object ... args);
/**
* 查詢某條記錄的某一個欄位值
* @param clazz
* @param sql
* @param args
*/
<E> E getForValue(String sql,Object ... args);
}
四、定義一個基類BaseDao實現DaoFun介面,該類的方法可以定義成protected,定義dao層的實現類來繼承該類即可直接使用該類的方法。
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.mysql.jdbc.ResultSetMetaData;
import com.qy.util.JDBCTools;
import com.qy.util.ReflectionUtils;
public class BaseDAO implements DaoFun {
private Connection connection = null; //資料庫連線物件
private PreparedStatement statement = null; //預編譯語句物件
private ResultSet resultSet = null; //查詢資料集物件
@Override
public void updata(String sql, Object... args) {
try {
//獲取資料庫連線
connection = JDBCTools.getConnection();
//獲取預編譯語句物件
statement = connection.prepareStatement(sql);
//設定預編譯語句的引數值
for(int i = 0; i < args.length; i ++){
statement.setObject(i + 1, args[i]);
}
int a = statement.executeUpdate();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
JDBCTools.colseAll(connection, statement, resultSet);
}
}
@Override
public <T> T getObject(Class<T> clazz, String sql, Object... args) {
T entity = null;
try {
//1.獲取connection
connection = JDBCTools.getConnection();
//2.獲取preparedStatement
statement = connection.prepareStatement(sql);
//3.填充佔位符
for (int i = 0; i < args.length; i++) {
statement.setObject(i + 1, args[i]);
}
//4.進行查詢
resultSet = statement.executeQuery();
//5.準備map<String,Object> 欄位名的別名 欄位值
if(resultSet.next()){
Map<String,Object> map = new HashMap<String, Object>();
//6.得到ResultSetMetaData物件
ResultSetMetaData rsmd = (ResultSetMetaData) resultSet.getMetaData();
//7.處理resultSet
//8.有ResultSetMetaData物件得到結果集中有多少列
int columnCount = rsmd.getColumnCount();
//9.由resultSetMetaData 得到每一列的別名 ResultSet得到值
for (int i = 0; i < columnCount; i++) {
String columnLabel = rsmd.getColumnLabel(i + 1);
Object columnValue = resultSet.getObject(columnLabel);
//10.填充map物件
map.put(columnLabel, columnValue);
}
//11利用反射獲取class物件
entity = clazz.newInstance();
//12.遍歷map物件利用反射填充物件的屬性值 屬性名為map的key 屬性值為map中的value
for(Map.Entry<String, Object> entry : map.entrySet()){
String propertyName = entry.getKey();
Object value = entry.getValue();
//利用反射對屬相賦值
ReflectionUtils.setFielValue(entity, propertyName, value);
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
JDBCTools.colseAll(connection, statement, resultSet);
}
return entity;
}
@Override
public <T> List<T> getObjectList(Class<T> clazz, String sql, Object... args) {
ArrayList<T> list = new ArrayList<T>();
T entity = null;
try {
//1.獲取connection
connection = JDBCTools.getConnection();
//2.獲取preparedStatement
statement = connection.prepareStatement(sql);
//3.填充佔位符
for (int i = 0; i < args.length; i++) {
statement.setObject(i + 1, args[i]);
}
//4.進行查詢
resultSet = statement.executeQuery();
//5.準備map<String,Object> 欄位名的別名 欄位值
Map<String,Object> map = new HashMap<String, Object>();
//6.得到ResultSetMetaData物件
ResultSetMetaData rsmd = (ResultSetMetaData) resultSet.getMetaData();
//8.有ResultSetMetaData物件得到結果集中有多少列
int columnCount = rsmd.getColumnCount();
while(resultSet.next()){
//7.處理resultSet
//9.由resultSetMetaData 得到每一列的別名 ResultSet得到值
for (int i = 0; i < columnCount; i++) {
String columnLabel = rsmd.getColumnLabel(i + 1);
Object columnValue = resultSet.getObject(columnLabel);
//10.填充map物件
map.put(columnLabel, columnValue);
}
//11利用反射獲取class物件
entity = clazz.newInstance();
//12.遍歷map物件利用反射填充物件的屬性值 屬性名為map的key 屬性值為map中的value
for(Map.Entry<String, Object> entry : map.entrySet()){
String propertyName = entry.getKey();
Object value = entry.getValue();
//利用反射為物件屬性賦值
ReflectionUtils.setFielValue(entity, propertyName, value);
}
list.add(entity);
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
JDBCTools.colseAll(connection, statement, resultSet);
}
return list;
}
@Override
public <E> E getForValue(String sql, Object... args) {
try {
//1.獲取connection
connection = JDBCTools.getConnection();
//2.獲取preparedStatement
statement = connection.prepareStatement(sql);
//3.填充佔位符
for (int i = 0; i < args.length; i++) {
statement.setObject(i + 1, args[i]);
}
//4.進行查詢
resultSet = statement.executeQuery();
//處理resultSet
if(resultSet.next()){
return (E) resultSet.getObject(1);
}
} catch (Exception e1) {
e1.printStackTrace();
}finally{
JDBCTools.colseAll(connection, statement, resultSet);
}
return null;
}
}
本篇文章主要介紹了dao層的一種設計,定義通用的資料庫操作方法,提高程式設計時提高程式碼的複用性,下篇文章主要介紹該篇定義方法的使用。