DAO详解及小实例

DAO程序开发架构:

客户层(client)=》显示层(Jsp/Servlet)=》业务层(BO)=》数据层(DAO)=》资源层(DataBase)

在这里插入图片描述

1.在Java EE中实现DAO模式,主要分为6个模块,具体如下:

(1) 数据库连接类:专门负责数据库的打开与关闭操作

(2) VO类(value object值对象):主要由属性、setter、getter方法组成,VO类中的属性与表中的字段相对应,每一个VO类的对象都表示表中的每一条数据。实际上VO类就是一个JavaBean。

(3) DAO接口:主要定义操作的接口,定义一系列数据库的原子性操作标准,如增删改查(只不过是接口,定义的都是抽象方法。建议看看Java继承与接口,涉及到编写接口)

(4) Impl:DAO接口真实实现类:完成数据库的各项操作,但是不负责数据库的打开和关闭

(5) Proxy:DAO 代理实现类:主要完成数据库的打开和关闭,并且调用真实对象的操作

(6)Factory:DAO工厂类:通过工厂类取得一个DAO的实例化对象

  1. 对于包的命名:
    在使用DAO时对包有严格的命名
  • 数据库连接: xxx.dbc.DatabaseConnection
  • DAO接口: xxx.dao.IXxxDAO
  • DAO接口真实实现类:xxx.dao.impl.XxxDAOImpl
  • DAO接口代理实现类:xxx.dao.proxy.XxxDAOProxy
  • VO类: xxx.vo.Xxx, VO命名要与表的命名一致
  • 工厂类:xxx.factory.DAOFactory.
    在这里插入图片描述
    3.一个小实例
    步骤一:创建数据库,此处用的mysql数据库
/*======================= 删除数据库 =======================*/
DROP DATABASE IF EXISTS smile ;
/*======================= 创建数据库 =======================*/
CREATE DATABASE smile ;
/*======================= 使用数据库 =======================*/
USE smile ;
/*======================= 删除数据表 =======================*/
DROP TABLE IF EXISTS worker ;
/*======================= 创建数据表 =======================*/
CREATE TABLE worker(
   empno			INT(4)			PRIMARY KEY,
   ename			VARCHAR(10),
   job				VARCHAR(9),
   hiredate			DATE,
   sal				FLOAT(7,2)
) ;
/*======================= 插入测试数据 =======================*/
INSERT INTO worker(empno,ename,job,hiredate,sal) VALUES (7369,'董鸣楠','销售','2003-10-09',1500.90) ;
INSERT INTO worker(empno,ename,job,hiredate,sal) VALUES (8964,'李祺','分析员','2003-10-01',3000) ;
INSERT INTO worker(empno,ename,job,hiredate,sal) VALUES (7698,'张惠','销售','2005-03-12',800) ;
INSERT INTO worker(empno,ename,job,hiredate,sal) VALUES (7782,'杨军','分析员','2005-01-12',2500) ;
INSERT INTO worker(empno,ename,job,hiredate,sal) VALUES (7762,'刘明','销售','2005-03-09',1000) ;
INSERT INTO worker(empno,ename,job,hiredate,sal) VALUES (7839,'王月','经理','2006-09-01',2500) ;

创建成功后会有一个含有worker表的smile数据库
在这里插入图片描述
步骤二:定义VO类

package com.lqc.vo;

import java.util.Date;

public class Worker {
    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;
    }
}

步骤三:定义一个数据库连接类

package com.lqc.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseConnection {
    private static final String DBDRIVER="com.mysql.cj.jdbc.Driver";
    private static final String DBURL="jdbc:mysql://localhost:3306/smile?characterEncoding=utf8&serverTimezone=UTC";
    private static final String DBUSER="root";
    private static final String DBPASSWORD="123456";
    private Connection conn;
    public DatabaseConnection() throws Exception {
        //加载数据库驱动
        System.out.println("1");
        Class.forName(DBDRIVER);
        System.out.println("2");
        //进行数据库连接
        this.conn= DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD);
        System.out.println("数据库连接成功");
    }
    //取得数据库连接
    public Connection getConnection(){
        return conn;
    }
    //关闭数据库连接
    public void close() throws Exception {
        if(this.conn!=null){
            try {
                this.conn.close();
            } catch (SQLException e) {
                throw e;
            }
        }
    }
}

步骤四:新建DAO接口

package com.lqc.dao;

import com.lqc.vo.Worker;

import java.util.List;

public interface IWorkerDAO {
    public boolean doCreate(Worker worker) throws Exception;
    public List<Worker> findALL(String keyWord) throws Exception;
    public Worker findById(int empno) throws Exception;
}

