DAO设计模式简介(转)
http://blog.csdn.net/thystar/article/details/41786763
DAO(Data Access Object,数据访问对象),主要的功能是用于进行数据操作的,在程序的标准开发框架中属于数据层的操作。
数据开发结构:
资源层是数据库的操作层,里面可以进行各种数据库的存储,但是这些数据存储的时候肯定是依靠SQL语句,数据层通过一个专门的数据库组件完成对数据库的操作
业务层是整个项目的核心
DAO组成
DatabaseConnection:专门负责数据库打开与关闭操作的类
VO:主要由属性,setter, getter方法组成,VO类中的属性与表中的字段相对应,每一个VO类的对象都表示表中的每一条记录;
DAO:主要定义操作的接口,定义一系列数据库的原子性操作,例如增删改查等;
Impl: DAO接口的真实实现类,主要完成具体数据库操作,但不负责数据库的打开和关闭;
Proxy:代理实现类,主要完成数据库的打开和关闭并且调用真实实现类对象的操作;
Factory: 工厂类,通过工厂类取得一个DAO的实例化对象。
对于包的命名:
在使用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.
用DAO重新写登陆页面:
所需要的文件:这里直接使用MVC模式开发,使用myeclipse 10。
数据库脚本:
- /*=============删除数据库=============*/
- DROP DATABASE IF EXISTS usr;
- /*=============创建数据库=============*/
- CREATE DATABASE usr;
- /*=============使用数据库=============*/
- USE usr;
- /*=============删除数据库表===========*/
- DROP TABLE IF EXISTS login;
- /*=============创建数据库表===========*/
- CREATE TABLE login(
- userid VARCHAR(30) PRIMARY KEY,
- name VARCHAR(30) NOT NULL,
- password VARCHAR(32) NOT NULL
- );
- INSERT INTO login(userid, name, password)VALUES('admin', 'admin', 'admin');
1.定义vo类,vo类定义了数据的属性,及相应的setter,getter方法。
定义User类 :User.java -------- package org.thystar.mvcdemo.vo.User.
- /**
- * vo层
- */
- package org.thystar.mvcdemo.vo;
- /**
- *
- * 定义用户类
- */
- public class User {
- private String userid; //用户ID
- private String name; //用户名
- private String password; //密码
- public String getUserid() {
- return userid;
- }
- public void setUserid(String userid) {
- this.userid = userid;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- }
2. 定义数据库连接类,这个类只负责连接数据库:
定义DataBaseConnection类 DatabaseConnection.java ------------package org.thystar.mvcdemo.dbc.DatabaseConnection;
- package org.thystar.mvcdemo.dbc;
- import java.sql.*;
- /**
- *
- * 连接数据库
- *
- */
- public class DatabaseConnection {
- // 定义数据库驱动程序
- private static final String DBDRIVER = "org.gjt.mm.mysql.Driver";
- // 数据库连接地址
- private static final String DBURL = "jdbc:mysql://localhost:3306/usr";
- private static final String DBUSER = "root"; // 数据库连接用户名
- private static final String DBPASSWORD = "mysqladmin"; // 数据库连接密码
- private Connection conn = null; //声明数据库连接对象
- public DatabaseConnection() throws Exception{ //构造函数
- try{
- Class.forName(DBDRIVER); // 加载驱动程序
- this.conn = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD); // 取得数据库连接
- }catch(Exception e){
- throw e;
- }
- }
- public Connection getConnection() { //取得数据库连接
- return this.conn;
- }
- public void close() throws Exception { // 关闭数据库操作
- if(this.conn != null){ // 避免NullPointerException
- try{
- this.conn.close(); // 关闭数据库
- }catch(Exception e){
- throw e; // 抛出异常
- }
- }
- }
- }
3 . 定义数据库操作接口,定义数据库操作的方法:
定义IUserDAO接口,IUserDAO.java --------- package org.thystar.mvcdemo.dao.IUserDAO
- package org.thystar.mvcdemo.dao;
- // 在这个操作中要导入vo包。
- import org.thystar.mvcdemo.vo.*;
- /**
- *
- * 数据库操作接口
- *
- */
- public interface IUserDAO {
- /**
- * 用户登录验证
- * @param user 传入vo对象
- * @return 验证操作结果
- * @throws Exception
- */
- public boolean findLogin(User user) throws Exception;
- }
4. 定义DAO实现类,实现接口中定义的方法
定义UserDAOImpl类, UserDAOImpl.java ---------package org.thystar.mvcdemo.dao.impl.UserDAOImpl
- package org.thystar.mvcdemo.dao.impl;
- import java.sql.*;
- import org.thystar.mvcdemo.dao.IUserDAO;
- import org.thystar.mvcdemo.vo.User;
- /**
- *
- * DAO实现类,实现方法,但不负责数据库的具体连接
- *
- */
- public class UserDAOImpl implements IUserDAO{
- private Connection conn = null; //定义数据库的连接对象
- private PreparedStatement pstmt = null; //定义数据库操作对象
- public UserDAOImpl(Connection conn){ // 构造方法,设置数据库连接
- this.conn = conn;
- }
- /**
- * 具体操作方法:查询
- */
- public boolean findLogin(User user) throws Exception{
- boolean flag = false; //定义标志位
- try{
- String sql = "SELECT name FROM login WHERE userid = ? AND password = ?";
- this.pstmt = this.conn.prepareStatement(sql); // 实例化操作
- this.pstmt.setString(1, user.getUserid()); // 设置用户id
- this.pstmt.setString(2, user.getPassword()); // 设置password
- ResultSet rs = this.pstmt.executeQuery(); // 取得查询结果
- if(rs.next()){
- user.setName(rs.getString(1)); //取得姓名
- flag = true;
- }
- }catch(Exception e){
- throw e;
- }
- return flag;
- }
- }
可以看出,在真实的数据库的实现类中,没有处理数据库打开和关闭的操作,只是通过构造方法取得了数据库的连接,真正的负责打开和关闭的操作由代理类实现
5.代理(proxy)类实现:负责数据库的打开和关闭及调用真实实现类对象操作:
定义UserDAOProxy implements IUserDAO,UserDAOProxy.java ------------package org.thystar.mvcdemo.dao.proxy.UserDAOProxy
- package org.thystar.mvcdemo.dao.proxy;
- /**
- * 代理类,要找到真实主题
- */
- import org.thystar.mvcdemo.dao.IUserDAO;
- import org.thystar.mvcdemo.dbc.DatabaseConnection;
- import org.thystar.mvcdemo.dao.impl.UserDAOImpl;
- import org.thystar.mvcdemo.vo.User;
- public class UserDAOProxy implements IUserDAO {
- private DatabaseConnection dbc = null;
- private IUserDAO dao = null;
- public UserDAOProxy() { //构造方法,实例化连接,同时实例化dao对象
- try {
- this.dbc = new DatabaseConnection(); // 连接数据库
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- this.dao = new UserDAOImpl(this.dbc.getConnection()); //实例化真实主题类
- }
- public boolean findLogin(User user) throws Exception{ // 实现接口中的方法。
- boolean flag = false; //定义标志位
- try{
- flag = this.dao.findLogin(user); // 调用真实主题
- }catch(Exception e){
- throw e; //向上抛出异常
- }finally{
- this.dbc.close();
- }
- return flag; //返回标记
- }
- }
6. 工厂类的实现: 取得DAO实例
定义DAOFactory类, DAOFactory.java --------------package org.thystar.mvcdemo.factory.DAOFactory
- package org.thystar.mvcdemo.factory;
- import org.thystar.mvcdemo.dao.IUserDAO;
- import org.thystar.mvcdemo.dao.proxy.UserDAOProxy;
- /**
- *
- * 工长类
- *
- */
- public class DAOFactory {
- public static IUserDAO getIUserDAOInstance(){ // 取得DAO实例
- return new UserDAOProxy(); // 返回代理实例
- }
- }
工厂类的功能就是直接返回DAO接口的实例化对象,以后客户端直接通过工厂类就可以取得DAO接口的实例化对象
到这里,数据层的部分就完成了,下面开始定义Servlet/jsp部分,也就是显示层,进行页面的显示
7 .定义Servlet:
LoginServlet.java
- /**
- * 定义Servlet
- */
- package org.thystar.mvcdemo.servlet;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.List;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.thystar.mvcdemo.factory.DAOFactory;
- import org.thystar.mvcdemo.vo.User;
- public class LoginServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- /**
- * The doGet method of the servlet. <br>
- *
- * This method is called when a form has its tag value method equals to get.
- *
- * @param request the request send by the client to the server
- * @param response the response send by the server to the client
- * @throws ServletException if an error occurred
- * @throws IOException if an error occurred
- */
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- String path = "login.jsp";
- String userid = request.getParameter("userid"); //接收userid的内容
- String userpass = request.getParameter("userpass"); //接收userpass的内容
- List<String> info = new ArrayList<String>(); // 保存返回信息
- //判断输入为空的情况
- if(userid == null || "".equals(userid)){
- info.add("用户id不能为空");
- }
- if(userpass == null || "".equals(userpass)){
- info.add("密码不能为空");
- }
- //用户名密码验证通过
- if(info.size() == 0){
- User user = new User(); //实例化vo
- user.setUserid(userid); //设置userid
- user.setPassword(userpass); //设置userpass
- try {
- if(DAOFactory.getIUserDAOInstance().findLogin(user)){ //验证通过
- info.add("通过验证" + user.getName() + "已登录");
- }else{
- info.add("登录失败");
- }
- } catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- }
- }
- request.setAttribute("info", info);
- request.getRequestDispatcher(path).forward(request, response); //跳转
- }
- /**
- * The doPost method of the servlet. <br>
- *
- * This method is called when a form has its tag value method equals to post.
- *
- * @param request the request send by the client to the server
- * @param response the response send by the server to the client
- * @throws ServletException if an error occurred
- * @throws IOException if an error occurred
- */
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- this.doGet(request, response); // 调用doGet操作
- }
- }
8. 登陆页
login.jsp
- <%@ page contentType = "text/html" pageEncoding="GBK" import = "java.util.*"%>
- <html>
- <head>
- <title>www.thystar.com</title>
- <script language = "JavaScript">
- function validate(f){
- if(!(/^\w{1,15}$/.test(f.userid.value))){
- alert("用户ID必须是1~15位");
- f.userid.focus();
- return false;
- }
- if(!(/^\w{1,15}$/.test(f.userpass.value))){
- alert("密码必须是1~15位");
- f.userpass.focus();
- return false;
- }
- return true;
- }
- </script>
- </head>
- <body>
- <h2>用户登录</h2>
- <%
- request.setCharacterEncoding("GBK");
- %>
- <%
- List<String> info=(List<String>)request.getAttribute("info");
- if(info != null){
- Iterator<String> iter = info.iterator();
- while(iter.hasNext()){
- %>
- <h4><%= iter.next() %></h4>
- <%
- }
- }
- %>
- <form action="LoginServlet" method="post" onSubmit = "validate(this)">
- 用户ID: <input type = "text" name = "userid"><br>
- 密 码:<input type = "password" name="userpass"><br>
- <input type = "submit" value = "登录">
- <input type = "reset" value = "重置">
- </form>
- </body>
- </html>
结果: