DAO(数据访问对象)
程序的标准架构为:
客户层(Client)-> 显示层(jsp/servlet)-> 业务层(BO) -> 数据层(BAO) -> 资源层(DataBase)
项目Gitee地址:https://gitee.com/hcflyambation/daoproject
1,组成部分(Java命名规范)
- 1,DatabaseConnection: 专门负责数据库打开和关闭操作的类;(xxx.dbc.DatabaseConnection)
- 2,VO:主要由属性、setter、geter组成,VO类中的属性与表中的字段相对应。(xxx.vo.Xxx)
- 3,DAO: 主要定义操作的接口,定义一系列的数据库的原子性操作,如,增删改查。(xxx.dao.XxxDAO)
- 4,Impl:DAO接口的真实实现类,完成具体的数据库操作,但是不负责数据库的打开和关闭。(xxx.dao.impl.XxxDAOImpl)
- 5,Proxy:代理实现类,主要完成数据库的打开和关闭,并且调用真实实现类对象的操作。(xxx.dao.proxy.XxxDAOProxy)
- 6,Factory:工厂类,通过工厂类获得一个DAO的实例化对象。(xxx.factory.DAOFactory)
2,DAO的实例开发
项目结构:

特别要注意的是:当启动web程序时,请将依赖的jar(postgresql-42.2.19.jar放入WEB-INF/lib/下,不然会检测不到)
JAR必须直接放在web项目的/ WEB-INF / lib文件夹中,而不用项目属性中的Build Path.该文件夹是webapp运行时类路径的标准部分
2.1,数据库脚本建立(使用PostgreSQL)
数据库名为:jsp
create table emp ( empno int primary key, ename varchar(10), job varchar(9), hiredate date, sal decimal);
2.2,编写与数据库对应的OV类(Emp.java)
package com.hcfly.vo;import java.math.BigDecimal;import java.util.Date;public class Emp { private int empno; private String ename; private String job; private Date hiredate; private float sal; public int getEmpno() { return empno; } public void setEmpno(int empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public Date getHiredate() { return hiredate; } public void setHiredate(Date hiredate) { this.hiredate = hiredate; } public float getSal() { return sal; } public void setSal(float sal) { this.sal = sal; }}
2.3, 编写数据库连接类(DatabaseConnection.java)
这个地方可以将DatabaseConnection抽象为一个接口,并且用不同的数据库访问类去实现它,来达到通用的水平。
package com.hcfly.dbc;import java.sql.Connection;import java.sql.DriverManager;public class DatabaseConnection { // 数据库连接类 private static final String DBDRIVER = "org.postgresql.Driver"; private static final String DBURL = "jdbc:postgresql://localhost/jsp"; private static final String DBUSER = "postgres"; private static final String DBPASSWORD = "miaomiao"; private Connection connection = null; public DatabaseConnection() throws Exception{ try { Class.forName(DBDRIVER); this.connection = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD);// System.out.println("连接成功"); } catch (Exception e) { throw e; // TODO: handle exception } } public Connection getConnection() { return this.connection; } public void close() throws Exception { if(this.connection != null) { try { this.connection.close(); } catch (Exception e) { throw e; // TODO: handle exception } } }}
2.4,定义DAO操作标准(IEmpDAO.java)
package com.hcfly.dao;import java.util.List;import com.hcfly.vo.Emp;public interface IEmpDAO { // 定义DAO操作 /** * 定义DAO的标准操作 * */ public boolean doCreate(Emp emp) throws Exception; /** * @param emp要增加的数据对象 */ public List<Emp> findAll(String keyWord) throws Exception; /** * 根据查询关键字进行搜索 */ public Emp findById(int empno) throws Exception;}
2.5,真实主题实现类(EmpDAOImpl.java)
package com.hcfly.dao.impl;import java.sql.Connection;import java.sql.Date;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.ArrayList;import java.util.List;import com.hcfly.dao.IEmpDAO;import com.hcfly.vo.Emp;public class EmpDAOImpl implements IEmpDAO{ /** * 真实主题类 */ private Connection connection = null; private PreparedStatement pstmt = null; public EmpDAOImpl(Connection connection) { // 获取数据库连接 this.connection = connection; } @Override public boolean doCreate(Emp emp) throws Exception { boolean flag = false; String sql = "INSERT INTO emp (empno, ename, job, hiredate, sal) VALUES (?,?,?,?,?)"; this.pstmt = this.connection.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 Date(emp.getHiredate().getTime())); this.pstmt.setFloat(5, emp.getSal()); if(this.pstmt.executeUpdate() > 0) { // 更新记录行数大于1 flag = true; } this.pstmt.close(); return flag; } @Override 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.connection.prepareStatement(sql); this.pstmt.setString(1, "%"+keyWord +"%"); this.pstmt.setString(2, "%"+keyWord +"%"); ResultSet rSet = this.pstmt.executeQuery(); Emp emp = null; while (rSet.next()) { emp = new Emp(); emp.setEmpno(rSet.getInt("empno")); emp.setEname(rSet.getString("ename")); emp.setHiredate(rSet.getDate("hiredate")); emp.setJob(rSet.getString("job")); emp.setSal(rSet.getFloat("sal")); all.add(emp); } this.pstmt.close(); // TODO Auto-generated method stub return all; } @Override public Emp findById(int empno) throws Exception { String sql = "SELECT empno, ename, job, hiredate, sal FROM emp WHERE empno=?"; this.pstmt = this.connection.prepareStatement(sql); this.pstmt.setInt(1, empno); ResultSet rSet = this.pstmt.executeQuery(); Emp emp = null; if(rSet.next()) { emp = new Emp(); emp.setEmpno(rSet.getInt("empno")); emp.setEname(rSet.getString("ename")); emp.setHiredate(rSet.getDate("hiredate")); emp.setJob(rSet.getString("job")); emp.setSal(rSet.getFloat("sal")); } this.pstmt.close(); // TODO Auto-generated method stub return emp; }}
2.5,代理主题实现类(IEmpDAOProxy.java)
package com.hcfly.dao.proxy;import java.util.List;import com.hcfly.dao.IEmpDAO;import com.hcfly.dao.impl.EmpDAOImpl;import com.hcfly.dbc.DatabaseConnection;import com.hcfly.vo.Emp;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.getConnection()); } @Override 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(); // 无论是否成功,将连接关闭 } // TODO Auto-generated method stub return flag; } @Override public List<Emp> findAll(String keyWord) throws Exception { List<Emp> all = null; try { all = this.dao.findAll(keyWord); } catch (Exception e) { throw e; } finally { this.dbc.close(); } return all; } @Override public Emp findById(int empno) throws Exception { Emp emp = null; try { emp = this.dao.findById(empno); } catch (Exception e) { throw e; }finally { this.dbc.close(); } return emp; }}
2.6,DAO工厂类(DAOFactory.java)
package com.hcfly.factory;import com.hcfly.dao.IEmpDAO;import com.hcfly.dao.proxy.EmpDAOProxy;public class DAOFactory { /** * 工厂类 * @return * @throws Exception */ public static IEmpDAO getIEmpDAOInstance() throws Exception{ return new EmpDAOProxy(); }}
2.7,测试类(TestDAOInsert.java)
package com.hcfly.dao.test;import java.util.Date;import com.hcfly.factory.DAOFactory;import com.hcfly.vo.Emp;public class TestDAOInsert { public static void main(String[] args) throws Exception{ // TODO Auto-generated method stub Emp emp = null; for(int x = 0; x < 5; x++) { emp = new Emp(); emp.setEmpno(1000+x); emp.setEname("张憨憨" + x); emp.setJob("程序员 - " + x); emp.setHiredate(new Date()); emp.setSal(500 * x);// DAOFactory.getIEmpDAOInstance().doCreate(emp); } System.out.println(DAOFactory.getIEmpDAOInstance().findById(1001)); }}
2.8,总结
DAO 只是提供了一个数据的操作平台,不管在Application还是Web程序中,此DAO程序都不用做修改。
3,DAO的web使用实例(开发工具为Ecplise,如果要运行,请先配置数据库)
从注册页面提交信息给数据库,然后读出来,展示到表格中。
3.1, 登录注册页面(增加数据表单)(emp_insert.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>注册</title></head><body> <form action="emp_insert_do.jsp" method="post" > 雇员编号:<input type="text" name="empno" id=""><br/> 雇员姓名:<input type="text" name="ename" id=""><br/> 雇员职位:<input type="text" name="job" id=""><br/> 雇员日期:<input type="text" name="hiredate" id=""><br/> 雇员工资:<input type="text" name="sal" id=""><br/> <input type="submit" value="注册"> <input type="reset" value="重置"> </form> <a href="emp_list.jsp">跳转到列表页面</a></body></html>
3.2, 处理数据页面(emp_insert_do.jsp)
<%@page import="com.hcfly.factory.DAOFactory"%><%@page import="java.text.SimpleDateFormat"%><%@page import="com.hcfly.vo.Emp"%><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>处理表单</title><%request.setCharacterEncoding("utf-8"); response.setHeader("refresh", "3;URL=emp_list.jsp"); // 设置跳转时间为3秒%></head><body><%Emp emp = new Emp();emp.setEmpno(Integer.parseInt(request.getParameter("empno")));emp.setEname(request.getParameter("ename"));emp.setJob(request.getParameter("job"));emp.setHiredate(new SimpleDateFormat("yyyy-MM-dd").parse(request.getParameter("hiredate")));emp.setSal(Float.parseFloat(request.getParameter("sal")));try{ if(DAOFactory.getIEmpDAOInstance().doCreate(emp)){ out.print("<h3>雇员信息添加成功!</h3>"); }else{ out.print("<h3>雇员信息添加失败!</h3>"); }}catch(Exception e){ e.printStackTrace();}%><h3>3秒后跳转到列表页</h3></body></html>
3.3,列表页面(emp_list.jsp)
<%@page import="com.hcfly.vo.Emp"%><%@page import="java.util.List"%><%@page import="org.apache.jasper.tagplugins.jstl.core.Catch"%><%@page import="java.util.Iterator"%><%@page import="com.hcfly.factory.DAOFactory"%><%@page import="java.util.Dictionary"%><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>列表</title><% request.setCharacterEncoding("utf-8"); %></head><body><% try{ String keyWord = request.getParameter("kw"); if(keyWord == null){ keyWord = ""; } List<Emp> all = DAOFactory.getIEmpDAOInstance().findAll(keyWord); Iterator<Emp> iter = all.iterator(); %><center> <form action="" method="post"> <input type="text" name="kw"> <input type="submit" value="查询"> </form> <table border="1" width="80%"> <tr> <td>雇员编号:</td> <td>雇员姓名:</td> <td>雇员工作:</td> <td>雇员工资:</td> <td>雇员日期:</td> </tr> <% while(iter.hasNext()){ Emp emp = iter.next(); %> <tr> <td><%= emp.getEmpno() %></td> <td><%= emp.getEname() %></td> <td><%= emp.getJob() %></td> <td><%= emp.getSal() %></td> <td><%= emp.getHiredate() %></td> </tr> <% } %> </table> <a href="emp_insert.jsp">跳转到插入页面</a> </center> <% }catch(Exception e){ e.printStackTrace(); } %></body></html>
3.4,结果展示
3.4.1 数据库

3.4.2,注册界面

3.4.3,列表页面
