设计模式-数据访问对象模式

时间:2022-07-25
本文章向大家介绍设计模式-数据访问对象模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

背景

经历过jsp页面请求jdbc将数据库中的数据直接查出后直接返回给控制器,然后jsp渲染的痛,相信经历过的都很清楚,这样的很难维护,而现在流行的mvc模式,其实m分为dao和entity两层,dao负责与数据库交互,而entity作为数据模型,很好起到了隔离作用。

数据访问对象模式是什么?

数据访问对象模式(Data Access Object Pattern)或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来。以下是数据访问对象模式的参与者。

角色:

数据访问对象接口(Data Access Object Interface):该接口定义了在一个模型对象上要执行的标准操作。

数据访问对象实体类(Data Access Object concrete class): 该类实现了上述的接口。该类负责从数据源获取数据,数据源可以是数据库,也可以是 xml,或者是其他的存储机制。

模型对象/数值对象(Model Object/Value Object):该对象是简单的 POJO,包含了 get/set 方法来存储通过使用 DAO 类检索到的数据。

优点:

隔离数据层:由于新增了dao层,不会影响到服务或者实体对象与数据库交互发生错误会在该层进行异常抛出。

缺点:

代码量增加:当然增加一层需要增加相应的代码,不过该缺点可以忽略,可以使层次更清晰嘛。

数据访问对象模式可以干嘛?

主要解决jsp时代的一个痛点,层次更清晰,并且各层职责明确,dao就是与数据交互而产生的。

个人理解:

数据访问对象模式就是mvc中的dao层,主要与数据库交互。

数据访问对象模式类图

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

实现代码

/**
 *
 * 功能描述:学生
 *
 * @param:
 * @return:
 * @auther: csh
 * @date: 2020/6/28 10:29
 */
public class Student {
   private String name;
   private int rollNo;
 
   Student(String name, int rollNo){
      this.name = name;
      this.rollNo = rollNo;
   }
 
   public String getName() {
      return name;
   }
 
   public void setName(String name) {
      this.name = name;
   }
 
   public int getRollNo() {
      return rollNo;
   }
 
   public void setRollNo(int rollNo) {
      this.rollNo = rollNo;
   }
}
/**
  *
  * 功能描述:接口
  *
  * @param:
  * @return:
  * @auther: csh
  * @date: 2020/6/28 10:29
  */
public interface StudentDao {
    /**
     *
     * 功能描述: 全部学生
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/6/28 10:29
     */
   public List<Student> getAllStudents();
   /**
    *
    * 功能描述:通过学生号获取
    *
    * @param:
    * @return:
    * @auther: csh
    * @date: 2020/6/28 10:29
    */
   public Student getStudent(int rollNo);
   /**
    *
    * 功能描述:更新学生信息
    *
    * @param:
    * @return:
    * @auther: csh
    * @date: 2020/6/28 10:30
    */
   public void updateStudent(Student student);
   /**
    *
    * 功能描述:删除学生信息
    *
    * @param:
    * @return:
    * @auther: csh
    * @date: 2020/6/28 10:30
    */
   public void deleteStudent(Student student);
}
/**
 *
 * 功能描述:学生接口实现
 *
 * @param:
 * @return:
 * @auther: csh
 * @date: 2020/6/28 10:30
 */
public class StudentDaoImpl implements StudentDao {
   
   //列表是当作一个数据库
   List<Student> students;
 
   public StudentDaoImpl(){
      students = new ArrayList<Student>();
      Student student1 = new Student("Robert",0);
      Student student2 = new Student("John",1);
      students.add(student1);
      students.add(student2);    
   }
   @Override
   public void deleteStudent(Student student) {
      students.remove(student.getRollNo());
      System.out.println("Student: Roll No " + student.getRollNo() 
         +", deleted from database");
   }
 
   //从数据库中检索学生名单
   @Override
   public List<Student> getAllStudents() {
      return students;
   }
 
   @Override
   public Student getStudent(int rollNo) {
      return students.get(rollNo);
   }
 
   @Override
   public void updateStudent(Student student) {
      students.get(student.getRollNo()).setName(student.getName());
      System.out.println("Student: Roll No " + student.getRollNo() 
         +", updated in the database");
   }
}
/**
 * @Auther: csh
 * @Date: 2020/6/28 10:31
 * @Description: 通过
 */
public class Client {
    public static void main(String[] args) {
        StudentDao studentDao = new StudentDaoImpl();

        //输出所有的学生
        for (Student allStudent : studentDao.getAllStudents()) {
            System.out.println("学生【学号:"+allStudent.getRollNo()+"姓名:"+allStudent.getName()+"】");
        }

        //更新学生信息
        Student student = studentDao.getAllStudents().get(0);
        student.setName("hong");
        studentDao.updateStudent(student);

        //获取学生信息
        Student now = studentDao.getAllStudents().get(0);
        System.out.println("姓名:"+now.getName()+"学号:"+now.getRollNo());
    }
}

结果

学生【学号:0姓名:Robert】
学生【学号:1姓名:John】
Student: Roll No 0, updated in the database
姓名:hong学号:0

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

最后

数据访问对象模式,就是现在在model层再分一层dao直接与数据库交互,这样的话一但发现错误,不会影响到服务或实体,并且该层在各大框如mvc或者spring boot以及各大企业中都会用到,基本mvc都会有一个dao层,用来作为与数据库交互一层。在测试中可以直接避开业务逻辑层直接用dao层进行单元测试。