JavaDAO模式基础

1.DAO模式理解

DAO模式是J2EE设计模式之一,开发人员为了降低耦合性,把底层的数据访问操作和上层的业务逻辑分开,此设计模式的主要作用是封装对数据库的操作;

2.DAO模式组成

  • VO:值对象,对象由属性、setter、getter方法组成,与数据库表中的字段相对应,代表数据库中表中的一条记录
  • DAO接口:封装对VO的所有操作
  • DAO实现类:DAO接口的具体实现

3.学习过程

  1. 创建所需数据表account
  2. 创建account表对应的VO
package com.oracle.vo;

public class Account {
	Integer accountid;
	String name;
	Integer remain;
	public Account(String name, Integer remain) {
		super();
		this.name = name;
		this.remain = remain;
	}
	public Account() {
		super();
	}
	public Integer getAccountid() {
		return accountid;
	}
	public void setAccountid(Integer accountid) {
		this.accountid = accountid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getRemain() {
		return remain;
	}
	public void setRemain(Integer remain) {
		this.remain = remain;
	}
	@Override
	public String toString() {
		return "Account [accountid=" + accountid + ", name=" + name + ", remain=" + remain + "]";
	}
}

3.创建与VO对应的DAO接口

package com.oracle.dao;

import java.util.List;

import com.oracle.vo.Account;

/**
 * 对Account对象各种操作的封装;
 * @author Hero
 *
 */
public interface AccountDao {

	void insert(Account account);
	
	void delete(Integer accountId);
	
	boolean update(Account account);
	
	//查询
	Account getAccountById(Integer accountId);
	
	List<Account> getAll();
}

4.编写JDBC操作

package com.oracle.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.oracle.vo.Account;

public class JdbcUtil {
	
	private static String url = "jdbc:mysql://localhost:3306/*****";
	private static String userName = "****";
	private static String password = "******";
	
	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static Connection getConnection() {
		Connection conn = null;
		
		try {
			conn = DriverManager.getConnection(url, userName, password);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return conn;
	}
	/**
	 * 执行一个sql
	 * @param sql
	 * @param agrs ; sql语义需要绑定的参数值
	 * @return
	 */
	public static int executeSql(String sql, Object...agrs) {
		int count = 0;
		try(Connection conn = getConnection();
			PreparedStatement ps = conn.prepareStatement(sql);) {
			
			for(int i = 0; i < agrs.length; i++) {
				ps.setObject(i+1, agrs[i]);
			}
			count = ps.executeUpdate();
		} catch(Exception e) {
			e.printStackTrace();
		}
		return count;
	}
	
	/**
	 * 执行查询sql,将查询的结果转换成T类型
	 * @param <T>
	 * @return
	 */
	public static <T> List<T> query(String sql,Convertor<T> convertor, Object...objs) {
		List<T> list = new ArrayList<T>();
		try(Connection conn = JdbcUtil.getConnection();
				PreparedStatement ps = conn.prepareStatement(sql);
				) {
			System.out.println(objs.length);
			for(int i = 0; i < objs.length; i++) {
				ps.setObject(i+1, objs[i]);
			}
			
			ResultSet rs = ps.executeQuery();
			while(rs.next()) {
				list.add(convertor.convert(rs));
			}
			
		} catch(Exception e) {
			e.printStackTrace();
		}
		return list;
	}
}

5.编写DAO实现类实现具体操作

package com.oracle.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.oracle.util.JdbcUtil;
import com.oracle.vo.Account;

public class AccountDaoImpl implements AccountDao {
	
	String sql_insert = "insert into account values(null,?,?)";
	
	String sql_delete = "delete from account where accountid = ?";
	
	String sql_update = "update account set name=?, remain=? where accountid=?";
	
	String sql_selectOne = "select * from account where accountid=?";
	
	String sql_select = "select * from account order by accountid";
	
	@Override
	public void insert(Account account) {
		// TODO Auto-generated method stub
		JdbcUtil.executeSql(sql_insert, account.getName(), account.getRemain());
	}

	@Override
	public void delete(Integer accountId) {
		// TODO Auto-generated method stub
		JdbcUtil.executeSql(sql_delete, accountId);
	}

	@Override
	public boolean update(Account account) {
		// TODO Auto-generated method stub
		return JdbcUtil.executeSql(sql_update, account.getName(), account.getRemain(), account.getAccountid()) > 0 ? true:false;
	}

	@Override
	public Account getAccountById(Integer accountId) {
		// TODO Auto-generated method stub
		List<Account> list = JdbcUtil.query(sql_selectOne, new AccountConverter(), accountId);
		return list.isEmpty() ? null:list.get(0);
	}

	@Override
	public List<Account> getAll() {
		// TODO Auto-generated method stub
		return JdbcUtil.query(sql_select, new AccountConverter());
	}
}

6.编写测试类进行测试

package com.oracle.test;

import java.util.List;

import com.oracle.dao.AccountDao;
import com.oracle.dao.AccountDaoImpl;
import com.oracle.vo.Account;

public class AccoutTest {
	public static void main(String[] args) {
		Account a = new Account("张三丰",5000);
		Account b = new Account("张无忌",1500);
		b.setAccountid(4);
		AccountDao dao = new AccountDaoImpl();
		
		//dao.insert(a);
		//dao.delete(1);
		//dao.update(b);
		//Account c = dao.getAccountById(4);
		/*List<Account> list = dao.getAll();
		for(Account ai:list) {
			System.out.println(ai);
		}*/
		//System.out.println(dao.getAccountById(5));
	}
}

7.扩展内容
此处编写了转换器接口,实现将ResultSet中的一条记录转换成一个VO对象

package com.oracle.util;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 转换器,将rs中的一条记录转换成一个vo对象;
 * @author Hero
 *
 * @param <T>
 */
public interface Convertor<T> {
	public T convert(ResultSet rs) throws SQLException;
}

转换器具体实现:

package com.oracle.dao;

import java.sql.ResultSet;
import java.sql.SQLException;

import com.oracle.util.Convertor;
import com.oracle.vo.Account;

public class AccountConverter implements Convertor<Account> {

	@Override
	public Account convert(ResultSet rs) throws SQLException {
		// TODO Auto-generated method stub
		Account a = new Account();
		a.setAccountid(rs.getInt(1));
		a.setName(rs.getString(2));
		a.setRemain(rs.getInt(3));
		return a;
	}
}

8.代码调优部分
在初期学习中DAO实现类中内容为每一个操作进行一次try-catch操作,作用相似,代码可进行简化。最终简化为JdbcUtil中的executeSql操作,实现输入SQL语句和PreparedStatemenqlt缺少对象,自动完成SQL操作,简化了实现类中代码。
query操作作用为利用转换器完成查询操作实现对ResultSet结果转换成对应VO组成的List表。

4.学习收获

  1. 掌握DAO设计模式可以封装对数据库的操作,且完成一次编码后,对应不同的数据表只需编写对应的VO、DAO实现类、VO转换器即可完成操作,过程中继承相应的接口,并调用已编写好的Jdbc操作,加快了编码效率。
  2. 应尝试编写更通用的泛型操作,对代码进一步调优。
  3. 加强对设计模式的学习,目前已学习的设计模式还有单例模式。
  4. 未完待续