热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaDAO模式详解与代码示例

DAO(DataAccessObject)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。

DAO(Data Access Object)模式是一种设计模式,用于抽象和封装所有对数据库或其他持久化机制访问的方法。它通过提供一个统一的接口来隐藏底层数据访问的复杂性,使得应用程序的其他部分无需关心数据访问的具体实现。

在实际开发中,DAO模式通常包含以下几个核心组件:

  • VO(Value Object):用于封装从数据库中读取的数据,例如用户信息。
  • DatabaseConnection:用于管理数据库连接的打开和关闭。
  • DAO接口:定义了对数据库操作的方法。
  • DAO实现类:实现了DAO接口中的方法,具体执行数据库操作。
  • DAO代理类:通过代理模式来管理数据库连接的打开和关闭。
  • DAO工厂类:用于创建DAO实例。

一、信息系统开发架构

一个典型的信息系统开发架构可以分为以下几个层次:

  • 客户端层:用户界面,通常是浏览器。
  • 显示层:用于展示数据,通常是JSP或Servlet。
  • 业务层:处理业务逻辑,调用数据层的方法。
  • 数据层:执行具体的数据库操作,如增删改查。
  • 数据库层:存储数据的实际数据库。

二、DAO模式的结构

DAO模式主要由以下几个部分组成:

  • VO(Value Object):用于封装从数据库中读取的数据,例如用户信息。
  • DatabaseConnection:用于管理数据库连接的打开和关闭。
  • DAO接口:定义了对数据库操作的方法。
  • DAO实现类:实现了DAO接口中的方法,具体执行数据库操作。
  • DAO代理类:通过代理模式来管理数据库连接的打开和关闭。
  • DAO工厂类:用于创建DAO实例。

三、DAO模式的好处

DAO模式的主要好处包括:

  • 分离关注点:将数据访问逻辑与业务逻辑分离,提高了代码的可维护性和可测试性。
  • 提高灵活性:可以通过修改DAO实现类来改变数据访问的方式,而无需修改业务逻辑。
  • 降低耦合度:通过接口定义数据访问方法,降低了业务逻辑与数据访问之间的耦合度。

四、DAO包命名规范

为了保持代码的清晰和可维护性,DAO相关的包和类命名应遵循一定的规范:

  • VO类:通常放在`org.vo`包下,例如`Emp.java`。
  • DatabaseConnection类:通常放在`org.dbc`包下,例如`DatabaseConnection.java`。
  • DAO接口和实现类:通常放在`org.dao`和`org.dao.impl`包下,例如`IEmpDAO.java`和`EmpDAOImpl.java`。
  • DAO代理类和工厂类:通常放在`org.dao.impl`和`org.dao.factory`包下,例如`EmpDAOProxy.java`和`DAOFactory.java`。

以下是具体的代码示例:

1. VO类 - `Emp.java`

package org.vo;

import java.util.Date;

public class Emp {
    private int empno;
    private String ename;
    private String job;
    private Date hireDate;
    private float sal;

    public Emp() {}

    // Getters and Setters
    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. 数据库连接管理类 - `DatabaseConnection.java`

package org.dbc;

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

public class DatabaseConnection {
    private Connection con = null;
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String USER = "root";
    private static final String URL = "jdbc:mysql://localhost:3306/mldn";
    private static final String PASS = "12345";

    public DatabaseConnection() throws SQLException, ClassNotFoundException {
        Class.forName(DRIVER);
        con = DriverManager.getConnection(URL, USER, PASS);
    }

    public Connection getConnection() throws SQLException {
        return con;
    }

    public void close() throws SQLException {
        if (con != null) {
            con.close();
        }
    }
}

3. DAO接口 - `IEmpDAO.java`

package org.dao;

import java.util.List;
import org.vo.Emp;

public interface IEmpDAO {
    boolean doCreate(Emp emp) throws Exception;
    List findAll() throws Exception;
    Emp findById(int empno) throws Exception;
}

4. DAO实现类 - `EmpDAOImpl.java`

package org.dao.impl;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.dao.IEmpDAO;
import org.vo.Emp;

public class EmpDAOImpl implements IEmpDAO {
    private Connection con;
    private PreparedStatement stat = null;

    public EmpDAOImpl(Connection con) {
        this.con = con;
    }

    @Override
    public boolean doCreate(Emp emp) throws SQLException {
        String sql = "INSERT INTO emp(empno, ename, job, hiredate, sal) VALUES(?, ?, ?, ?, ?)";
        stat = con.prepareStatement(sql);
        stat.setInt(1, emp.getEmpno());
        stat.setString(2, emp.getEname());
        stat.setString(3, emp.getJob());
        stat.setDate(4, new java.sql.Date(emp.getHireDate().getTime()));
        stat.setFloat(5, emp.getSal());
        int update = stat.executeUpdate();
        return update > 0;
    }

    @Override
    public List findAll() throws SQLException {
        String sql = "SELECT * FROM emp";
        stat = con.prepareStatement(sql);
        ResultSet rs = stat.executeQuery();
        List list = new ArrayList<>();
        while (rs.next()) {
            Emp emp = new Emp();
            emp.setEmpno(rs.getInt("empno"));
            emp.setEname(rs.getString("ename"));
            emp.setJob(rs.getString("job"));
            emp.setHireDate(rs.getDate("hiredate"));
            emp.setSal(rs.getFloat("sal"));
            list.add(emp);
        }
        return list;
    }

    @Override
    public Emp findById(int empno) throws SQLException {
        String sql = "SELECT * FROM emp WHERE empno=?";
        stat = con.prepareStatement(sql);
        stat.setInt(1, empno);
        ResultSet rs = stat.executeQuery();
        if (rs.next()) {
            Emp emp = new Emp();
            emp.setEmpno(rs.getInt("empno"));
            emp.setEname(rs.getString("ename"));
            emp.setJob(rs.getString("job"));
            emp.setHireDate(rs.getDate("hiredate"));
            emp.setSal(rs.getFloat("sal"));
            return emp;
        }
        return null;
    }
}

5. DAO代理类 - `EmpDAOProxy.java`

package org.dao.impl;

import java.sql.SQLException;

import org.dao.IEmpDAO;
import org.dbc.DatabaseConnection;
import org.vo.Emp;

public class EmpDAOProxy implements IEmpDAO {
    private DatabaseConnection dbc;
    private IEmpDAO dao = null;

    public EmpDAOProxy() throws SQLException, ClassNotFoundException {
        dbc = new DatabaseConnection();
        dao = new EmpDAOImpl(dbc.getConnection());
    }

    @Override
    public boolean doCreate(Emp emp) throws SQLException {
        boolean flag = false;
        if (dao.findById(emp.getEmpno()) == null) {
            flag = dao.doCreate(emp);
        }
        dbc.close();
        return flag;
    }

    @Override
    public List findAll() throws SQLException {
        List list = dao.findAll();
        dbc.close();
        return list;
    }

    @Override
    public Emp findById(int empno) throws SQLException {
        Emp emp = dao.findById(empno);
        dbc.close();
        return emp;
    }
}

6. DAO工厂类 - `DAOFactory.java`

package org.dao.factory;

import org.dao.IEmpDAO;
import org.dao.impl.EmpDAOProxy;

public class DAOFactory {
    public static IEmpDAO getInstance() {
        IEmpDAO dao = null;
        try {
            dao = new EmpDAOProxy();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dao;
    }
}

7. 测试类 - `TestDAO.java`

package org.dao.test;

import java.sql.SQLException;
import org.dao.IEmpDAO;
import org.dao.factory.DAOFactory;
import org.vo.Emp;

public class TestDAO {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        for (int i = 0; i <5; i++) {
            Emp emp = new Emp();
            emp.setEmpno(i);
            emp.setEname("xiazdong-" + i);
            emp.setJob("stu-" + i);
            emp.setHireDate(new java.util.Date());
            emp.setSal(500 * i);
            DAOFactory.getInstance().doCreate(emp);
        }
    }
}

通过使用DAO设计模式,可以在JSP中屏蔽数据库连接的操作,使JSP仅负责显示数据,从而提高代码的可维护性和可扩展性。


推荐阅读
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Java 中 Writer flush()方法,示例 ... [详细]
  • Java 类成员初始化顺序与数组创建
    本文探讨了Java中类成员的初始化顺序、静态引入、可变参数以及finalize方法的应用。通过具体的代码示例,详细解释了这些概念及其在实际编程中的使用。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 探讨如何通过编程技术实现100个并发连接,解决线程创建顺序问题,并提供高效的并发测试方案。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文介绍了如何使用 Spring Boot DevTools 实现应用程序在开发过程中自动重启。这一特性显著提高了开发效率,特别是在集成开发环境(IDE)中工作时,能够提供快速的反馈循环。默认情况下,DevTools 会监控类路径上的文件变化,并根据需要触发应用重启。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
author-avatar
郁雯佩菱2
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有