在定义接口的时候,接口的前面加了一个I,这个是接口的命名规范,表示这是一个接口。
步骤五:DAO接口定义完成之后,就要写具体的实现类。分为2种,一种是真实实现类,还有一种是代理操作类。真实实现类负责数据库的具体操作,不包括数据库的打开与关闭;代理操作类真正负责的就是数据库的打开与关闭。
真实实现类

package com.lqc.dao.impl;

import com.lqc.dao.IWorkerDAO;
import com.lqc.vo.Worker;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class WorkerDAOImpl implements IWorkerDAO {
    private Connection conn =null;
    private PreparedStatement pstmt=null;
    //通过构造方法取得数据库连接
    public WorkerDAOImpl(Connection conn){
        this.conn=conn;
    }
    //数据增加操作
    @Override
    public boolean doCreate(Worker worker) throws Exception {
        boolean flag=false;
        //添加sql语句
        String sql="INSERT INTO worker(empno,ename,job,hiredate,sal) VALUES (?,?,?,?,?)";
        //实例化PrepareStatement对象
        this.pstmt=this.conn.prepareStatement(sql);
        this.pstmt.setInt(1, worker.getEmpno());
        this.pstmt.setString(2,worker.getEname());
        this.pstmt.setString(3,worker.getJob());
        this.pstmt.setString(4, String.valueOf(new Date(worker.getHiredate().getTime())));
        this.pstmt.setFloat(5,worker.getSal());
        if(this.pstmt.executeUpdate()>0){
            flag=true;
        }
        this.pstmt.close();
        return flag;
    }

    //查询操作
    @Override
    public List<Worker> findALL(String keyWord) throws Exception {
        //定义集合接受全部数据
        List<Worker> all=new ArrayList<Worker>();
        String sql="SELECT empno,ename,job,hiredate,sal FROM worker 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();
        Worker worker=null;
        //遍历集合取出每一条数据
        while(rs.next()){
            worker=new Worker();
            worker.setEmpno(rs.getInt(1));
            worker.setEname(rs.getString(2));
            worker.setJob(rs.getString(3));
            worker.setHiredate(rs.getDate(4));
            worker.setSal(rs.getFloat(5));
            all.add(worker);
        }
        this.pstmt.close();
        return all;
    }

    //根据编号查询操作
    @Override
    public Worker findById(int empno) throws Exception {
        Worker emp=null;
        String sql="SELECT empno,ename,job,hiredate,sal FROM worker WHERE empno=?";
        this.pstmt=this.conn.prepareStatement(sql);
        this.pstmt.setInt(1,empno);
        ResultSet rs=this.pstmt.executeQuery();
        if(rs.next()){
            emp=new Worker();
            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;
    }
}

代理操作类

package com.lqc.dao.proxy;

import com.lqc.dao.IWorkerDAO;
import com.lqc.dao.impl.WorkerDAOImpl;
import com.lqc.db.DatabaseConnection;
import com.lqc.vo.Worker;

import java.util.List;

public class WorkerDAOProxy implements IWorkerDAO {
    private DatabaseConnection db=null; //数据库连接对象
    private IWorkerDAO dao=null;        //DAO对象
    public WorkerDAOProxy() throws Exception {  //实例化数据库连接和DAO对象
        this.db=new DatabaseConnection();   //连接数据库
        this.dao=new WorkerDAOImpl(this.db.getConnection());    //实例化真实操作类对象
    }
    @Override
    public boolean doCreate(Worker worker) throws Exception {
        boolean flag=false;
        try{
            //如果要插入的雇员编号不存在
            if(this.dao.findById(worker.getEmpno())==null){
                //真实操作类调用
                flag=this.dao.doCreate(worker);
            }
        }catch (Exception e){
            throw e;
        }finally {
            this.db.close();
        }
        return flag;
    }

    @Override
    public List<Worker> findALL(String keyWord) throws Exception {
        List<Worker> all=null;
        try{
            all=this.dao.findALL(keyWord);
        }catch (Exception e){
            throw e;
        }finally {
            this.db.close();
        }
        return all;
    }

    @Override
    public Worker findById(int empno) throws Exception {
        Worker emp=null;
        try{
            emp=this.dao.findById(empno);
        }catch (Exception e){
            throw e;
        }finally {
            this.db.close();
        }
        return null;
    }
}

代理操作类中的方法是调用真实实现类中的相应方法。同时这个代理类也能够使代码开发结构更清晰。

步骤六:编写工厂类

package com.lqc.factory;

import com.lqc.dao.IWorkerDAO;
import com.lqc.dao.proxy.WorkerDAOProxy;

public class DAOFactory {
    public static IWorkerDAO getIWorkerDAOInstance() throws Exception {
        return new WorkerDAOProxy();
    }
}

这个类的功能就是直接返回DAO接口的实例化对象,也就是说在客户端直接通过工厂类就可以获取DAO接口的实例化对象。
接下来测试一下。
测试查询功能

package com.lqc.dao.test;

import com.lqc.factory.DAOFactory;
import com.lqc.vo.Worker;

import java.util.Iterator;
import java.util.List;

public class TestfindAll {
    public static void main(String args[]) throws Exception {
        List<Worker> all= DAOFactory.getIWorkerDAOInstance().findALL("");
        Iterator<Worker> iter=all.iterator();
        while(iter.hasNext()){
            Worker worker=iter.next();
            System.out.println(worker.getEmpno()+","+worker.getEname()+","+worker.getJob()+","+
                    worker.getHiredate()+","+worker.getSal());
        }
    }
}

在这里插入图片描述
接下来测试web程序的查询
编写work_list.jsp

<%--
  Created by IntelliJ IDEA.
  User: l1957
  Date: 2021/1/20
  Time: 11:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=GBK" language="java" pageEncoding="GBK" %>
<%@ page import="com.lqc.factory.*,com.lqc.vo.*"%>
<%@ page import="java.util.*"%>
<html>
<head>
    <title>work list</title>
</head>
<% request.setCharacterEncoding("GBK");%>
<body>
<%
    String keyWord=request.getParameter("kw");
    out.println(keyWord);
    if(keyWord==null){
        keyWord="";
    }
    List<Worker> all=DAOFactory.getIWorkerDAOInstance().findALL(keyWord);
    Iterator<Worker> iter=all.iterator();
%>
<center>
    <form action="work_list.jsp" 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()){
        Worker worker=iter.next();
%>
    <tr>
        <td><%=worker.getEmpno()%></td>
        <td><%=worker.getEname()%></td>
        <td><%=worker.getJob()%></td>
        <td><%=worker.getHiredate()%></td>
        <td><%=worker.getSal()%></td>
    </tr>

<%
    }
%>
    </table>
</center>
</body>
</html>

在这里插入图片描述
添加功能也可以自行测试
work_add.jsp

<%--
  Created by IntelliJ IDEA.
  User: l1957
  Date: 2021/1/20
  Time: 11:30
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=GBK" language="java" pageEncoding="GBK" %>
<html>
<head>
    <title>work add</title>
</head>
<% request.setCharacterEncoding("GBK");%>
<body>
<form action="work_add_do.jsp" method="post">&nbsp;&nbsp;&nbsp;&nbsp;号:<input type="text" name="empno"><br>&nbsp;&nbsp;&nbsp;&nbsp;名:<input type="text" name="ename"><br>&nbsp;&nbsp;&nbsp;&nbsp;位:<input type="text" name="job"><br>
    工作日期:<input type="text" name="hiredate"><br>&nbsp;&nbsp;&nbsp;&nbsp;资:<input type="text" name="sal"><br>
    <input type="submit" value="注册">
    <input type="reset" value="重置">
</form>
</body>
</html>

work_add_do.jsp

<%--
  Created by IntelliJ IDEA.
  User: l1957
  Date: 2021/1/20
  Time: 11:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=GBK" language="java" pageEncoding="GBK" %>
<%@ page import="com.lqc.factory.*,com.lqc.vo.*"%>
<%@ page import="java.text.*"%>
<html>
<head>
    <title>work add do</title>
</head>
<% request.setCharacterEncoding("GBK");%>
<body>
<%
        Worker worker=new Worker();
        worker.setEmpno(Integer.parseInt(request.getParameter("empno")));
        worker.setEname(request.getParameter("ename"));
        worker.setJob(request.getParameter("job"));
        worker.setHiredate(new SimpleDateFormat("yyyy-MM-dd").parse(request.getParameter("hiredate")));
        worker.setSal(Float.parseFloat(request.getParameter("sal")));
        try{
                if(DAOFactory.getIWorkerDAOInstance().doCreate(worker)){
%>
<h3>信息添加成功!</h3>
<%
}else{
%>
<h3>信息添加失败</h3>
<%       } %>
<%
        }catch(Exception e){
                e.printStackTrace();
        }
%>

</body>
</html>

摘自《java web从入门到项目实践》

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值