DAO设计模式简介:
DAO(data access object,数据访问对象)主要功能就是用于进行数据操作的,在程序的标准
架构中属于数据层;
·资源层主要是数据库的操作层,里面可以进行各种数据的存储,但是这是数据存储操作的时候肯定
依靠sql语句,之前发现,如果一个程序中出现过多次sql语句的直接操作,则jsp变得相当复杂
,
而且也不便于程序的可重用性。
可以通过一个专门的数据库的操作组件完成,这就是数据层;
DAO组成:
在整个DAO中实际上都是以接口为操作标准的,即:客户端依靠DAO实现的接口进行操作,而服务
器
端要将接口进行具体的实现,DAO由以下部分组成:
·DatabaseConnection:专门负责数据库的连接与关闭;
·VO:主要由属性、setter、getter方法组成,VO类中的属性与表中的字段相对应,每个VO类的
对象
都表示表中的一条记录;
·DAO:主要定义操作的接口,定义一系列数据库的原子性操作,例如:增加、修改、删除、按
ID查询等;
·Impl:DAO接口的真正实现类,完成数据库操作,但不负责数据库的打开和关闭;
·Proxy:代理实现类,主要完成数据库的打开和关闭,并且调用Impl类;
·Factory:工厂类,通过工厂类取得一个DAO的实例化对象;
·首先在WEB-INF\classes目录下创建VO类:
Emp.java:
package com.lid.vo;
import java.util.Date;
public class Emp{
private int empno;
private String ename;
private String job;
private Date hiredate;
private float sal;
public void setEmpno(int empno){
this.empno=empno;
}
public int getEmpno(){
return this.empno;
}
public void setEname(String ename){
this.ename=ename;
}
public String getEname(){
return this.ename;
}
public void setJob(String job){
this.job=job;
}
public String getJob(){
return this.job;
}
public void setHiredate(Date hiredate){
this.hiredate=hiredate;
}
public Date getHiredate(){
return this.hiredate;
}
public void setSal(float sal){
this.sal=sal;
}
public float getSal(){
return this.sal;
}
}
·数据库连接---DatabaseConnection:
package com.lid.dbc;
import java.sql.Connection;
import java.sql.DriverManager;
public class DatabaseConnection{
private static final String DBDRIVER="org.gjt.mm.mysql.Driver";
private static final String DBURL="jdbc:mysql://localhost:3306/lid";
private static final String DBUSERNAME="root";
private static final String DBPASSWORD="123";
private Connection conn=null;
public DatabaseConnection() throws Exception{
Class.forName(DBDRIVER);
this.conn=DriverManager.getConnection(DBURL,DBUSERNAME,DBPASSWORD);
}
public Connection getDatabaseConnection(){
return this.conn;
}
public void close() throws Exception{
if(this.conn!=null){
try{
this.conn.close();
}
catch(Exception e){
throw e;
}
}
}
}
·创建DAO接口----IEmpDAO:
本程序中只进行几个简单的操作;
package com.lid.dao;
import java.util.*;
import com.lid.vo.*;
public interface IEmpDAO{
//增加新纪录
public boolean doCreate(Emp emp) throws Exception;
//查询全部
public List<Emp> findAll(String keyWord) throws Exception;
//根据id查询
public Emp findById(int empno) throws Exception;
}
接口有了之后下面定义的就是实现类
·具体的实现类--EmpDAOImpl.java:
package com.lid.dao.Impl;
import java.sql.*;
import java.util.*;
import com.lid.dao.*;
import com.lid.vo.*;
public class EmpDAOImpl implements IEmpDAO{
private Connection conn;
private PreparedStatement pstmt;
public EmpDAOImpl(Connection conn){
this.conn=conn;
}
//增加新纪录
public boolean doCreate(Emp emp) throws Exception{
boolean flag=false;
String sql="insert into emp(empno,ename,job,hiredate,sal)
value(?,?,?,?,?)";
this.pstmt=this.conn.prepareStatement(sql);
this.pstmt.setInt(1,emp.getEmpno());
this.pstmt.setString(2,emp.getEname());
this.pstmt.setString(3,emp.getJob());
this.pstmt.setDate(4,new java.sql.Date(emp.getHiredate
().getTime()));
this.pstmt.setFloat(5,emp.getSal());
if(this.pstmt.executeUpdate()>0){
flag=true;
}
this.pstmt.close();
return flag;
}
//查询全部
public List<Emp> findAll(String keyWord) throws Exception{
List<Emp> all=new ArrayList<Emp>();
String sql="select empno,ename,job,hiredate,sal from emp
where ename like ? or job like ?";
this.pstmt=this.conn.prepareStatement(sql);
this.pstmt.setString(1,"%"+keyWord+"%");
this.pstmt.setString(2,"%"+keyWord+"%");
ResultSet rs=this.pstmt.executeQuery();
while(rs.next()){
Emp 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.getFloat(5));
all.add(emp);
}
this.pstmt.close();
return all;
}
//根据id查询
public Emp findById(int empno) throws Exception{
Emp emp=null;
String sql="select empno,ename,job,hiredate,sal from emp
where empno=?";this.pstmt=this.conn.prepareStatement(sql);
this.pstmt.setInt(1,empno);
ResultSet rs=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.getFloat(5));
}
this.pstmt.close();
return emp;
}
}
·代理类:---EmpDAOProxy.java:
完成数据库的打开与关闭并且调用实现类的方法;
package com.lid.dao.impl;
import java.sql.*;
import java.util.*;
import com.lid.dbc.*;
import com.lid.dao.*;
import com.lid.dao.impl.*;
import com.lid.vo.*;
public class EmpDAOProxy implements IEmpDAO{
private DatabaseConnection dbc=null;
private IEmpDAO dao=null;
public EmpDAOProxy() throws Exception{
this.dbc=new DatabaseConnection();
this.dao=new EmpDAOImpl
(this.dbc.getDatabaseConnection());
}
//增加新纪录
public boolean doCreate(Emp emp) throws Exception{
boolean flag=false;
try{
//要添加的数据在数库中不存在
if(this.dao.findById(emp.getEmpno
())==null){
flag=this.dao.doCreate(emp);
}
}
catch(Exception e){
throw e;
}
finally{
this.dbc.close();
}
return flag;
}
//查询全部
public List<Emp> findAll(String keyWord) throws Exception{
List<Emp> all=new ArrayList<Emp>();
try{
all=this.dao.findAll(keyWord);
}
catch(Exception e){
throw e;
}
finally{
this.dbc.close();
}
return all;
}
//根据id查询
public Emp findById(int empno) throws Exception{
Emp emp=new Emp();
try{
emp=this.dao.findById(empno);
}
catch(Exception e){
throw e;
}
finally{
this.dbc.close();
}
return emp;
}
}
·工厂:
得到接口的实现类的对象
package com.lid.factory;
import com.lid.dao.IEmpDAO;
import com.lid.dao.impl.EmpDAOProxy;
public class DAOFactory{
public static IEmpDAO getIEmpDAOInstance() throws Exception{
return new EmpDAOProxy();
}
}
下面做一个测试:
首先将驱动程序配置到classpath(类路径中);
创建一个TestDAOInsert.java:
package com.lid.dao.test;
import com.lid.factory.*;
import com.lid.vo.*;
public class TestDAOInsert{
public static void main(String args[]) throws Exception{
Emp emp=null;
for(int x=0;x<5;x++){
emp=new Emp();
emp.setEmpno(1000+x);
emp.setEname("yuj-"+x);
emp.setJob("程序员-"+x);
emp.setHiredate(new java.util.Date());
emp.setSal(500*x);
DAOFactory.getIEmpDAOInstance().doCreate(emp);
}
}
}
编译执行完后看数据库中是否添加成功;
创建一个TestDAOSelect.java:
package com.lid.dao.test;
import java.util.*;
import com.lid.factory.*;
import com.lid.vo.*;
public class TestDAOSelect{
public static void main(String args[]) throws Exception{
List<Emp> all =DAOFactory.getIEmpDAOInstance().findAll("yuj");
Iterator<Emp> iter =all.iterator();
while(iter.hasNext()){
Emp emp=iter.next();
System.out.println(emp.getEname());
}
}
}
编译执行完成后看看是否查到数据;
到此为止DAO全部完成,下面我们用jsp完成DAO的调用;
emp_insert.jsp:
<%@ page contentType="text/html" pageEncoding="gbk"%>
<html>
<head><title>这是测试</title></head>
<body>
<form action="emp_insert_do.jsp" method="post">
雇员编号:<input type="text" name="empno"><br>
雇员姓名:<input type="text" name="ename"><br>
雇员职位:<input type="text" name="job"><br>
雇佣日期:<input type="text" name="hiredate"><br>
基本工资:<input type="text" name="sal"><br>
<input type="submit" value="注册">
<input type="reset" value="重置">
</form>
<h3></h3>
</body>
</html>
emp_insert_do.jsp:
<%@ page contentType="text/html" pageEncoding="gbk"%>
<%@ page import="com.lid.factory.*"%>
<%@ page import="com.lid.vo.*"%>
<%@ page import="java.text.*"%>
<html>
<head><title>这是测试</title></head>
<body>
<%
request.setCharacterEncoding("gbk");
Emp emp=new Emp();
emp.setEmpno(Integer.parseInt(request.getParameter("empno")));
emp.setEname(request.getParameter("ename"));
emp.setJob(request.getParameter("job"));
//就是将String类型的时间转化成时间类型
emp.setHiredate(new SimpleDateFormat("yyyy-MM-dd").parse
(request.getParameter("hiredate")));
emp.setSal(Float.parseFloat(request.getParameter("sal")));
try{
if(DAOFactory.getIEmpDAOInstance().doCreate(emp)){
%>
<h3>雇员信息添加成功!</h3>
<%
}else{
%>
<h3>雇员信息添加失败!</h3>
<%
}
%>
<%
}catch(Exception e){
System.out.println(e);
}
%>
<h3></h3>
</body>
</html>
emp_list.jsp:
<%@ page contentType="text/html" pageEncoding="gbk"%>
<%@ page import="com.lid.factory.*"%>
<%@ page import="com.lid.vo.*"%>
<%@ page import="java.util.*"%>
<html>
<head><title>这是测试</title></head>
<body>
<%
request.setCharacterEncoding("gbk");
%>
<%
String keyWord=request.getParameter("kw");
if(keyWord==null){
keyWord="";
}
List<Emp> all= DAOFactory.getIEmpDAOInstance().findAll(keyWord);
Iterator<Emp> iter=all.iterator();
%>
<center>
<form action="emp_list.jsp" method="post">
请输入关键字:<input type="text" name="kw">
<input type="submit" value="查询">
</form>
<table border="1">
<tr>
<td>雇员编号</td>
<td>雇员姓名</td>
<td>雇员工作</td>
<td>雇佣日期</td>
<td>基本工资</td>
<%
while(iter.hasNext()){
Emp emp=iter.next();
%>
<tr>
<td><%=emp.getEmpno()%></td>
<td><%=emp.getEname()%></td>
<td><%=emp.getJob()%></td>
<td><%=emp.getHiredate()%></td>
<td><%=emp.getSal()%></td>
</tr>
<%
}
%>
</tr>
</table>
</center>
<h3></h3>
</body>
</html>
可以发现,使用JSP+DAO的开发之后,程序变得更加的清晰,而且以后所有的数据操作
可以任意的移植,不一定非要在jsp上使用了。
所以使用jsp+javabean的开发模式也称为 Model I,通过jsp显示,通过javabean完成功能,
达到显示和数据操作相分离;
Model 1:
jsp+JavaBean;
这样业务逻辑层就有jsp和javabean共同完成了;
jsp:完成显示,和业务逻辑
javabean:完成数据操作和业务逻辑;