一、前言

   这个DAO设计模式,其实之前用过好多次了,但某些概念还是有的迷糊,故整理如下

二、DAO设计模式

2.1、DAO设计模式中概念

  • DAO 属于 J2EE 数据层的操作  即  在 DAO 中封装了一个表在一个项目中所应该具有的全部操作
  • J2EE 的组件层次 : 客户端   》 表示层  》  业务层 》   数据层 (数据库中的表)
  • DAO对应J2EE的组件层次的数据层,DAO规定的是一个接口,在这个里面定义整个模块对表的操作   如:
  1. 增加 
  2. 修改 
  3. 删除 
  4. 按 ID 查询 
  5. 查询全部 
  6. 模糊查询 

2.2、几个名词释义

1.O/R Mapping :即Object Relational Mapping(对象关系映射)的缩写。

 解释:对象与关系数据库绑定,用对象来表示关系据。

2.VO:     即      值对象(Value Object)

解释:确切的来说VO是业务对象,如果说业务逻辑处理类是它工作的地方,那么实体类则是它的家。

3.PO:     即     持久对象(Persisent Object)

解释:向数据库中添加新数据时创建,删除数据库中数据时削除的。它只能存活在一个数据库连接中,断开连接即被销毁。

4.POJO: 即    简单java对象(plain ordinary java object )

解释:在Object/RelationMapping(对象关系型映射)工具中,能够做到维护数据库表记录的持久对象(PO);中间对象,POJO经持久化或就是PO

5.TO:      即    传输对象(Transfer Object)

解释:在项目的不同层之间传输的对象

6.DAO    即     数据访问对象(data access object) 

解释:一个接口,定义对表中数据的操作方式

7.DTO:    即:数据传输对象(Data Transfer Object)

8.BO:      即   业务对象(business object)

2.3、举例

   比如说用户登录在登录之前必须要注册,这样才可以实现登录

  •  插入  》针对对象的插入
  •  对象  》VO,TO,POJO(值对象,传输对象,简单java对象(最根本的Java对象))  即:只包含属性和setter、getter的方法类
  •  客户 》 VO 》DAO     VO的对象与表中字段对应 
  • 定义接口后,要定义实现该接口的实现类,实现类要实现接口中对数据库的所有操作
  • 定义一个数据库连接类工具类,由数据库连接类工具类,统一管理数据库连接 
  • 查询全部的操作返回值是 List,所以需要使用 Iterator 进行输出 
  • 使用 DAO 之后,前台调用代码减少很多,但可以发现类增加了 
  • 可以发现以下的一个重要问题: 
  • PersonDAO dao = new PersonDAOImpl() ;接口直接通过其子类实例化,直接的影响就是程序在调用时必须知道具体的子类,这样会造成修改不方便 所以,必须使用工厂设计,使前台不关注于具体子类是谁 
  • DAO 整体设计,是采用以下模式: 
  • 调用处 》 DAO 工厂 》 具体子类实现 》 完成数据库操作 
  • |-----------------|------------- VO ----------| 
  • 直接的好处:前台显示与后台逻辑操作分离 

三、案例巩固

3.1、实体类 VO对象

package cn.itcase.vo;

public class Admin {
	private String id ;
	private String name ;
	private String password ;
	private int age ;
	private String email ;
	// 	// VO值对象    包括get和set方法
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	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;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	
}

3.2 接口的定义

package cn.itcase.dao;

import java.util.List;

import cn.itcase.vo.Admin;

//规定出了操作admin表在此项目里的全部方法
public interface AdminDao {
	// 增加操作
	public void insert(Admin aadmin) throws Exception;

	// 修改操作
	public void update(Admin aadmin) throws Exception;

	// 删除操作
	public void delete(String id) throws Exception;

	// 按ID查询操作
	public Admin queryById(String id) throws Exception;

	// 查询全部
	public List<Admin> queryAll() throws Exception;

	// 模糊查询
	public List<Admin> queryByLike(String cond) throws Exception;
}

3.3、接口实现类的定义

package cn.itcase.dao.impl;

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

import cn.itcase.dao.AdminDao;
import cn.itcase.jdbcutils.JdbcUtils;
import cn.itcase.vo.Admin;

public class AdminDaoImpl implements AdminDao {
	// 全局变量初始化
	PreparedStatement pstmt = null; // 预编译对象
	Connection conn = null; // 连接对象
	ResultSet rs = null; // 结果集对象

