Code more, please skip the code, the code to understand the logic in the study
Introduced
Recalling the last one in the project, the final hierarchy:
In the MVC, we analyzed the advantages of the MVC design pattern have, as well as inadequate, and by the Service for processing business logic layer on its basis, but this does not end, for large projects, the program structure is still not clear enough the, service layer not only to deal with business logic, but also handle database operations; still the following problems:
- Coupling high
- Code reusability poor
- Service is not functional responsibilities of a single layer
DAO
In order to solve these problems, the Service layer further decoupling, how to do it, can be realized by increasing the data access layer DAO;
definition:
DAO, (Data Access Object), data access objects, object refers to the provision of CRUD functions of data; responsible for dealing with the database, between the business logic layer and the database;
simply put:
Is originally database operations Service encapsulated DAO layer to layer; Service layer such that the focus on the business logic, reducing the coupling between the functions;
Increasing the hierarchical structure of the DAO:
DAO layer composition
DAO is a design pattern for the data access layer, the entire composition comprising the following components:
Looks very complicated, yes, DAO is a complete solution for solving database operations, according to the above structure to achieve it, for large-scale commercial projects is very standard, but the need for small, fast development of the project words, daunting
Old driver is recommended: Excessive design will make people see nature, you must keep in mind the key issues to be addressed when designing learning mode, to see the problems with the role and importance of each part
Examples
To enable a clearer understanding of the nature of the DAO, where the use of the simplified design DAO
There are three objects in DAO is a must:
- Data Access Objects (Bean)
- Database connection class
- DAO implementation
Service layer is ultimately required to achieve DAO object database connection object is repeated in order to extract the code exists, the Bean is already present in the original system
Now two new classes need a DAO, a database connection class, create them like this
DBTool:
Database connection class is responsible for connecting to the database query is executed, and finally close the resource
package com.kkb.test;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DBTool {
//默认参数
public String ip = "127.0.0.1";
public int port = 3306;
public String
user="root",
password="admin",
charset ="utf8",
dbName="db1";
private static boolean DriverLoaded=false;
//使用默认参数链接数据库
public DBTool() throws ClassNotFoundException {
if(DriverLoaded)return;
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("DBTools message:数据库驱动加载成功!");
} catch (ClassNotFoundException e) {
System.out.println("DBTools Error:驱动程序加载失败!");
throw e;
}
DriverLoaded=true;
}
//自定义参数初始化
public DBTool(String ip, int port, String user, String password, String dbName) throws ClassNotFoundException {
this();
this.ip = ip;
this.port = port;
this.user = user;
this.password = password;
this.dbName = dbName;
}
//自定义参数初始化
public DBTool(String user, String password, String dbName) throws ClassNotFoundException {
this();
this.user = user;
this.password = password;
this.dbName = dbName;
}
//获取一个链接
public Connection getConnection() throws SQLException {
String url = String.format("jdbc:mysql://%s:%s/%s?characterEncoding=%s&user=%s&password=%s&useSSL=false",ip,port,dbName,charset,user,password);
try {
return DriverManager.getConnection(url);
} catch (SQLException e) {
System.out.println("DBTools Error 数据库连接失败!");
throw e;
}
}
//执行查询语句
public List<Map<String,Object>> executeQuery(String sql, Object...args) throws SQLException {
ArrayList<Map<String, Object>> res = new ArrayList<>();
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
Connection connection = null;
try {
connection = getConnection();
preparedStatement = getPreparedStatement(connection, sql, args);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
resultSet.getMetaData().getColumnCount();
HashMap<String, Object> map = new HashMap<>();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount() ; i++) {
map.put(resultSet.getMetaData().getColumnName(i),resultSet.getObject(i));
}
res.add(map);
}
} catch (SQLException e) {
e.printStackTrace();
throw e;
} finally {
if(resultSet != null)
resultSet.close();
if(preparedStatement != null)
preparedStatement.close();
if(connection != null)
connection.close();
}
return res;
}
//sql参数预处理
private PreparedStatement getPreparedStatement(Connection connection, String sql, Object[] args) throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
int count = sql.length() - sql.replace("?", "").length();
if(count != args.length){
throw new SQLException("DBTool Error: 参数个数不匹配");
}
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i+1,args[i]);
}
return preparedStatement;
}
//执行更新语句
public boolean executeUpdate(String sql,Object...args) throws SQLException {
try {
Connection connection = getConnection();
PreparedStatement preparedStatement = getPreparedStatement(connection, sql, args);
int i = preparedStatement.executeUpdate();
if (i>0){return true;}
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
return false;
}
}
UserDao:
Service layer is responsible for providing the required CURD method, essentially encapsulates SQL execution, and analytical results
package com.kkb.models;
import com.kkb.test.DBTool;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class UserDao {
private DBTool tools;
//构造函数
public UserDao() throws ClassNotFoundException {
tools = new DBTool();
}
//新增用户
public boolean insertUser(UserBean user) throws SQLException {
String sql = "insert into user values(null,?,?)";
return tools.executeUpdate(sql, user.getName(), user.getPwd());
}
//删除用户
public boolean deleteUser(UserBean user) throws SQLException {
String sql = "delete from user where id = ?";
return tools.executeUpdate(sql, user.getId());
}
//更新用户
public boolean updateUser(UserBean user) throws SQLException {
String sql = "update user set name = ? , pwd = ? where id = ?";
return tools.executeUpdate(sql, user.getName(), user.getPwd(), user.getId());
}
//查询所有用户
public List<UserBean> queryAllUser() throws SQLException {
ArrayList<UserBean> beans = new ArrayList<>();
List<Map<String, Object>> maps = tools.executeQuery("select *from user");
//转List
for (Map<String, Object> temp : maps) {
UserBean bean = getUserBean(temp);
beans.add(bean);
}
return beans;
}
//map 转 bean 方法
private UserBean getUserBean(Map<String, Object> temp) {
UserBean bean = new UserBean();
bean.setId((Integer) temp.get("id"));
bean.setName((String) temp.get("name"));
bean.setPwd((String) temp.get("pwd"));
return bean;
}
//通过ID查询
public UserBean queryUserByID(Integer id) throws SQLException {
List<Map<String, Object>> maps = tools.executeQuery("select *from user where id = ?", id);
//转List
for (Map<String, Object> temp : maps) {
UserBean bean = getUserBean(temp);
return bean;
}
return null;
}
//登录认证
public UserBean checkLogin(UserBean login) throws SQLException {
List<Map<String, Object>> maps = tools.executeQuery("select *from user where name = ? and pwd = ?", login.getName(), login.getPwd());
for (Map<String, Object> temp : maps) {
UserBean bean = getUserBean(temp);
return bean;
}
return null;
}
//通过名字查询
public UserBean queryUserByName(String name) throws SQLException {
String sql = "select *from user where name = ?";
List<Map<String, Object>> maps = tools.executeQuery(sql, name);
if (!maps.isEmpty()){
return getUserBean(maps.get(0));
}
return null;
}
}
UserService:
Replace the original use JDBC place, instead use UserDao to complete the database operation
package com.kkb.srvices;
import com.kkb.exceptions.LoginException;
import com.kkb.models.UserBean;
import com.kkb.models.UserDao;
import java.sql.*;
//用来处理与用户相关的业务逻辑
public class UserService {
private UserDao dao;
public UserService() throws ClassNotFoundException {
this.dao = new UserDao();
}
//用于检查登录的方法
public UserBean checkLogin(UserBean reqBean) throws LoginException {
//判断参数是否有效
if(reqBean.getName() == null || reqBean.getPwd() == null ||
reqBean.getName().equals("") || reqBean.getPwd().equals("")
){
throw new LoginException("用户名或密码不能为空!");
}else {
try {
UserBean bean = dao.checkLogin(reqBean);
if(bean != null)
return bean;
else
throw new LoginException("用户名或密码错误!");
} catch (SQLException e) {
e.printStackTrace();
throw new LoginException("数据库炸了!");
}
}
}
}
Thus, on the use of DAO (Data Access Objects), coupled to understanding of Service layer, to improve the maintainability of the code, but the complexity of the corresponding program also increased
Emphasize:
The DAO methods are not fixed according to the specific business requirements to design
MVC + DAO implementation process:
Factories and interfaces it?
Design patterns like a double-edged sword, bringing scalability, and maintainability, and so on and so on edge, adding design patterns also make the program even more complicated
We have to do is to use the right mode at the right design projects
The above case is not used in factories and interfaces, Shashi Hou to use it?
analysis:
When the project development to the late, the company has earned a lot of money, and want to replace more powerful Oracle database, oracle sql is slightly different, and had to re-write a new set of DAO implementation, after finishing you had to find all use the UserDao place, all changes again, the first time you cry ...
Smart you will not let yourself when this happens again, then you ........ quit!
to sum up:
Because all the same between the two methods, only the different SQL statements, so an interface for extracting them, and then define a class factory for creating an object in the future to replace the implementation class time, modify the factory class can be replaced to achieve the Dao class
FIG overall structure:
If the last in a configuration file, so Factory to acquire Dao configuration file type needs to be created, that will be perfect!
Here MVC + Service + DAO design pattern to get away
Request a plurality of different processing functions Servlet
Wait, I vaguely remember what the problem is not solved in the first chapter?
In fact, this problem solution is simple:
First request to be processed is mapped to the Servlet, and then in the Servlet to select a corresponding processing method according to the request path,
Of course, a method how to match the path corresponding to the different methods is also
Servlet is determined directly in the path and then calls the method (comparative low)
Reflected by the method, and to find the path matching (same method name, limitations)
You can take, can provide a path (flexible, high) + annotation with annotations by reflection, method name
The third method is employed SpringMVC
Is not want to write a MVC framework? Come on show in