前言
在這篇文章中,我們將使用Spring搭配Hibernate來建構Web站台,以DAO(Data Access Object;資料存取物件)的方式透過Hibernate存取資料庫的數据。使用的工具&技術:
1.JDK1.7.0_04
2.Hibernate 3.2.3.GA
3.JBoss Hibernate Tools
4.Spring3.0.7
5.MySQL 5.5
6.Eclipse Java EE KEPLER
創建一個MySpringHiber的Web專案
這個小節中,我們需要根據圖1.中的的目錄資料結構,來分別建立本專案中各個重要的程式檔案。並且會逐步說明每支程式的關鍵內容明細的組成部份。
圖1.MySpringHiber專案結構
第一步,下載Spring 3.0.7與Hibernate 3.2.3ga版本的相關jar檔。
Spring部份的主要jar
com.springsource.org.aopalliance-1.0.0.jar
org.springframework.aop-3.0.7.RELEASE.jar
org.springframework.asm-3.0.7.RELEASE.jar
org.springframework.aspects-3.0.7.RELEASE.jar
org.springframework.beans-3.0.7.RELEASE.jar
org.springframework.context.support-3.0.7.RELEASE.jar
org.springframework.context-3.0.7.RELEASE.jar
org.springframework.core-3.0.7.RELEASE.jar
org.springframework.expression-3.0.7.RELEASE.jar
org.springframework.jdbc-3.0.7.RELEASE.jar
org.springframework.orm-3.0.7.RELEASE.jar
org.springframework.oxm-3.0.7.RELEASE.jar
org.springframework.transaction-3.0.7.RELEASE.jar
org.springframework.web.servlet-3.0.7.RELEASE.jar
org.springframework.web-3.0.7.RELEASE.jar
Hibernate部份的主要jar
antlr-2.7.6.jar
cglib-2.1.3.jar
dom4j-1.6.1.jar
hibernate3.jar
javassist.jar
jta.jar
其他必要的jar
mysql-connector-java-5.0.5-bin.jar
commons-logging-1.1.1.jar
commons-collections-2.1.1.jar
commons-dbcp.jar
commons-pool.jar
slf4j-api-1.7.5.jar
slf4j-jdk14-1.7.5.jar
log4j-1.2.11.jar
第二步,建立applicationContext.xml的spring的設定檔。注意代碼內的注解說明文字,主要設定內容的重點 ,可以分為dataSource(數据來源), sessionFactory, TransactionManager, Spring Bean的元件自動搜尋注入。
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 | <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" default-autowire="byName" default-lazy-init="false"> <!-- 數据來源定義 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="mysql"/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingLocations" value="classpath*:com/yourcompany/msh/domain/*.hbm.xml"/> <property name="hibernateProperties"> <props> <!--常用資料庫方言 MySQL5Dialect --> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.query.substitutions">true 1, false 0</prop> <prop key="hibernate.default_batch_fetch_size">4</prop> <prop key="hibernate.connection.zeroDateTimeBehavior">convertToNull</prop> </props> </property> </bean> <!--Hibernate TransactionManager--> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 以 @Transactional 標注来定義交易事務 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> <!-- component-scan自動搜索@Component , @Controller , @Service , @Repository等標注的類別 --> <context:component-scan base-package="com.**.dao" /> <context:component-scan base-package="com.**.service" /> </beans> |
第三步,修正Web.xml的檔案內容。設置Spring ApplicationContext配置文件的路徑,此參數用於後面的Spring-Context loader,然後建立一支TestSpring的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 | <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- Spring ApplicationContext配置文件的路徑,此參數用於後面的Spring-Context loader --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring/*.xml</param-value> </context-param> <!--Spring ApplicationContext 載入 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>TestSpring</servlet-name> <servlet-class>com.yourcompany.msh.test.TestSpring</servlet-class> </servlet> <servlet-mapping> <servlet-name>TestSpring</servlet-name> <url-pattern>/TestSpring</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> |
而後移除以下的程式碼:
1 2 3 4 5 6 7 8 9 10 11 | private final SessionFactory sessionFactory = getSessionFactory(); protected SessionFactory getSessionFactory() { try { return HibernateUtil.getSessionFactory(); } catch (Exception e) { log.error("Could not build SessionFactory", e); throw new IllegalStateException( "Could not build SessionFactory"); } } |
再把sessionFactory變數全部由getSessionFactory()方法取代:
Before
1 | sessionFactory.getCurrentSession().persist(transientInstance); |
After
1 | getSessionFactory().getCurrentSession().persist(transientInstance); |
第五步,重新改寫UserInfoManager的代碼。
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 | package com.yourcompany.msh.service; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.yourcompany.msh.dao.UserInfoHome; import com.yourcompany.msh.domain.UserInfo; @Service @Transactional public class UserInfoManager { private UserInfoHome userInfoHome; public void setUserInfoHome(UserInfoHome userInfoHome) { this.userInfoHome = userInfoHome; } /** * 查詢 */ public UserInfo query(Integer pk) { return (UserInfo)userInfoHome.findById(pk); } /** * 新增 */ public void add(UserInfo user) { userInfoHome.persist(user); } /** * 修改 */ public void update(UserInfo user) { userInfoHome.merge(user); } /** * 刪除 */ public void delete(UserInfo user) { userInfoHome.delete(user); } } |
第六步,寫一支TestSpring來測試Spring結合Hibernate操作資料表。
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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | package com.yourcompany.msh.test; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.support.SpringBeanAutowiringSupport; import com.yourcompany.msh.domain.UserInfo; import com.yourcompany.msh.service.UserInfoManager; public class TestSpring extends HttpServlet { @Autowired private UserInfoManager userInfoManager; /** * Constructor of the object. */ public TestSpring() { super(); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init(ServletConfig config) throws ServletException { SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,config.getServletContext()); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doit(request,response); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doit(request,response); } public void doit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet For Spring</TITLE></HEAD>"); out.println(" <BODY>"); UserInfo user = null; // 查詢 user = userInfoManager.query(new Integer(1)); out.println("查詢一筆記Username: "+user.getUsername()); // 新增 /*user = new UserInfo("Linda", "da67890", new Date(), new Integer(0), new Integer(32)); userInfoManager.add(user); out.println("新增一筆記"+user.getUsername()+"成功");*/ // 修改 /*user = userInfoManager.query(new Integer(2)); user.setUsername("Marry"); user.setSex(new Integer(0)); //更新為女性 user.setAge(new Integer(37)); //更新為37歲 out.println("修改一筆記"+user.getUsername()+"成功");*/ // 刪除 /*user = userInfoManager.query(new Integer(2)); out.println("刪除一筆記"+user.getUsername()+"成功");*/ out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } } |
總結
想要建立一個Spring結合Hibernate的Web專案,需要先具備這兩個框架的基礎知識,這樣才能讓我們更精確有效的建製整個案子的基礎架構。
(下載本文範例程式檔) 記得下載相關jar檔