	// 增加操作
	@Override
	public void insert(Admin admin) throws Exception {
		try {
			// 0.需要操作的sql
			String sql = "insert into admin(id,name,password,age,email) values(?,?,?,?,?);";
			// 1.使用工具类连接数据库
			conn = JdbcUtils.getConnection();
			// 2.预编译sql
			pstmt = conn.prepareStatement(sql);
			// 3.设置参数
			pstmt.setString(1, admin.getId());
			pstmt.setString(2, admin.getName());
			pstmt.setString(3, admin.getPassword());
			pstmt.setInt(4, admin.getAge());
			pstmt.setString(5, admin.getEmail());
			// 4.执行相应操作并返回结果
			int result = pstmt.executeUpdate();
			System.out.println("影响了:" + result + "记录");
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			JdbcUtils.closeAll(conn, pstmt, null); // 关闭对象
		}
	}

	// 修改操作
	@Override
	public void update(Admin admin) throws Exception {
		try {
			// 0.需要操作的sql
			String sql = "UPDATE admin SET name=?,password=?,age=?,email=? WHERE id=?";
			// 1.使用工具类连接数据库
			conn = JdbcUtils.getConnection();
			// 2.预编译sql
			pstmt = conn.prepareStatement(sql);
			// 3.设置参数
			pstmt.setString(1, admin.getName());
			pstmt.setString(2, admin.getPassword());
			pstmt.setInt(3, admin.getAge());
			pstmt.setString(4, admin.getEmail());
			pstmt.setString(5, admin.getId());
			// 4.执行相应操作并返回结果
			int result = pstmt.executeUpdate();
			System.out.println("影响了" + result + "记录");

		} catch (Exception e) {
			throw new RuntimeException(e);
			// 5.关闭数据库连接对象
		} finally {
			JdbcUtils.closeAll(conn, pstmt, null); // 关闭对象
		}
	}

	// 删除操作
	@Override
	public void delete(String id) throws Exception {
		try {
			// 0.需要执行的sql语句
			String sql = "DELETE FROM admin WHERE id=?";

			// 1.使用工具类连接数据库
			conn = JdbcUtils.getConnection();
			// 2.预编译sql
			pstmt = conn.prepareStatement(sql);
			// 3.设置参数
			pstmt.setString(1, id);
			// 4.执行相应操作并返回结果
			int result = pstmt.executeUpdate();
			System.out.println("影响了" + result + "记录");

		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			// 5.关闭数据库连接对象
			JdbcUtils.closeAll(conn, pstmt, null);
		}
	}

	// 按ID查询操作
	@Override
	public Admin queryById(String id) throws Exception {
		Admin admin = null;
		try {
			// 0.需要执行的sql操作
			String sql = "SELECT id,name,password,age,email FROM admin WHERE id=?";
			// 1.使用工具类连接数据库
			conn = JdbcUtils.getConnection();
			// 2.预编译sql
			pstmt = conn.prepareStatement(sql);
			// 3.设置参数
			pstmt.setString(1, id);
			// 4.执行相应操作并返回结果
			rs = pstmt.executeQuery();
			System.out.println(rs);
			// 创建list 并遍历list
			// List<Admin> list = new ArrayList<Admin>();
			if (rs.next()) {
				// 查询出内容,之后将查询出的内容赋值给admin对象
				admin = new Admin();
				admin.setId(rs.getString(1));
				admin.setName(rs.getString(2));
				admin.setPassword(rs.getString(3));
				admin.setAge(rs.getInt(4));
				admin.setEmail(rs.getString(5));
				// list.add(admin);
			}

		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			// 5.关闭数据库连接对象
			JdbcUtils.closeAll(conn, pstmt, rs);
		}
		return admin;

	}

