DAO设计模式2.docx
《DAO设计模式2.docx》由会员分享,可在线阅读,更多相关《DAO设计模式2.docx(28页珍藏版)》请在冰豆网上搜索。
DAO设计模式2
3.4.2 、定义IEmpDAO接口的实现类
既然在接口中已经定义了数据层的操作标准,那么对于实现类只需要遵循数据层的CRUD操作即可,但是对于DAO接口的实现类需要有明确的定义,要求将其定义在:
cn.mldn.oracle.dao.impl包之中。
范例:
定义EmpDAOImpl子类
· 现在有如下一种的子类实现接口方式:
@Override
public boolean doCreate(Empvo) throws Exception{
DatabaseConnectiondbc= new DatabaseConnection();
Stringsql= "INSERTINTOemp(empno,ename,job,hiredate,sal,comm)VALUES(?
?
?
?
?
?
)";
PreparedStatementpstmt=dbc.getConnection().prepareStatement(sql);
pstmt.setInt(1,vo.getEmpno());
pstmt.setString(2,vo.getEname());
pstmt.setString(3,vo.getJob());
pstmt.setDate(4, new java.sql.Date(vo.getHiredate().getTime()));
pstmt.setDouble(5,vo.getSal());
pstmt.setDouble(6,vo.getComm());
if (pstmt.executeUpdate()>0){
return true ;
}
dbc.close();
return false;
}
如果真的按照这种方式实现的程序,有两个重要问题:
· 对于数据层之中给出的若干方法,由服务层调用,一个服务层要执行N个数据层,那么每次执行的时候打开一次关闭一次数据库?
· 按照异常的处理机制,如果现在执行的过程之中出现了错误,那么顺着throws就结束调用了,数据库就再也无法关闭了。
按照之前的分析,一个业务要进行多个数据层操作,所以数据库连接与关闭交给业务层做最合适,而数据层只需要有一个Connection对象就可以操作了,它不需要关心这个对象是从那里来的,怎么来的,只关心能不能使用。
package cn.mldn.oracle.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import cn.mldn.oracle.dao.IEmpDAO;
import cn.mldn.oracle.vo.Emp;
public class EmpDAOImpl implements IEmpDAO{
private Connection conn;
private PreparedStatement pstmt;
public EmpDAOImpl(Connectionconn){
this.conn =conn;
}
@Override
public boolean doCreate(Empvo) throws Exception{
Stringsql= "INSERTINTOemp(empno,ename,job,hiredate,sal,comm)VALUES(?
?
?
?
?
?
)";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setInt(1,vo.getEmpno());
this.pstmt.setString(2,vo.getEname());
this.pstmt.setString(3,vo.getJob());
this.pstmt.setDate(4, new java.sql.Date(vo.getHiredate().getTime()));
this.pstmt.setDouble(5,vo.getSal());
this.pstmt.setDouble(6,vo.getComm());
if (this.pstmt.executeUpdate()>0){
return true;
}
return false;
}
@Override
public boolean doUpdate(Empvo) throws Exception{
Stringsql= "UPDATEempSETename=?
job=?
hiredate=?
sal=?
comm=?
WHEREempno=?
";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1,vo.getEname());
this.pstmt.setString(2,vo.getJob());
this.pstmt.setDate(3, new java.sql.Date(vo.getHiredate().getTime()));
this.pstmt.setDouble(4,vo.getSal());
this.pstmt.setDouble(5,vo.getComm());
this.pstmt.setInt(6,vo.getEmpno());
if (this.pstmt.executeUpdate()>0){
return true;
}
return false;
}
@Override
public boolean doRemove(int id) throws Exception{
Stringsql= "DELETEFROMempWHEREempno=?
";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setInt(1,id);
if (this.pstmt.executeUpdate()>0){
return true;
}
return false;
}
@Override
public EmpfindById(int id) throws Exception{
Empemp= null;
Stringsql= "SELECTempno,ename,job,hiredate,sal,commFROMempWHEREempno=?
";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setInt(1,id);
ResultSetrs= this.pstmt.executeQuery();
if (rs.next()){
emp= new Emp();
emp.setEmpno(rs.getInt
(1));
emp.setEname(rs.getString
(2));
emp.setJob(rs.getString(3));
emp.setHiredate(rs.getDate(4));
emp.setSal(rs.getDouble(5));
emp.setComm(rs.getDouble(6));
}
return emp;
}
@Override
public ListfindAll() throws Exception{
Listall= new ArrayList();
Stringsql= "SELECTempno,ename,job,hiredate,sal,commFROMemp";
this.pstmt = this.conn.prepareStatement(sql);
ResultSetrs= this.pstmt.executeQuery();
while (rs.next()){
Empemp= new Emp();
emp.setEmpno(rs.getInt
(1));
emp.setEname(rs.getString
(2));
emp.setJob(rs.getString(3));
emp.setHiredate(rs.getDate(4));
emp.setSal(rs.getDouble(5));
emp.setComm(rs.getDouble(6));
all.add(emp);
}
return all;
}
@Override
public ListfindAll(Stringcolumn,StringkeyWord, int currentPage,
int lineSize) throws Exception{
Listall= new ArrayList();
Stringsql= "SELECT*FROM("
+ "SELECTempno,ename,job,hiredate,sal,comm,ROWNUMrnFROMempWHERE"
+column+ "LIKE?
ANDROWNUM<=?
)temp" + "WHEREtemp.rn>?
";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, "%" +keyWord+ "%");
this.pstmt.setInt(2,currentPage*lineSize);
this.pstmt.setInt(3,(currentPage-1)*lineSize);
ResultSetrs= this.pstmt.executeQuery();
while (rs.next()){
Empemp= new Emp();
emp.setEmpno(rs.getInt
(1));
emp.setEname(rs.getString
(2));
emp.setJob(rs.getString(3));
emp.setHiredate(rs.getDate(4));
emp.setSal(rs.getDouble(5));
emp.setComm(rs.getDouble(6));
all.add(emp);
}
return all;
}
@Override
public int getAllCount(Stringcolumn,StringkeyWord) throws Exception{
Stringsql= "SELECTCOUNT(empno)FROMempWHERE" +column+ "LIKE?
";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, "%" +keyWord+ "%");
ResultSetrs= this.pstmt.executeQuery();
if (rs.next()){
return rs.getInt
(1);
}
return 0;
}
}
3.4.3 、定义DAO工厂类
由于不同层之间只能依靠接口取得对象,所以就一定需要定义工厂操作类,工厂类定义在cn.mldn.oracle.factory包之中,名称为DAOFactory。
范例:
定义工厂类
package cn.mldn.oracle.factory;
import java.sql.Connection;
import cn.mldn.oracle.dao.IEmpDAO;
import cn.mldn.oracle.dao.impl.EmpDAOImpl;
public class DAOFactory{
public static IEmpDAOgetIEmpDAOInstance(Connectionconn){
return new EmpDAOImpl(conn);
}
}
3.5、开发业务层(重点)
3.5.1 、开发业务层标准
业务层以后也是需要留给其他层进行调用的,所以业务层定义的时候也需要首先定义出操作标准,而这个标准也依然使用接口完成,对于业务层,接口命名要求:
表名称 +Service,例如:
IEmpService,表示操作Emp表的业务。
范例:
在cn.mldn.oracle.service包中定义IEmpService接口
package cn.mldn.oracle.service;
import java.util.Map;
import cn.mldn.oracle.vo.Emp;
public interface IEmpService{
/**
* 调用数据库的增加操作,操作流程如下:
*
首先要使用IEmpDAO接口中的findById()方法,根据要增加的id查看指定的雇员信息是否存在; *
如果要增加的雇员信息不存在,则执行IEmpDAO接口的doCreate()方法,并将结果返回; * @param vo 包装数据的对象
* @return 如果增加成功,返回true,如果雇员编号存在或者是增加失败,返回false
* @throws Exception 有异常交给被调用处处理
*/
public boolean insert(Empvo) throws Exception;
/**
* 执行数据的更新操作,操作的时候直接调用IEmpDAO接口的doUpdate()方法,并将更新结果返回
* @param vo 包装数据的对象
* @return 如果修改成功,返回true,如果数据不存在或修改失败,返回false
* @throws Exception 有异常交给被调用处处理
*/
public boolean update(Empvo) throws Exception;
/**
* 执行数据的删除操作,删除操作的时候调用IEmpDAO接口的doRemove()方法
* @param id 要删除雇员的id
* @return 如果删除成功,返回true,如果数据不存在或删除失败,则返回false
* @throws Exception 有异常交给被调用处处理
*/
public boolean delete(int id) throws Exception;
/**
* 根据雇员的编号取得全部的信息
* @param id 雇员编号
* @return 如果雇员存在则将数据包装为Emp对象返回,如果数据不存在则返回null
* @throws Exception 有异常交给被调用处处理
*/
public Empget(int id) throws Exception;
/**
* 查询全部或者是模糊查询全部数据,查询的同时可以返回满足此查询的数据量,在调用的时候需要执行以下操作:
*
查询全部的雇员信息:需要IEmpDAO接口的findAll()方法;
*
查询满足条件的雇员数量:使用IEmpDAO接口的getAllCount()方法操作;
* @param column 模糊查询的字段
* @param keyWord 模糊查询的关键字
* @param currentPage 当前所在页
* @param lineSize 每页显示的数据长度
* @return 由于在进行数据返回的时候,此方法要返回两类数据:
List、int,使用Map返回:
*
返回值1:key=allEmps,value=findAll();
*
返回值2:key=empCount,value=getAllCount();
* @throws Exception 有异常交给被调用处处理
*/
public Maplist(Stringcolumn,StringkeyWord,
int currentPage, int lineSize) throws Exception;
}
3.5.2 、定义业务层标准的实现类
如果现在要想实现业务层的标准,必须有一个原则先把握住:
一个业务层的方法操作要调用多个数据层,同时每个业务要处理数据库的打开和关闭。
范例:
定义标准实现类 —— cn.mldn.oracle.service.impl.EmpServiceImpl
package cn.mldn.oracle.service.impl;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import cn.mldn.oracle.dao.IEmpDAO;
import cn.mldn.oracle.dbc.DatabaseConnection;
import cn.mldn.oracle.factory.DAOFactory;
import cn.mldn.oracle.service.IEmpService;
import cn.mldn.oracle.vo.Emp;
public class EmpServiceImpl implements IEmpService{
private DatabaseConnection dbc = new DatabaseConnection();
@Override
public boolean insert(Empvo) throws Exception{
try {
Connectionconn= this.dbc.getConnection(); // 取得连接
IEmpDAOdao=DAOFactory.getIEmpDAOInstance(conn); // 取得DAO接口对象
if (dao.findById(vo.getEmpno())== null){ // 没有要查询的雇员信息
return dao.doCreate(vo); // 返回DAO的结果
}
return false; // 数据存在,直接返回false
} catch (Exceptione){
throw e;
} finally {
this.dbc.close();
}
}
@Override
public boolean update(Empvo) throws Exception{
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.doUpdate(vo);
} catch (Exceptione){
throw e;
} finally {
this.dbc.close();
}
}
@Override