本文完全根据我对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);
}
}