DAO设计模式

xiaoxiao2021-02-28  90

本文完全根据我对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)它是用来在表现层与应用层之间传输数据的,它会根据表现层的需求来对数据进行打包发送,具体的使用我不是很熟悉,日后再更新

转载请注明原文地址: https://www.6miu.com/read-23812.html

最新回复(0)