	// 查询全部
	@Override
	public List<Admin> queryAll() throws Exception {
		try {
			// 0.需要执行的sql操作
			String sql = "SELECT id,name,password,age,email FROM admin";
			// 1.使用工具类连接数据库
			conn = JdbcUtils.getConnection();
			// 2.预编译sql
			pstmt = conn.prepareStatement(sql);
			// 3.设置参数
			// 3.1 创建list
			List<Admin> list = new ArrayList<Admin>();
			// 3.2 遍历list
			while (rs.next()) {
				Admin admin = null;
				admin = new Admin();
				admin.setId(rs.getString(1));
				admin.setName(rs.getString(2));
				admin.setPassword(rs.getString(3));
				admin.setAge(rs.getInt(4));
				admin.setEmail(rs.getString(5));
				list.add(admin);
			}

			// 4.执行相应操作并返回结果
			rs = pstmt.executeQuery();
			System.out.println("打印影响的记录" + rs);
			return list;

		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			// 5.关闭数据库连接对象
			JdbcUtils.closeAll(conn, pstmt, rs);
		}

	}

	// 模糊查询
	@Override
	public List<Admin> queryByLike(String cond) throws Exception {
		try {
			// 0.需要执行的sql操作
			String sql = "SELECT id,name,password,age,email FROM admin WHERE name LIKE ? or email LIKE ?";
			// 1.使用工具类连接数据库
			conn = JdbcUtils.getConnection();
			// 2.预编译sql
			pstmt = conn.prepareStatement(sql);
			// 3. 执行预编译
			rs = pstmt.executeQuery();
			// 4.设置参数
			//4.1 模糊查询条件设置
			pstmt.setString(1,"%"+cond+"%") ;
			pstmt.setString(2,"%"+cond+"%") ;
			// 4.2  创建list
			List<Admin> list = new ArrayList<Admin>();
			// 4.3 遍历list
			while(rs.next()){
				Admin admin = new Admin();
				admin = new Admin();
				admin.setId(rs.getString(1));
				admin.setName(rs.getString(2));
				admin.setPassword(rs.getString(3));
				admin.setAge(rs.getInt(4));
				admin.setEmail(rs.getString(5));
				list.add(admin);
			}
			return list;
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			// 5.关闭数据库连接对象
			JdbcUtils.closeAll(conn, pstmt, rs);
		}
	}

}

3.4、DAO工厂

package cn.itcase.daofactory;

import cn.itcase.dao.AdminDao;
import cn.itcase.dao.impl.AdminDaoImpl;

public class DaoFactory {
	public static AdminDao getAdminDaoInstance() {
		return new AdminDaoImpl();
	}
}

3.5、JDBC连接数据的工具类

package cn.itcase.jdbcutils;

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

public class JdbcUtils {
	// 连接参数
		// private String url = "jdbc:mysql://localhost:3306/jdbc_demo";
		private static String url = "jdbc:mysql://admin?characterEncoding=utf8";
		private static String user = "root";
		private static String password = "0000";

		/*
		 * 返回连接对象
		 */
		public static Connection getConnection() {
			try {
				Class.forName("com.mysql,jdbc.Driver");
				return DriverManager.getConnection(url, user, password);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}

		/* 关闭 */
		public static void closeAll(Connection conn, PreparedStatement pstmt,
				ResultSet rs) {
			try {
				if (rs != null) {
					rs.close(); // 快速异常捕获 Alt + shift + z
					rs = null; // 建议垃圾回收期回收资源
				}
				if (pstmt != null) {
					pstmt.close();
					pstmt = null;
				}
				if (conn != null && !conn.isClosed()) {
					conn.close();
					conn = null;
				}
			} catch (SQLException e) {
				throw new RuntimeException(e);
			}
		}
}

3.6、数据代码

/*建库*/
/*建库并设置默认编码*/
GBK: create database admin DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci;   
/*本项目使用utf8的默认编码*/ 
UTF8: CREATE DATABASE  admin DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

/*使用库*/
USE admin
/*建表*/
CREATE TABLE admin
( 
 id VARCHAR(32) NOT NULL PRIMARY KEY , 
 NAME VARCHAR(20) NOT NULL , 
 PASSWORD VARCHAR(20) NOT NULL , 
 age VARCHAR(20) NOT NULL , 
 email VARCHAR(20) NOT NULL 
) ;

三、总结

   DAO设计模式基本上就是这么个固定的套路,接口实现类中的五个步骤有点瑕疵。但不影响总体上对于设计DAO设计模式的理解。值得注意的是DAO这工厂类,DAO工厂类的主要优点是实现接口与具体实现的分离,可以使系统能够面向接口编程,而不是依赖于很多具体的类。也就是说通过工厂类这个中间对象来管理实现类,而不使接口实现类依赖接口