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仅负责显示数据,从而提高代码的可维护性和可扩展性。