DAO設計 :
DAO層主要是做數據持久層的工作,負責與數據庫進行聯絡的一些任務都封裝在此,DAO層的設計首先是設計DAO的接口,然后在Spring的配置文件中定義此接口的實現類,然后就可在模塊中調用此接口來進行數據業務的處理,而不用關心此接口的具體實現類是哪個類,顯得結構非常清晰,DAO層的數據源配置,以及有關數據庫連接的參數都在Spring的配置文件中進行配置。
在該層主要完成對象-關系映射的建立,通過這個映射,再通過訪問業務對象即可實現對數據庫的訪問,使得開發中不必再用SQL語句編寫復雜的數據庫訪問程序,這樣就簡化了對數據庫的訪問,提高了開發效率。同時通過對象-關系映射的配置,可以建立業務對象之間的復雜關系,如一對多、多對一、一對一、多對多等關系。這樣就不再需要在數據庫中建立表之間的復雜聯系,使得業務對象之間的關系和數據庫相分離,簡化了數據庫的建立和維護。在這一層中主要使用Hibernate框架來實現。
針對以上問題,產生了基于MVC模式Model層的DAO模式(Data Access Object),主要由工廠類(Factory)、代理類(Proxy)、實現類(DAOImpl)、DAO接口和值對象類(VO)以及數據庫連接類組成。
這里總結一下MVC+DAO的設計流程。通過MVC+DAO的設計模式,可以使項目在設計過程中結構更為明晰,并且能夠方便的進行修改。MVC是一個分層模型,即模型、視圖、控制器。DAO是一個數據庫訪問模型,隔離數據庫操作。
環境說明:
數據庫:mysql
開發語言:JSP + Servlet + Java
服務器:tomcat 7.x
包規劃:
entity 放置與數據庫中的表相對應的實體類
dao 放置DAO設計模式下實現訪問數據庫的接口
dao.impl 放置DAO對應的接口實現類
servlet 放置Servlet
util 工具包
設計流程綜述:
0.設計數據庫以及視圖頁面(VIEW)
1.設計數據庫的工具類
2.設計符合java bean標準的entity類 (MODEL)
3.設計訪問數據庫的DAO接口
4.設計實現DAO接口的實現類
5.創建Servlet響應請求(CONTROLLER)
例子:以一個簡單的登錄頁面設計為例
0.設計數據庫以及視圖頁面
數據庫設計:
1
2
3
4
5
6
|
CREATE TABLE `NewTable` ( `id` int (10) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT , ` name ` varchar (10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL , ` password ` varchar (10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL , PRIMARY KEY (`id`) ) |
頁面視圖:
index.jsp的核心代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
< form action = "/iMath/servlet/AdminServlet?method=login" method = "post" > < table border = '1' align = "center" > < caption >USER LOGIN</ caption > < tr > < th >username</ th > < th >< input type = "text" name = "username" /></ th > </ tr > < tr > < th >password</ th > < th >< input type = "password" name = "password" /></ th > </ tr > < tr > < td colspan = "2" align = "center" >< input type = "submit" value = "submit" /></ td > </ tr > </ table > </ form > |
核心代碼就是一個form表單,用于提供視圖,為用戶提供輸入的接口。核心是指定action和method屬性。這應該是最簡單的一步,下面的工作則進入真正的代碼編寫階段。
轉發頁面:
message.jsp核心代碼如下:其實就句話
1
2
3
|
< body > ${message} </ body > |
1.設計數據庫的工具類
這步的操作應該是大同小異的,目的只是抽取公共代碼,簡化程序流程。
dbConfig.properties 文件存放數據庫的配置文件,這么做的優點的是可以項目編譯后也能方便的修改數據庫配置的相關信息。
1
2
3
4
|
driver = com.mysql.jdbc.Driver url = jdbc:mysql://127.0.0.1:3306/imath?useUnicode=true&characterEncoding=utf-8 user = root password =1234 |
DBUtil類設計:該類用實現建立數據庫連接和關閉數據庫連接的公共操作。
代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
package cn.imath.util; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public final class DBUtil { private static String driver; private static String url; private static String user; private static String password; /** * load the property file */ static { Properties props = new Properties(); //get the class loader InputStream is = DBUtil. class .getClassLoader().getResourceAsStream( "cn/imath/util/dbConfig.properties" ); try { props.load(is); } catch (Exception e) { e.printStackTrace(); } driver = props.getProperty( "driver" ); url = props.getProperty( "url" ); user = props.getProperty( "user" ); password = props.getProperty( "password" ); } /** * register the driver */ static { try { Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * OPEN THE DATABASE CONNECTION * @return */ public static Connection getConn(){ Connection conn = null ; try { conn = DriverManager.getConnection(url, user, password); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * CLOSE THE DATABASE CONNECTION * @param rs */ public static void closeAll(ResultSet rs,Statement stmt,Connection conn){ close(rs); close(stmt); close(conn); } public static void close(ResultSet rs){ if (rs!= null ){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void close(Statement stmt){ if (stmt!= null ){ try { stmt.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void close(Connection conn){ if (conn!= null ){ try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } } } |
這里要注意的是:導入的包均為java.sql包。這里建立了兩個核心方法,后面會經常用到 getConn() 和 closeAll()方法,分別用于取得數據庫連接和關閉數據庫連接。
2.設計符合java bean標準的entity類
這里的entity類對應于上面的admin表。因此設計Admin類如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package cn.imath.entity; public class Admin { private int id; private String name; private String password; public int getId() { return id; } public void setId( int id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getPassword() { return password; } public void setPassword(String password) { this .password = password; } } |
entity類的設計是為了實現對數據的封裝,只要對照數據庫設計來就行,然后最好符合java bean的設計標準,用getter/setter實現訪問。
3.設計訪問數據庫的DAO接口
dao接口的設計非常簡單,目的是為后面的具體的業務方法提供一個模版。
AdminDao接口如下:
1
2
3
4
5
6
7
8
9
10
11
|
package cn.imath.dao; import cn.imath.entity.Admin; public interface AdminDao { /** * LOGIN METHOD * @param username * @param password * @return INSTANCE OF Admin */ public Admin login(String username,String password); } |
4.設計實現DAO接口的實現類
接下來設計上面DAO接口的實現類,用于實現具體的業務。這里就能體現上面模版的作用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package cn.imath.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import cn.imath.dao.AdminDao; import cn.imath.entity.Admin; import cn.imath.util.DBUtil; public class AdminDaoImpl implements AdminDao { /** * LOGIN METHOD */ public Admin login(String username, String password) { String sql = "select * from admin where name=? and password=? " ; Connection conn = DBUtil.getConn(); try { PreparedStatement pstmt = conn.prepareStatement(sql); //set the query parameters pstmt.setString( 1 ,username); pstmt.setString( 2 , password); ResultSet rs = pstmt.executeQuery(); if (rs.next()){ int id = rs.getInt( 1 ); Admin ad = new Admin(); ad.setId(id); ad.setPassword(password); ad.setName(username); return ad; } } catch (SQLException e) { e.printStackTrace(); } return null ; } } |
dao的實現類實現了具體的業務方法,封裝了sql的相關操作。
5.創建Servlet響應請求
Servlet負責處理請求。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package cn.imath.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.imath.dao.AdminDao; import cn.imath.dao.impl.AdminDaoImpl; import cn.imath.entity.Admin; public class AdminServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding( "utf-8" ); String method = request.getParameter( "method" ); if (method!= null ){ if ( "login" .equals(method)){ this .login(request,response); } } } private void login(HttpServletRequest request, HttpServletResponse response) { String username = request.getParameter( "username" ); String password = request.getParameter( "password" ); AdminDao dao = new AdminDaoImpl(); Admin ad = dao.login(username, password); if (ad!= null ){ request.setAttribute( "message" , "Login Success" ); } else { request.setAttribute( "message" , "Login Failed" ); } try { request.getRequestDispatcher( "/message.jsp" ).forward(request, response); } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } |
這里將login方法獨立于doPost方法,這樣有助于對功能的擴充。
這里介紹的只是MVC+DAO的設計流程,通過這種模式可以改進項目的設計,使項目結構更為清晰,有了合理的方法,具體的項目才不致太混亂。最后,說一下需要改進的地方:
1.數據庫的連接控制,可以用連接池進行改進,如DBCP或C3P0
2.數據庫操作可以用common dbutils進行改進
總結
以上就是本文關于MVC+DAO設計模式下的設計流程詳解的全部內容,希望對大家有所幫助。有什么問題,可以隨時留言指出。感謝大家!
原文鏈接:http://blog.csdn.net/tao_sun/article/details/19124853