手把手教你如何自定義DAO框架(重量級乾貨)(yet)
https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247484864&idx=2&sn=9721e840eab2b929e9523d82c45a1bb6&chksm=ebd63aecdca1b3fa998f27a185630f7e6b40564cf7cacec8e32818184fcf1d2e23d33757beee&mpshare=1&scene=1&srcid=0206Vt8xydSjEPcErB4rA2az&key=7a4fd26cfac6ce0520c3b75a31a96df31d4be437a8f3317af06cfc9c97b79ac5fbf1bdc6bd5d03aed3ab70644e57d1140efc6bdc63ad85edd4508daea3e8e113732c605adb68dc975c22022d8f989caf&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=EVZTeGFk8lco7QnbdQu1aVcnN2PUGDc58FC5tG6YJ74SpwFYT%2BA%2BC4MKrc8qeCV1
描述:本篇部落格,主要是對於目前實際web專案開發中,對於資料庫操作的一些基本方法的封裝,通過這樣的方式,可以使得開發更加簡單,減少程式碼量,也便於維護和閱讀。其中,主要是講解了三種不同情況的封裝方法,都是自身實際開發過程中,進行積累的,當然,還有很多不足之處,但是基本夠專案的基本開發。
一:非框架的DAO層封裝
其中包含的知識點:
1:連線池
2:資料來源
3:反射
4:資料庫元資料物件
5:基本的jdbc知識
封裝步驟:
(1)匯入dbcp資料來源包
(2)編寫properties檔案,並且命令為dbcpconfig.properties
#連線設定
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/填寫要使用的資料庫
username=填寫自己的mysql賬號
password=填寫自己的mysql密碼
#<!-- 初始化連線 -->
initialSize=10
#最大連線數量
maxActive=50
#<!-- 最大空閒連線 -->
maxIdle=20
#<!-- 最小空閒連線 -->
minIdle=5
#<!-- 超時等待時間以毫秒為單位 6000毫秒/1000等於60秒 -->
maxWait=60000
#JDBC驅動建立連線時附帶的連線屬性屬性的格式必須為這樣:[屬性名=property;]
#注意:"user" 與 "password" 兩個屬性會被明確地傳遞,因此這裡不需要包含他們。
connectionProperties=useUnicode=true;characterEncoding=gbk
#指定由連線池所建立的連線的自動提交(auto-commit)狀態。
defaultAutoCommit=true
#driver default 指定由連線池所建立的連線的只讀(read-only)狀態。
#如果沒有設定該值,則“setReadOnly”方法將不被呼叫。(某些驅動並不支援只讀模式,如:Informix)
defaultReadOnly=false
#driver default 指定由連線池所建立的連線的事務級別(TransactionIsolation)。
#可用值為下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
(3)編寫DBCP工具類
publicclassDBCPUtils{
privatestaticDataSource ds ;
static{
//將配置檔案載入進來
InputStreamin= DBCPUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties") ;
Properties props =newProperties() ;
try{
props.load(in) ;
ds = BasicDataSourceFactory.createDataSource(props) ;
}catch(Exception e) {
thrownewRuntimeException("伺服器忙") ;
}
}
//提供獲取連線的方法
publicstaticConnectiongetConnection(){
try{
returnds.getConnection() ;
}catch(SQLException e) {
thrownewRuntimeException("伺服器忙") ;
}
}
}
(4)編寫基本DAO層方法封裝
//自定義框架
publicclassBaseDao{
// 執行添改刪語句
publicbooleanupdate(String sql, Object...params){
// 拿到連線物件
Connection conn = DBCPUtils.getConnection();
intt =0;
try{
// 建立預處理命令物件
PreparedStatement pstmt = conn.prepareStatement(sql);
// 對?進行賦值
// 獲取ParameterMetaData物件
ParameterMetaData pmd = pstmt.getParameterMetaData();
// 拿到?的個數
intn = pmd.getParameterCount();
if(n >0) {
// sql語句裡有?號
if(params==null||params.length != n) {
thrownewRuntimeException("引數的個數不匹配");
}
// 依次給每個?賦值
for(inti =0; i < n; i++) {
pstmt.setObject(i +1,params[i]);
}
}
t = pstmt.executeUpdate();
}catch(SQLException e) {
e.printStackTrace();
}finally{
try{
conn.close();// 還回池中了
}catch(SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
returnt >0?true:false;
}
// 執行查詢(返回的結果可能是一個或者多個,或者為null,這個就具體根據返回結果再進行處理即可)
publicObjectqueryOne(String sql,Class clazz, Object...params){
// 拿到連線物件
Connection conn = DBCPUtils.getConnection();
try{
// 建立預處理命令物件
PreparedStatement pstmt = conn.prepareStatement(sql);
// 對?進行賦值
// 獲取ParameterMetaData物件
ParameterMetaData pmd = pstmt.getParameterMetaData();
// 拿到?的個數
intn = pmd.getParameterCount();
if(n >0) {
// sql語句裡有?號
if(params==null||params.length != n) {
thrownewRuntimeException("引數的個數不匹配");
}
// 依次給每個?賦值
for(inti =0; i < n; i++) {
pstmt.setObject(i +1,params[i]);
}
}
ResultSet rs = pstmt.executeQuery();
//返回的結果可能是一個或者多個,或者為null
returnnewResultSetListenerHandlerImpl().handler(rs, clazz) ;
}catch(SQLException e) {
thrownewRuntimeException() ;
}finally{
try{
conn.close();// 還回池中了
}catch(SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
(5)查詢返回結果集與實體bean的封裝物件ResultSetListenerHandlerImpl
//只適用於結果集有多條記錄的情況
//物件的屬性名和表中的欄位名應當一致
publicclassResultSetListenerHandlerImpl{
publicObject handler(ResultSet rs,Classclazz){
List<Object>list=newArrayList<Object>() ;
//拿到結果集的元資料物件
try{
while(rs.next()){
ResultSetMetaData rsmd = rs.getMetaData() ;
//拿到公有多少列
int columnCount = rsmd.getColumnCount() ;
//先建立物件
Object obj = clazz.newInstance() ;
for(int i =0; i < columnCount; i++) {
//拿到列名
String columnName = rsmd.getColumnName(i+1) ;
//拿到物件對應的屬性
Field field = clazz.getDeclaredField(columnName) ;
//設定私有屬性可以訪問
field.setAccessible(true) ;
//拿到此列對應的值
Object objectValue = rs.getObject(i+1) ;
//給屬性賦值
field.set(obj, objectValue) ;
}
list.add(obj) ;
}
returnlist;
}catch(Exceptione) {
thrownewRuntimeException() ;
}
}
}
上面這個是返回一個List的情況,如果只想是返回單個物件,那麼很簡單,稍微處理一下就可以用下面這個類來實現:
//只適用於結果集只有一條記錄的情況
//物件的屬性名和表中的欄位名應當一致
publicclassResultSetHandlerImpl{
publicObjecthandler(ResultSet rs, Class clazz){
//拿到結果集的元資料物件
try{
if(rs.next()){
ResultSetMetaData rsmd = rs.getMetaData() ;
//拿到公有多少列
intcolumnCount = rsmd.getColumnCount() ;
//先建立物件
Object obj = clazz.newInstance() ;
for(inti =0; i < columnCount; i++) {
//拿到列名
String columnName = rsmd.getColumnName(i+1) ;
//拿到物件對應的屬性
Field field = clazz.getDeclaredField(columnName) ;
//設定私有屬性可以訪問
field.setAccessible(true) ;
//拿到此列對應的值
Object objectValue = rs.getObject(i+1) ;
//給屬性賦值
field.set(obj, objectValue) ;
}
returnobj ;
}else
returnnull;
}catch(Exception e) {
thrownewRuntimeException() ;
}
}
}
二:Mybatis的DAO層封裝
(1)一般先寫介面:
publicinterfaceDAO{
/**
* 儲存物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObject save(String str, Object obj) throwsException;
/**
* 修改物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObject update(String str, Object obj) throwsException;
/**
* 刪除物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObject delete(String str, Object obj) throwsException;
/**
* 查詢物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObject findForObject(String str, Object obj) throwsException;
/**
* 查詢物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObject findForList(String str, Object obj) throwsException;
/**
* 查詢物件封裝成Map
*
*@params
*@paramobj
*@return
*@throwsException
*/
publicObject findForMap(String sql, Object obj, String key, String value) throwsException;
}
(2)再寫實現層:
@Repository("daoSupport")
publicclassDaoSupportimplementsDAO{
@Resource(name ="sqlSessionTemplate")
privateSqlSessionTemplate sqlSessionTemplate;
/**
* 儲存物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObjectsave(String str, Object obj)throwsException{
returnsqlSessionTemplate.insert(str, obj);
}
/**
* 批量更新
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObjectbatchSave(String str, List objs)throwsException{
returnsqlSessionTemplate.insert(str, objs);
}
/**
* 修改物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObjectupdate(String str, Object obj)throwsException{
returnsqlSessionTemplate.update(str, obj);
}
/**
* 批量更新
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicvoidbatchUpdate(String str, List objs)throwsException{
SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
// 批量執行器
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
try{
if(objs !=null) {
for(inti =0, size = objs.size(); i < size; i++) {
sqlSession.update(str, objs.get(i));
}
sqlSession.flushStatements();
sqlSession.commit();
sqlSession.clearCache();
}
}finally{
sqlSession.close();
}
}
/**
* 批量更新
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObjectbatchDelete(String str, List objs)throwsException{
returnsqlSessionTemplate.delete(str, objs);
}
/**
* 刪除物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObjectdelete(String str, Object obj)throwsException{
returnsqlSessionTemplate.delete(str, obj);
}
/**
* 查詢物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObjectfindForObject(String str, Object obj)throwsException{
returnsqlSessionTemplate.selectOne(str, obj);
}
/**
* 查詢物件
*
*@paramstr
*@paramobj
*@return
*@throwsException
*/
publicObjectfindForList(String str, Object obj)throwsException{
returnsqlSessionTemplate.selectList(str, obj);
}
publicObjectfindForMap(String str, Object obj, String key, String value)throwsException{
returnsqlSessionTemplate.selectMap(str, obj, key);
}
}