Skip to content

Latest commit

 

History

History
361 lines (322 loc) · 8.76 KB

面向接口編程.md

File metadata and controls

361 lines (322 loc) · 8.76 KB

面向接口編程

DAO 模式

DAO (Data Access Object) 模式就是寫一個類,把訪問數據庫的代碼封裝起持。DAO 在數據庫與業務邏輯(Service) 之間。

  • 實體域: 即操作的對象,例如我們操作的表示 user 表,那麼就需要先寫一個 User 類。
  • DAO 模式需要先提供一個 DAO 接口。
  • 然後再提供一個 DAO 接口的實現類。
  • 再編寫一個 DAO 工廠,Service 通過工廠來獲取 DAO 實現。

修改項目

UserDao

  • 把 UserDao 修改為接口,然後把原來的 UserDao 修改類名為 UserDaoImpl
  • 修改 UserService 中對 UserDao 的實例化: private UserDao userDao = DaoFactory.getUserDao()
  • 創建 DaoFactory,提供 getUserDao()
package user.dao;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import user.domain.User;

/**
 * 数据类
 * @author asus
 *
 */
public class UserDaoImpl implements UserDao {
	private String path = "F:/users.xml";//依赖数据文件
	
	/**
	 * 按用户名查询
	 * @param username
	 * @return
	 */
	public User findByUsername(String username) {
		/*
		 * 1. 得到Document
		 * 2. xpath查询!
		 *   3. 校验查询结果是否为null,如果为null,返回null
		 *   4. 如果不为null,需要把Element封装到User对象中。
		 */
		/*
		 * 1. 得到Document
		 */
		// 创建解析器
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(path);
			/*
			 * 2. 通过xpath查询得到Element
			 */
			Element ele = (Element)doc.selectSingleNode("//user[@username='" + username + "']");
			/*
			 * 3. 校验ele是否为null,如果为null,返回null
			 */
			if(ele == null) return  null;
			
			/*
			 * 4. 把ele的数据封装到User对象中
			 */
			User user = new User();
			String attrUsername = ele.attributeValue("username");//获取该元素的名为username属性值
			String attrPassword = ele.attributeValue("password");//获取该元素的名为password属性值
			user.setUsername(attrUsername);
			user.setPassword(attrPassword);
			
			return user;
		} catch (DocumentException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 添加用户
	 * @param user
	 */
	public void add(User user) {
		/*
		 * 1. 得到Document
		 * 2. 通过Document得到root元素!<users>
		 * 3. 使用参数user,转发成Element对象
		 * 4. 把element添加到root元素中
		 * 5. 保存Document
		 */
		
		// 得到Document
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(path);
			// 得到根元素
			Element root = doc.getRootElement();
			// 通过根元素创建新元素
			Element userEle = root.addElement("user");
			// 为userEle设置属性
			userEle.addAttribute("username", user.getUsername());
			userEle.addAttribute("password", user.getPassword());
			
			/*
			 * 保存文档
			 */
			// 创建输出格式化器
			OutputFormat format = new OutputFormat("\t", true);//缩进使用\t,是否换行,使用是!
			format.setTrimText(true);//清空原有的换行和缩进
			
			// 创建XmlWriter
			XMLWriter writer;
			try {
				writer = new XMLWriter(
						new OutputStreamWriter(
								new FileOutputStream(path), "UTF-8"), format);
				writer.write(doc);//保存document对象
				writer.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		} catch (DocumentException e) {
			throw new RuntimeException(e);
		}
	}
}

package user.dao;

import user.domain.User;

public interface UserDao {
	public void add(User form);
	public User findByUsername(String username);
}

package user.service;

import user.dao.DaoFactory;
import user.dao.UserDao;
import user.dao.UserDaoImpl;
import user.domain.User;

/**
 * User的业务逻辑层
 * @author asus
 *
 */
public class UserService {
	//把具體實現類的創見隱藏到工廠裡
	private UserDao userDao = DaoFactory.getUserDao();
	
	/**
	 * 注册功能
	 * @param user
	 * @throws UserException
	 */
	public void regist(User user) throws UserException {
		/*
		 * 1. 使用用户名去查询,如果返回null,完成添加
		 * 2. 如果返回的不是null,抛出异常!
		 */
		User _user = userDao.findByUsername(user.getUsername());
		if(_user != null) throw new UserException("用户名" + user.getUsername() + ", 已被注册过了!");
		
		userDao.add(user);
	}

