DAO设计模式

简介: 本文完全根据我对DAO设计模式的理解程度完成,在未来不断地学习中,我也会不断更新这篇文章,如果你对文章内容有建议欢迎评论!DAO(Data Access Object,数据访问接口)设计模...

本文完全根据我对DAO设计模式的理解程度完成,在未来不断地学习中,我也会不断更新这篇文章,如果你对文章内容有建议欢迎评论!

DAO(Data Access Object,数据访问接口)设计模式是J2EE(Java2平台企业版)的核心模式

这种设计模式很好的将底层数据访问与业务逻辑实现高度分离,这样便于开发人员专注于开发所需的功能实现代码,而不需要过多地考虑上下层交互的问题,很好地降低了出bug的几率,提高了开发效率
这里写图片描述

一个典型的DAO实现有下列几个组件:

  • 一个DAO工厂类
  • 一个DAO接口
  • 一个实现DAO接口的具体类
  • 数据传输对象(DTO)

废话不多说,我们直接上代码,通过一个例子来使大家对DAO设计模式有个了解
这里写图片描述

现在,假设我们需要搭建一个简单博客

那么,我们需要考虑一个博客需要哪些必要的元素?
最基本的元素一定是用户(User)文章(Article)评论(Comment)

好,现在假设我们的博客简单到只有这么几个元素
这里写图片描述

那么,根据那四个基本组件,首先我们来看看什么是DAO工厂类?

其实这个类就是像是一个DAO类菜单,里面有各种DAO类供你选择

public class DAOFactory{
    public static UserDAO getUserDAO()
        throws Exception{
            return UserDAOImpl(); //获取实现类
        }
    public static ArticleDAO getArticleDAO()
        throws Exception{
            return UserDAOImpl(); //获取实现类
        }
    public static CommentDAO getCommentDAO()
        throws Exception{
            return UserDAOImpl(); //获取实现类
        }
}

好, 接下来看看DAO接口怎么写?
在写每个元素的DAO接口之前,我们需要先写一个BaseDAO类
我们在这个类中来写对数据库的CRUD(增删改查)操作,这样可以简化我们后面写DAO接口的实现类

对于BaseDAO的实现大家可以不必细看,只需要知道它的作用是什么,在需要的时候自己实现即可,它只是起到一个简化代码的作用
ps.你即将要翻过一长串代码,请耐心享受这一过程

public class BaseDAO <T>{

    public boolean insert(String sql, Object...args){

        Connection connection = null;
        PreparedStatement preparedStatement = null;

        try {
            connection = DBUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            if(args != null){
                for(int i = 0; i < args.length; i++){
                    preparedStatement.setObject(i + 1, args[i]);
                }
            }
            preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("插入失败");
            return false;
        } finally{
            DBUtil.release(preparedStatement, connection);
        }

        return true;
    }

    public boolean update(String sql, Object... args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;

        try {
            connection = DBUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }

            preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            DBUtil.release(null, preparedStatement, connection);
        }

        return true;
    }

    @SuppressWarnings("hiding")
    public <T> T get(Class<T> clazz, String sql, Object... args) {
        List<T> result = getForList(clazz, sql, args);
        if(result.size() > 0){
            return result.get(0);
        }

        return null;
    }

    @SuppressWarnings("hiding")
    public <T> List<T> getForList(Class<T> clazz, 
            String sql, Object... args) {

        List<T> list = new ArrayList<T>();

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = DBUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }

            resultSet = preparedStatement.executeQuery();

            List<Map<String, Object>> values = 
                    handleResultSetToMapList(resultSet);

            list = transfterMapListToBeanList(clazz, values);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtil.release(resultSet, preparedStatement, connection);
        }

        return list;
    }

    @SuppressWarnings("hiding")
    public <T> List<T> transfterMapListToBeanList(Class<T> clazz,
            List<Map<String, Object>> values) throws InstantiationException,
            IllegalAccessException, InvocationTargetException {

        List<T> result = new ArrayList<T>();

        T bean = null;

        if (values.size() > 0) {
            for (Map<String, Object> m : values) {
                bean = clazz.newInstance();
                for (Map.Entry<String, Object> entry : m.entrySet()) {
                    String propertyName = entry.getKey();
                    Object value = entry.getValue();

                    BeanUtils.setProperty(bean, propertyName, value);
                }
                result.add(bean);
            }
        }

        return result;
    }

    public List<Map<String, Object>> handleResultSetToMapList(
            ResultSet resultSet) throws SQLException {

        List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();

        List<String> columnLabels = getColumnLabels(resultSet);
        Map<String, Object> map = null;

        while (resultSet.next()) {
            map = new HashMap<String, Object>();

            for (String columnLabel : columnLabels) {
                Object value = resultSet.getObject(columnLabel);
                map.put(columnLabel, value);
            }

            values.add(map);
        }
        return values;
    }

    private List<String> getColumnLabels(ResultSet rs) throws SQLException {
        List<String> labels = new ArrayList<String>();

        ResultSetMetaData rsmd = rs.getMetaData();
        for (int i = 0; i < rsmd.getColumnCount(); i++) {
            labels.add(rsmd.getColumnLabel(i + 1));
        }

        return labels;
    }

    @SuppressWarnings("unchecked")
    public <E> E getForValue(String sql, Object... args) {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = DBUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }

            resultSet = preparedStatement.executeQuery();

            if(resultSet.next()){
                return (E) resultSet.getObject(1);
            }
        } catch(Exception ex){
            ex.printStackTrace();
        } finally{
            DBUtil.release(resultSet, preparedStatement, connection);
        }

        return null;
    }

}

