一、什么是Dao设计模式

  Dao设计模式封装了操作具体数据库的细节,对业务层提供操作数据库的接口,因此降低了业务层代码与具体数据库之间的耦合,有利于人员分工,增加了程序的可移植性。

  Dao设计模式中主要包含这5个模块:

    1、VO类:VO(Value Object)即值对象,每一个值对象对应一张数据库表,便于我们传递数据。

    2、Dao接口:Dao接口定义了操作数据库的方法,业务层通过调用这些方法来操作数据库。

    3、Dao实现类:操作数据库的方法的具体实现,封装了操作数据库的细节。

    4、Dao工厂类:用于代替new操作,进一步降低业务层与数据层之间的耦合。

    5、数据库连接类:封装了连接数据库、关闭数据库等常用的操作,减少重复编码。

  下面我们应用Dao设计模式来实现一个简单的转账操作,加深对其的理解。

二、Dao设计模式实现

  首先,我们创建vo、dao、factory、util包来分别存放Dao设计模式5个模块的代码。因为我们使用的是JDBC连接MySQL数据库,所以还需要创建一个lib包存放并引用JDBC驱动。除此之外,我们还需要创建一个test包进行代码的测试。创建好后的目录结构如下:

  接着设计一张user表,表中包含了用户基本信息和余额,并插入一些数据。

  根据user表在vo包中创建VO类user.java。

  1. package vo;
  2.  
  3. public class User {
  4.  
  5. private int id;
  6.  
  7. private String username;
  8.  
  9. private int sum;
  10.  
  11. public int getId() {
  12. return id;
  13. }
  14.  
  15. public void setId(int id) {
  16. this.id = id;
  17. }
  18.  
  19. public String getUsername() {
  20. return username;
  21. }
  22.  
  23. public void setUsername(String username) {
  24. this.username = username;
  25. }
  26.  
  27. public int getSum() {
  28. return sum;
  29. }
  30.  
  31. public void setSum(int sum) {
  32. this.sum = sum;
  33. }
  34.  
  35. @Override
  36. public String toString() {
  37. return "User [id=" + id + ", username=" + username + ", sum=" + sum + "]";
  38. }
  39.  
  40. }

  在util包中创建数据库连接类JDBC.java。

  1. package util;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.DriverManager;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8.  
  9. public class JDBC {
  10. //获取数据库链接
  11. public static Connection getConnection() {
  12. Connection con = null;
  13. try {
  14. String url = "jdbc:mysql://localhost:3306/user?serverTimezone=Asia/Shanghai";
  15. Class.forName("com.mysql.cj.jdbc.Driver");
  16. con = DriverManager.getConnection(url, "root", "root");
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }
  20. return con;
  21. }
  22. //关闭资源
  23. public static void close(Connection con, Statement st, ResultSet rs) {
  24. try {
  25. if (rs != null) {
  26. rs.close();
  27. }
  28. if (st != null) {
  29. st.close();
  30. }
  31. if (con != null) {
  32. con.close();
  33. }
  34. } catch (SQLException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. }

  经过分析,该转账系统需要两类数据库操作,分别是“查询用户信息”和“更新用户余额”。因此我们在dao包中创建IUserDao.java接口并定义这两种方法。

  1. package dao;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.SQLException;
  5.  
  6. import vo.User;
  7.  
  8. public interface IUserDao {
  9. //根据用户名查找用户信息
  10. public User selectUserByName(Connection con, User user);
  11. //根据用户名更新用户余额
  12. public int updateSumByName(Connection con, User user) throws SQLException;
  13. }

  接着在dao包中创建该接口的实现类UserDaoImpl.java,实现这两种方法。

  1. package dao;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7.  
  8. import util.JDBC;
  9. import vo.User;
  10.  
  11. public class UserDaoImpl implements IUserDao {
  12.  
  13. @Override
  14. public User selectUserByName(Connection con, User user) {
  15. String sql = "select * from user where username = ?";
  16. PreparedStatement pStatement = null;
  17. ResultSet rs = null;
  18. try {
  19. pStatement = con.prepareStatement(sql);
  20. pStatement.setString(1, user.getUsername());
  21. rs = pStatement.executeQuery();
  22. if (rs.next()) {
  23. user.setId(rs.getInt("id"));
  24. user.setUsername(rs.getString("username"));
  25. user.setSum(rs.getInt("sum"));
  26. return user;
  27. }
  28. } catch (SQLException e) {
  29. e.printStackTrace();
  30. }finally {
  31. JDBC.close(null, pStatement, rs);
  32. }
  33. return null;
  34. }
  35.  
  36. @Override
  37. public int updateSumByName(Connection con, User user) throws SQLException {
  38. String sql = "update user set sum = ? where username = ?";
  39. PreparedStatement pStatement = null;
  40. try {
  41. pStatement = con.prepareStatement(sql);
  42. pStatement.setInt(1, user.getSum());
  43. pStatement.setString(2, user.getUsername());
  44. return pStatement.executeUpdate();
  45. } catch (SQLException e) {
  46. e.printStackTrace();
  47. //抛出异常,便于进行事务处理
  48. throw e;
  49. }finally {
  50. JDBC.close(null, pStatement, null);
  51. }
  52. }
  53. }

  最后,我们还需要在factory包中创建Dao工厂类DaoFactory.java。

  1. package factory;
  2.  
  3. import dao.IUserDao;
  4. import dao.UserDaoImpl;
  5.  
  6. public class DaoFactory {
  7. public static IUserDao getUserDao() {
  8. return new UserDaoImpl();
  9. }
  10. }

  到这里,转账系统的Dao层就设计好了。我们在test包中创建Main.java进行测试。

  1. package test;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.SQLException;
  5.  
  6. import dao.IUserDao;
  7. import factory.DaoFactory;
  8. import util.JDBC;
  9. import vo.User;
  10.  
  11. public class Main {
  12.  
  13. public static void main(String[] args) {
  14. Connection con = JDBC.getConnection();
  15. IUserDao userDao = DaoFactory.getUserDao();
  16. //被转账的用户
  17. User user_in = new User();
  18. user_in.setUsername("ysy");
  19. user_in = userDao.selectUserByName(con, user_in);
  20. System.out.println(user_in);
  21. //转账的用户
  22. User user_out = new User();
  23. user_out.setUsername("管理员");
  24. user_out = userDao.selectUserByName(con, user_out);
  25. System.out.println(user_out);
  26. //转账30元
  27. user_in.setSum(user_in.getSum() + 30);
  28. user_out.setSum(user_out.getSum() - 30);
  29. //事务处理
  30. try {
  31. con.setAutoCommit(false);
  32. userDao.updateSumByName(con, user_in);
  33. userDao.updateSumByName(con, user_out);
  34. con.commit();
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. try {
  38. con.rollback();
  39. } catch (SQLException e1) {
  40. e1.printStackTrace();
  41. }
  42. }
  43. //查询转账结果
  44. user_in = userDao.selectUserByName(con, user_in);
  45. System.out.println(user_in);
  46. user_out = userDao.selectUserByName(con, user_out);
  47. System.out.println(user_out);
  48. JDBC.close(con, null, null);
  49. }
  50. }

  执行结果如下:

  最终的目录结构如下:

Dao设计模式简单实现的更多相关文章

  1. 简单的Dao设计模式

    简单的DAO设计模式 这两天学习到了DAO(Data Access Object 数据存取对象)设计模式.想谈谈自己的感受,刚开始接触是感觉有点难,觉得自己逻辑理不清,主要是以前学的知识比较零散没有很 ...

  2. Java Dao设计模式

    一.信息系统的开发架构   客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是客户端,简单的来说就是浏览器. 2.显示层:JSP/S ...

  3. JavaBean中DAO设计模式介绍(转)

    一.信息系统的开发架构 客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是客户端,简单的来说就是浏览器. 2.显示层:JSP/Ser ...

  4. JavaBean在DAO设计模式简介

    一.信息系统开发框架 客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层是client,简单的来说就是浏览器. 2.显示层:JSP/Se ...

  5. JavaBean中DAO设计模式介绍

    一.信息系统的开发架构 客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是client,简单的来说就是浏览器. 2.显示层:JSP/ ...

  6. DAO设计模式(转)

    J2EE开发人员使用数据访问对象(DAO)设计模式把底层的数据访问逻辑和高层的商务逻辑分开.实现DAO模式能够更加专注于编写数据访问代码. 我们先来回顾一下DAO设计模式和数据访问对象. DAO基础  ...

  7. JavaBean中DAO设计模式简介

    一.信息系统的开发架构 客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是客户端,简单的来说就是浏览器. 2.显示层:JSP/Ser ...

  8. DAO设计模式

    DAO设计模式 DAO设计模式简介: DAO设计模式可以减少代码量,增强程序的可移植性,提高代码的可读性. DAO(数据库操作对象)设计模式是 JavaEE 数据层的操作.主要由五部分组成: 1.数据 ...

  9. JavaWeb技术(二):DAO设计模式

    1. DAO全称:Data Access Object , 数据访问对象.使用DAO设计模式来封装数据持久化层的所有操作(CRUD),使得数据访问逻辑和业务逻辑分离,实现解耦的目的. 2. 典型的DA ...

随机推荐

  1. 【概率论】3-3:累积分布函数(Cumulative Distribution Function)

    title: [概率论]3-3:累积分布函数(Cumulative Distribution Function) categories: Mathematic Probability keywords ...

  2. Ubuntu18.04安装和配置Django,并实现简单示例

    一.前言(系统,django介绍,window.mac.linux简单区别) Django是python开发过程最重要的web框架.因为在看的Django教学视频是在mac下安装的,我自己用的是Lin ...

  3. idea导入项目之后包位置报错

    解决办法:

  4. 二十三、Linux任务计划及周期性任务执行:at、crontab命令

    一.概述 未来的某时间点执行一次某任务:at, batch周期性运行某任务:crontab 这两个任务的执行结果:会通过邮件发送给用户 (本地终端用户之间的邮件通知) centos 5,6,7默认开启 ...

  5. Robot Framework(十五) 扩展RobotFramework框架——远程库接口

    4.2远程库接口 远程库接口提供了在运行Robot Framework本身的机器上运行测试库的方法,以及使用除本机支持的Python和Java之外的其他语言实现库的方法.对于测试库,用户远程库看起来与 ...

  6. POJ 1051 Jury Compromise ——(暴力DP)

    题目不难,暴力地dp一下就好,但是不知道我WA在哪里了,对拍了好多的数据都没找出错误= =.估计又是哪里小细节写错了QAQ..思路是用dp[i][j]表示已经选了i个,差值为j的最大和.转移的话暴力枚 ...

  7. csp-s模拟110

    倒计时三天. 这场又是巨头们的AK场,大众分200+,貌似真实的csps? 然而T1又炸了,$1<<62$暴int,要$1ll<<62$.T2试图打70部分分,T3也只会40分 ...

  8. Linux设备驱动程序 之 中断和锁

    中断和锁 1. 硬中断和软中断(包括tasklet和timer)共享数据,硬中断中使用spin_lock/spin_unlock,软中断中使用spin_lock_irq/spin_unlock_irq ...

  9. udp如何实现可靠性传输?

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   1udp与tcp的区别 TCP(TransmissionControl Protocol 传输控制协议)是一种面向连接的 ...

  10. Python在for循环中更改list值的方法

    一.在for循环中直接更改列表中元素的值不会起作用: 如: l = list(range(10)[::2]) print (l) for n in l: n = 0 print (l) 运行结果: [ ...