	/**
	 * 登录功能
	 * @param form
	 * @return
	 * @throws UserException 
	 */
	public User login(User form) throws UserException {
		/*
		 * 1. 使用form中的username进行查询,得到User user
		 */
		User user = userDao.findByUsername(form.getUsername());
		/*
		 * 2. 如果返回null,说明用户名不存在,抛出异常,异常信息为“用户名不存在”
		 */
		if(user == null) throw new UserException("用户名不存在!");
		/*
		 * 3. 比较user的password和form的password,如果不同,抛出异常,异常信息为“密码错误!”
		 */
		if(!form.getPassword().equals(user.getPassword())) {
			throw new UserException("密码错误!");
		}
		
		/*
		 * 返回数据库中查询出来的user,而不是form,因为form中只有用户名和密码,而user是所有用户信息!
		 */
		return user;
	}
}

package user.dao;

import java.io.InputStream;
import java.util.Properties;

/**
 * 通過配置文件得到 dao 實現類的名稱
 * 通過類名稱,完成創建類對象(反射完成的)
 * @author jack870131
 *
 */
public class DaoFactory {
	private static Properties props = null;
	static {
		//加載配置文件內容到 props 中
		try {
			InputStream in = DaoFactory.class
					.getClassLoader().getResourceAsStream("dao.properties");
			props = new Properties();
			props.load(in);
		} catch(Exception e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 返回一個具體 UserDao 的實現類對象
	 * @return
	 */
	public static UserDao getUserDao() {
		/**
		 * 給出一個配置文件,文件中給出 UserDao 接口的實現類名稱
		 * 獲取實現類的類名,通過反射完成創鍵對象
		 */
		try {
			//得到 dao 實現類的名稱
			String daoClassName = props.getProperty("usermng.dao.UserDao");
			//通過反射來創建實現類的對象
			Class clazz = Class.forName(daoClassName);
			return (UserDao) clazz.newInstance();
		} catch(Exception e) {
			throw new RuntimeException(e);
		}
	}
}


package user.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import user.domain.User;

/**
 * 针对数据库的实现
 * @author asus
 *
 */
public class JdbcUserDaoImpl implements UserDao {
	@Override
	public void addUser(User form) {
		Connection con = null;
		PreparedStatement pstmt = null;
		try {
			/*
			 * 一、得到连接
			 */
			con = JdbcUtils.getConnection();
			/*
			 * 二、准备sql模板,得到pstmt
			 */
			String sql = "INSERT INTO t_user VALUES(?,?,?,?)";
			pstmt = con.prepareStatement(sql);
			/*
			 * 三、为pstmt中的问号赋值
			 */
			pstmt.setString(1, form.getUsername());
			pstmt.setString(2, form.getPassword());
			pstmt.setInt(3, form.getAge());
			pstmt.setString(4, form.getGender());
			
			/*
			 * 四、执行之
			 */
			pstmt.executeUpdate();
		} catch(Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if(pstmt != null) pstmt.close();
				if(con != null) con.close();
			} catch(SQLException e) {}
		}
	}

	@Override
	public User findByUsername(String username) {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			/*
			 * 一、得到连接
			 */
			con = JdbcUtils.getConnection();
			/*
			 * 二、准备sql模板,得到pstmt
			 */
			String sql = "SELECT * FROM t_user WHERE username=?";
			pstmt = con.prepareStatement(sql);
			/*
			 * 三、为pstmt中的问号赋值
			 */
			pstmt.setString(1, username);
			
			/*
			 * 四、执行之
			 */
			rs = pstmt.executeQuery();
			
			/*
			 * 五、把rs转换成User类型,返回!
			 */
			if(rs == null) {
				return null;
			}
			if(rs.next()) {
				//转换成User对象,并返回
				// ORM --> 对象关系映射! hibernate!
				User user = new User();
				user.setUsername(rs.getString("username"));
				user.setPassword(rs.getString("password"));
				user.setAge(rs.getInt("age"));
				user.setGender(rs.getString("gender"));
				
				return user;
			} else {
				return null;
			}
		} catch(Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if(pstmt != null) pstmt.close();
				if(con != null) con.close();
			} catch(SQLException e) {}
		}
	}
}

//dao.properties
user.dao.UserDao=user.dao.UserDaoImpl

//daoconfig.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc\:mysql\://localhost\:3306/mydb1
username=root
password=tyler0131