这里写图片描述

哪位哥们儿知道怎么让代码折叠起来请评论!在线等!

好了,接下来就是各个元素的DAO接口
你希望对这个元素做哪些操作,你就将哪些方法写进去

/*
 * 我希望能够对User基本的增删改查,那就写这四个方法
 * 如果你还希望有其他特殊的操作,也可以进去
 * 例如:queryByName(name)根据名字查找,等等
 * 接口中所有方法默认为public abstract可以不用写出
 */
public interface UserDAO{
    boolean addUser(String name, String password, String email);
    boolean deleteUser(String email);
    boolean alterUser(String name, String password, String email);
    User queryUser(String email);
}

好的,我就写这么一个,不是因为我懒,而是大家那么聪明,一点就通,其他的一定已经知道怎么写了

去你妈的.jpg

那么,接下来自然就是写实现这些DAO接口的DAOImpl实现类

/*
 * 实现类继承BaseDAO
 */
public class UserDAOImpl extends BaseDAO<User>
     implements UserDAO {
     //sql语句中的'?'是因为BaseDAO使用了prepareStatement
     //它以'?'为占位符,用来接收参数
     @Override
     public boolean addUser(String name, String password, String email){
         String sql = "insert into User(name, password, email) values(?, ?, ?)";
         return insert(sql, name, password, email);
         //insert()来自BaseDAO
         //看看,这就是BaseDAO好处的体现,就这么简单的两行就结束了
     }
     @Override
     public boolean deleteUser(String email){
         String sql = "delete from User where email=?";
         return update(sql, email);
     }
     @Override
     public boolean alterUser(String name, String password, String email){
         String sql = "update User name=?,password=?,email=? where email=?";
         return update(sql, name, password, email);
     }
     @Override
     public User queryUser(String email){
         String sql = "select * from User where email=?";
         return get(sql, email);
    }
}

DAO设计模式的核心就是以上那些,关于数据传输对象DTO(Data Transfer Object)它是用来在表现层与应用层之间传输数据的,它会根据表现层的需求来对数据进行打包发送,具体的使用我不是很熟悉,日后再更新
这里写图片描述

目录
相关文章
|
8月前
|
设计模式 JavaScript Java
DAO设计模式
DAO设计模式 1.认识DAO 2.DAO各部分的详解 3.DAO设计模式流程
68 0
DAO设计模式
|
SQL Java 数据库连接
DAO 设计模式
介绍 DAO功能是数据操作.客户发送数据到显示层,显示层发送数据到业务层,业务发送数据到数据层,数据层进行持久化.即.保存进入databases 一些简称 BO 业务对象的简称 DAO 一个数据访问对象,增删查改 PO数据库一条记录,映射成javaBean对象,拥有getter/setter方法 ...
8238 0
|
关系型数据库 Java 数据库
DAO设计模式---实现一个简单的注册(上)
DAO设计模式是属于Java Web中对数据层的具体操作,使用DAO设计模式可以简化大量代码的编写和增加程序的可移植性,可以很方便在日后对代码的修改。 如果在JSP中使用JDBC操作数据库,那样在JSP中就会嵌入大量的Java代码,显示和逻辑功能的代码混在一起,可读性差,难以维护。
1327 0
|
SQL 设计模式
DAO设计模式---实现一个简单的注册(中)
4、DAO接口实现类: package com.song.Impl; import java.sql.*; import com.song.DAO.RegisterDAO; import com.
900 0
|
Java 设计模式
DAO设计模式---实现一个简单的注册(下)
6、DAO工厂类: package com.song.DAOFactory; import com.song.DAO.RegisterDAO; import com.song.Impl.RegisterImpl; public class RegisterFactory{ publ...
913 0
|
17天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
19 0
|
1月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
37 0
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。