關于使用Spring和hibernate開發web程序的配置說明和簡單實例的詳細說明
關于使用Spring和hibernate開發web程序的配置說明和簡單實例的詳細說明
作者:yanek
email:yanek@126.com
一、實現目標:
通過使用spring和hibernate,實現用戶的添加功能。把用戶信息加入到數據庫中
使用Spring 的hibernate模板實現DAO操作。
最終效果: 瀏覽器中輸入 http://localhost:8083/hibernateTestWeb/user.do 數據庫就增加一條記錄。
二、分層結構
系統采用如下分層結構
1.WEB層:用戶界面層? 采用spring WEB MVC框架實現
2 SERVICE層:業務邏輯層 包括業務接口和實現類組成
3.DAO層: 數據訪問層??? 包括數據訪問接口和實現類組成
4.持久層:使用hibernate實現 使用hibernate實現數據庫的訪問。實現DAO接口。
三、數據庫結構
數據庫結構:USER_TABLE 表
建表sql語句
create table USER_TABLE
(
? ID?????? VARCHAR2(255) not null,
? USERNAME VARCHAR2(20),
? PASSWORD VARCHAR2(20)
)
假設使用的是數據庫:oracle9i
用戶名 密碼為test/1234
四、系統設計的相關類及其層次結構
1. User.java? 表示用戶實體的值對象類,與數據庫用戶表結構相對應,標準的javabean,提供setter和getter方法。
2. UserDAO.java? DAO接口
3. UserDAOImp.java? DAO接口的實現類
4. UserService?? 業務邏輯層的接口
5. UserServiceImp 業務邏輯層的接口的實現類,調用DAo接口實現業務邏輯。
6. UserController web層客戶調用層,調用業務邏輯層,實現對業務邏輯的處理。(前臺)
五、相關配置文件:(重點,問題出錯的地方)
包括Spring 的配置文件和hibernate配置文件,以及web.xml文件
說明:
web.xml,applicationContext.xml,SpringhibernateStudy-servlet.xml都在WEB-INF根目錄下,映射文件在與實體類相同的目錄下
?
1.Spring 的配置文件:
這里配置文件包括兩個:
1.applicationContext.xml??? 對數據源,事務,事務代理,DAO ,Service層類進行定義和配置
內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> ? ???</list> ? ??<property name="hibernateProperties"> ? <bean id="UserDAO" class="apps.hibernatetest.ioc.UserDAOImp"> ? <bean id="mytransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> ? <bean id="MyTransactionProxyFactory" abstract="true" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> </beans>
注意:這里名稱要與在web.xml中對org.springframework.web.servlet.DispatcherServlet的對應servlet名稱對應。 這里web.xml文件里配置了名字為SpringhibernateStudy,所以文件名必須為:SpringhibernateStudy-servlet.xml 格式:servlet名稱+-servlet.xml? 如果配置名稱為SpringServlet則,配置文件應該為:SpringServlet-servlet.xml 內容如下: <?xml version="1.0" encoding="UTF-8"?> ? <!-- 下面定義web層控制器類,引用到業務處理類,通過已經定義的service類來自動注入web控制器引用的service類-->
? ? 2.hibernate配置文件: 這里主要是映射文件 :User.hbm.xml 與表USER_TABLE 對應 名稱為:User.hbm.xml? 詳細配置代碼如下: <?xml version="1.0"?> ??? <class name="apps.hibernatetest.ioc.User" table="USER_TABLE"> ?????? <property name="username" type="string"> ????? <property name="password" type="string"> ??? </class> </hibernate-mapping>
1.類名一定要寫完整路徑帶包名 ?????????? 如:User.java的完整路徑為apps.hibernatetest.ioc.User,對應配置如下 ? ??<property name="mappingResources"> ? ???</list> ? 用hibernate往數據庫里插入數據時,出現net.sf.hibernate.MappingException: No persister for的解決辦法
這里對servlet等信息配置: <?xml version="1.0" encoding="UTF-8"?> ? ? <listener> ? <servlet>
</web-app>
1. User.java? 表示用戶實體的值對象類,與數據庫用戶表結構相對應,標準的javabean,提供setter和getter方法。 注意: 1.提供setter和getter方法,符合javabean規范
package apps.hibernatetest.ioc; public class User implements java.io.Serializable ??????????? public User(){} ??????????? public String getId() ??????????? public void setId(String id) ??????????? public String getUsername() ??????????? public void setUsername(String username) ??????????? public String getPassword() ??????????? public void setPassword(String password)
? 2. UserDAO.java? DAO接口
public interface UserDAO ? ? 3. UserDAOImp.java? DAO接口的實現類
1. 繼承HibernateDaoSupport UserDAOImp.java package apps.hibernatetest.ioc; import org.springframework.orm.hibernate.HibernateCallback; public class UserDAOImp extends HibernateDaoSupport? implements UserDAO ? } ?
UserService.java package apps.hibernatetest.ioc; public interface UserService ? public void userAdd(User user);
注意: 1.實現指定的service接口 ? private UserDAO userDAO; UserServiceImp.java
public class UserServiceImp implements UserService ?
UserController.java package apps.hibernatetest.ioc; import org.springframework.context.ApplicationContext; public class UserController implements Controller ? public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException ??????????? User u=new User(); }
1.實現Controller接口
??????????? String url="";
需要導入如下主要的jar包:
http://www.e-jrsj.com/hibernatetest.rar
? 九、在main方法中對在配置文件中的javabean類方法測試的代碼:
package apps.hibernatetest.ioc; import org.springframework.beans.factory.BeanFactory; public class Test ? public static void main(String[] args) ??? Resource resource = new ClassPathResource("applicationContext.xml"); ??? UserService service = (UserService) factory.getBean("userService"); ??? System.out.println("tettet"); ??? service.userAdd(u); ?
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "
<beans>
<!-- 下面定義數據庫的連接信息,使用類為org.apache.commons.dbcp.BasicDataSource-->
??? <property name="driverClassName">
???????? <value>oracle.jdbc.driver.OracleDriver</value>
???? </property>
???
??? <property name="url">
??? ?<value>jdbc:oracle:thin:@192.168.1.191:1521:yanek</value>
??? </property>
??? <property name="username">
??? ?<value>test</value>
??? </property>
??? <property? name="password">
??? ?<value>1234</value>
??? </property>
???
? </bean>
?
?
?
<!-- 下面定義sessionFactory來為創建session做準備-->
?
? <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
? ??<property name="dataSource">
? ???<ref local="dataSource" />
? ??</property>
?
? ??<property name="mappingResources">
? ???<list>
? ????<value>apps/hibernatetest/ioc/User.hbm.xml</value>
? ??</property>
? ???<props>
? ?????? <prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop>
? ?????? <prop key="hibernate.show_sql">true</prop>
? ?????? <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
? ???</props>
? ??</property>
? </bean>
?
?
?<!-- 下面定義hibernate模板 -->
?
? <bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate">
??? <property name="sessionFactory">
????? <ref local="sessionFactory" />
???? </property>
? </bean>
?
?
? <!-- 下面定義用戶定義的DAO,指定了DAO的實現類,dao實現引用到hibernate模板-->
??? <property name="hibernateTemplate">
?????? <ref local="hibernateTemplate" />
???? </property>
? </bean>
?
??? <!-- 下面定義事務管理器類,引用到sessionFactory-->
??? <property name="sessionFactory">
?????? <ref local="sessionFactory"/>
??? </property>
? </bean>
?
?
????? <!-- 下面定義事務代理工廠類類,引用到事務管理器,指定調用方法使用事務處理的匹配規則-->
?
??? <property name="transactionManager">
????? <ref local="mytransactionManager"/>
??? </property>
??? <property name="transactionAttributes">
????? <props>
???????? <prop key="user*">PROPAGATION_REQUIRED</prop>
???????? <prop key="insert*">PROPAGATION_REQUIRED</prop>
???????? <prop key="del*">PROPAGATION_REQUIRED</prop>
???????? <prop key="up*">PROPAGATION_REQUIRED</prop>
???????? <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
???????? <prop key="dis*">PROPAGATION_REQUIRED,readOnly</prop>
????? </props>
??? </property>
? </bean>
?
?
? <!-- 下面定義業務邏輯類,引用到事務管理器,通過已經定義的DAO來自動注入業務邏輯類引用的DAO類-->
?
?
?? <bean id="userService" parent="MyTransactionProxyFactory">
?? ??<property name="target">
?? ???<bean class="apps.hibernatetest.ioc.UserServiceImp">
?? ????<property name="userDAO"><ref local="UserDAO"/></property>
?? ???</bean>
?? ??</property>
?? </bean>
2.SpringhibernateStudy-servlet.xml? 主要對mvc web層的javabean定義
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "<!--? - Application context definition for "springapp" DispatcherServlet.? -->
<beans>?
?
?? <bean id="UserController" class="apps.hibernatetest.ioc.UserController">??
??? <property name="userService">
? <ref bean="userService" />
? </property>
? </bean>
?
?
??? <!-- 下面定義web層請求訪問路徑和控制器類的影射關系以及對請求方式處理類的類配置的方法-->
?
?? <bean id="UserurlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
?<property name="mappings">?????
??<props>
???<prop key="/user.do">UserController</prop>
???
??? <!-- 這里表示 //user.do會由 名稱為UserController的對應的控制器來apps.hibernatetest.ioc.UserController處理-->
??</props>
?</property>
?? </bean>
?
</beans>??
<!DOCTYPE hibernate-mapping
??? PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
??? "<hibernate-mapping>
?????? <id name="id" type="string" unsaved-value="null">
?????????? <column name="ID" sql-type="varchar2(255)" not-null="true" />
?????????? <generator class="uuid.hex"/>
?????? </id>
?????????? <column name="USERNAME" sql-type="varchar2(20)"/>
?????? </property>
?????????? <column name="PASSWORD" sql-type="varchar2(20)"/>
?????? </property>
注意:
2.對應的數據庫表明一定要與數據庫一致
?? 如: <class name="apps.hibernatetest.ioc.User" table="USER_TABLE">
???
??? name屬性為:實體類名
??? table屬性為:數據庫表的名稱
???
3.其字段信息要與數據庫表結構一致
4.該配置文件放在與實體類相同的目錄中,并在spring文件中給與說明
? ???<list>
? ????<value>apps/hibernatetest/ioc/User.hbm.xml</value>
? ??</property>
根據我的出錯處理經驗,出現No persister for錯誤后有如下三種解決辦法:
1》檢查hbm.xml文件。
2》檢查cfg.xml文件,看看類的hbm.xml文件名是不是已經寫上了。
3》對于one-to-many(Parent-to-Child)的關系,應該是
child.setParent(parent),而不是child.setParent(parent.id)
???
???
3. web.xml文件:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "<web-app>
??? <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
? </listener>
? <servlet>
?
??? <servlet-name>ContextLoaderServlet</servlet-name>
??? <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
??? <load-on-startup>1</load-on-startup>
? </servlet>
?
?
???? <!-- 上面定義監聽器和上下文裝載的servelet,來裝載applicatincontext.xml文件 -->
?
?
?
???? <!-- 下面定義配置Spring的請求分發器類-->
? <servlet>
??? <servlet-name>SpringhibernateStudy</servlet-name>
??? <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
??? <load-on-startup>2</load-on-startup>
? </servlet>
??? <servlet-name>debugjsp</servlet-name>
??? <description>Added to compile JSPs with debug info</description>
??? <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
??? <init-param>
????? <param-name>classdebuginfo</param-name>
????? <param-value>true</param-value>
??? </init-param>
??? <load-on-startup>3</load-on-startup>
? </servlet>
?
???? <!-- 下面定義配置Spring的請求分發器將處理所有*.do的請求-->
? <servlet-mapping>
??? <servlet-name>SpringhibernateStudy</servlet-name>
??? <url-pattern>*.do</url-pattern>
? </servlet-mapping>
?
? <servlet-mapping>
??? <servlet-name>debugjsp</servlet-name>
??? <url-pattern>*.jsp</url-pattern>
? </servlet-mapping>
六、相關各個類的詳細代碼極其說明
2.實現java.io.Serializable可序列化接口。
3.與數據庫表結構一一對應
User.java
{
??????????? private String id;
??????????? private String username;
??????????? private String password;
??????????? {
????????????????????? return id;
??????????? }
??????????? {
????????????????????? this.id = id;
??????????? }
??????????? {
????????????????????? return username;
??????????? }
??????????? {
???????????????????? this.username = username;
??????????? }
??????????? {
????????????????????? return password;
??????????? }
??????????? {
????????????????????? this.password = password;
??????????? }
}
UserDAO.java
package apps.hibernatetest.ioc;
{
??? public void userAdd(User user);
}
注意:
2. 實現dao接口
3.使用模板類處理數據
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
{
? public void userAdd(User user)
? {
??????? //try
?????? // {
??????????? //System.out.println("save="+getHibernateTemplate().save(user));
??????????? System.out.println("aaa====>"+user.getUsername());
??????????? System.out.println("bbb====>"+user.getPassword());
??????????? getHibernateTemplate().save(user);
??????????? System.out.println("bbb");
?????? /* }
??????? catch(Exception? e)
??????? {
???????????? System.out.println("執行插入用戶錯誤!");
??????? }*/
? }
4. UserService?? 業務邏輯層的接口
{
}
5. UserServiceImp 業務邏輯層的接口的實現類,調用DAO接口實現業務邏輯。
2.接口實現調用DAO接口
3.必須有userDAO屬性,并提供setter方法,如下
? public UserDAO getUserDAO()
? {
??????? return userDAO;
? }
? public void setUserDAO(UserDAO userDAO)
? {
??????? this.userDAO = userDAO;
? }
?
? 在配置文件中,通過配置自動實現DAO屬性的自動注入。
?
? 通過這樣來定義service業務類和DAO的依賴關系
?
?
package apps.hibernatetest.ioc;
{
? private UserDAO userDAO;
? private User user = new User();
? public UserDAO getUserDAO()
? {
??????? return userDAO;
? }
? public void setUserDAO(UserDAO userDAO)
? {
??????? this.userDAO = userDAO;
? }
? public void userAdd(User user)
? {
????? userDAO.userAdd(user);
? }
}
6. UserController web層客戶調用層,調用業務邏輯層,實現對業務邏輯的處理。(前臺)
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.*;
import javax.servlet.http.*;
import org.springframework.web.bind.RequestUtils;
import java.io.IOException;
import java.util.Map;
import java.util.*;
import java.util.HashMap;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;
{
? private UserService userService;
? public void setUserService(UserService userService)
? {
??????? this.userService = userService;
? }
?{
??????????? String url="";
??????????? url="addok.jsp";
??????????? u.setUsername("aaa");
??????????? u.setPassword("bbbb");
??????????? userService.userAdd(u);
??????????? return new ModelAndView(url);
?}
注意:
2.提供私有屬性,并提供setter方法
如下代碼
? private UserService userService;
? public void setUserService(UserService userService)
? {
??????? this.userService = userService;
? }
?
?3.在控制器在handleRequest中調用屬性userService調用業務邏輯。
?
?
??????????? User u=new User();
??????????? u.setUsername("aaa");
??????????? u.setPassword("bbbb");
??????????? userService.userAdd(u);
???????????
4. 定義url變量,設置其值,作為ModelAndView類的構造函數的參數,作為業務邏輯處理完后的跳轉地址
??????????? url="addok.jsp";
??????????? return new ModelAndView(url);
???????????
???????????
?
???????????
???????????
七,相關項目說明:
調試環境:jbulder9.0
spring.jar
hibernate.java
dhcp.java
classes12
等等
八、代碼下載:
注意:applicationContext.xml文件放在classes根目錄下
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
{
? {
?
?
?? //根據配置文件得到beanFactory(bean工廠)
??? BeanFactory factory = new XmlBeanFactory(resource);
???
???
??? //下面通過bean工廠從配置文件中得到實例化的bean,并轉換為相應的接口
???
??? UserDAO dao = (UserDAO) factory.getBean("UserDAO");??
???
??? /*
????? <bean id="UserDAO" class="apps.hibernatetest.ioc.UserDAOImp">
??? <property name="hibernateTemplate">
?????? <ref local="hibernateTemplate" />
???? </property>
??? </bean>
? */
???
???
???
??? /*
????? 對應配置文件
?????? <bean id="userService" parent="MyTransactionProxyFactory">
?? ??<property name="target">
?? ???<bean class="apps.hibernatetest.ioc.UserServiceImp">
?? ????<property name="userDAO"><ref local="UserDAO"/></property>
?? ???</bean>
?? ??</property>
????? </bean>
??? */
???
???
???
???
??? User u=new User();
??? u.setUsername("aaa");
??? u.setPassword("bbbb");
??? dao.userAdd(u);
? }
}