關于JSF1.2 + Spring2.5 + Hibernate3 + Facelets + Annotation整合配置的參考。
提供一個整合JSF,Spring, Hibernate(JPA), Facelets, 及Annotation的基礎環境。對于剛開始使用這種組合的項目,或許可以參考一下,相信使用以上整合環境的項目還是比較少。我一直很喜歡這種組合,JSF組件式的開發,Spring, Hibernate對BackingBean及數據源的管理,Facelets的模版化技術,以及Annotation都大大簡化了開發。JSF組件的高度封裝及高可重用性,使得頁面代碼在非常簡單的情況下快速實現非常復雜的功能。Spring,Hibernate的整合進一步簡化了JSF的開發,特別是Annotation的配置使得現在幾乎完全不需要去XML中配置Bean這些繁瑣的事情,這確實很繁瑣,特別是如果再加上配置JSF的導航規則,在開發過程中經常要去碰這些東西,確實很麻煩,又容易出錯。所以如果項目允許,還是推薦使用Annotation,并且這也是很多專家推薦的。作為Java5新加入的特性,它確實對開發帶來了很大的方便,以前不怎么喜歡,不過現在感覺它很有前途!另一個就是Facelets了,這可是用來替代JSP的視圖描述技術,Facelets模版化的威力可是非常強大,雖然不少人認為它的自定義標簽功能更強大,具體介紹還是大家網上搜一下吧。下面看一下大概的配置過程,僅供參考,因為網上也有不少類似的教程,所以不作啰嗦,僅取重點。
環境:Netbeans7, Tomcat6.0.18, MySQL5
相關框架:JSF1.2,Spring2.5,Hibernate3(JPA), Facelets, Annotation, MyFaces(附加), QFaces(附加)
1.相關引用的jar包


可以看到引用的jar還是不少,至少加起來有43.2M。最后一個是我自定義的組件包qfaces-1.2.1,剛升級支持Facelets(qfaces在1.2及之前未能夠支持Facelets而沒有說明,使一些用Facelets的朋友遇到麻煩,這里道歉哦。)
2.web.xml文件配置
1 <?xml version="1.0" encoding="UTF-8"?>
2 <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">
3 <context-param>
4 <param-name>com.sun.faces.verifyObjects</param-name>
5 <param-value>false</param-value>
6 </context-param>
7 <context-param>
8 <param-name>com.sun.faces.validateXml</param-name>
9 <param-value>true</param-value>
10 </context-param>
11 <context-param>
12 <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
13 <param-value>client</param-value>
14 </context-param>
15
16 <!-- Config:Facelets -->
17
18 <context-param>
19 <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
20 <param-value>.xhtml</param-value>
21 </context-param>
22
23 <!-- Config:Spring -->
24
25 <servlet>
26 <servlet-name>dispatcher</servlet-name>
27 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
28 <load-on-startup>2</load-on-startup>
29 </servlet>
30 <servlet-mapping>
31 <servlet-name>dispatcher</servlet-name>
32 <url-pattern>*.htm</url-pattern>
33 </servlet-mapping>
34 <listener>
35 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
36 </listener>
37 <listener>
38 <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
39 </listener>
40 <listener>
41 <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
42 </listener>
43 <listener>
44 <listener-class>com.sun.faces.application.WebappLifecycleListener</listener-class>
45 </listener>
46
47 <!-- Config:MyFaces -->
48
49 <filter>
50 <filter-name>MyFacesExtensionsFilter</filter-name>
51 <filter-class>
52 org.apache.myfaces.webapp.filter.ExtensionsFilter
53 </filter-class>
54 <init-param>
55 <param-name>uploadMaxFileSize</param-name>
56 <param-value>100m</param-value>
57 </init-param>
58 <init-param>
59 <param-name>uploadThresholdSize</param-name>
60 <param-value>80k</param-value>
61 </init-param>
62 </filter>
63 <filter-mapping>
64 <filter-name>MyFacesExtensionsFilter</filter-name>
65 <servlet-name>Faces Servlet</servlet-name>
66 </filter-mapping>
67 <filter-mapping>
68 <filter-name>MyFacesExtensionsFilter</filter-name>
69 <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
70 </filter-mapping>
71
72 <!-- Config:QFaces -->
73
74 <servlet>
75 <servlet-name>QFaces</servlet-name>
76 <servlet-class>name.huliqing.qfaces.FacesServlet</servlet-class>
77 </servlet>
78 <servlet-mapping>
79 <servlet-name>QFaces</servlet-name>
80 <url-pattern>*.qfaces</url-pattern>
81 </servlet-mapping>
82
83 <!-- End -->
84
85 <servlet>
86 <servlet-name>Faces Servlet</servlet-name>
87 <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
88 <load-on-startup>1</load-on-startup>
89 </servlet>
90 <servlet-mapping>
91 <servlet-name>Faces Servlet</servlet-name>
92 <url-pattern>*.faces</url-pattern>
93 </servlet-mapping>
94 <session-config>
95 <session-timeout>
96 30
97 </session-timeout>
98 </session-config>
99 <welcome-file-list>
100 <welcome-file>welcome.jsp</welcome-file>
101 </welcome-file-list>
102 </web-app>
103
這是web.xml,可以看到默認的配置很簡單,并沒有什么特別的,在網上大都可以看到類似。相關部分都有注識。上面Facelets配置的默認后綴就是xhtml了,這樣當我們訪問如 test.faces這樣的頁面時,就會由Facelets的ViewHandler最后解析到test.xhtml。所以我們的頁面后綴就需要是.xhtml。另外兩個額外的配置MyFaces,QFaces,如果不需要,都可以直接注釋掉,不會影響。2 <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">
3 <context-param>
4 <param-name>com.sun.faces.verifyObjects</param-name>
5 <param-value>false</param-value>
6 </context-param>
7 <context-param>
8 <param-name>com.sun.faces.validateXml</param-name>
9 <param-value>true</param-value>
10 </context-param>
11 <context-param>
12 <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
13 <param-value>client</param-value>
14 </context-param>
15
16 <!-- Config:Facelets -->
17
18 <context-param>
19 <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
20 <param-value>.xhtml</param-value>
21 </context-param>
22
23 <!-- Config:Spring -->
24
25 <servlet>
26 <servlet-name>dispatcher</servlet-name>
27 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
28 <load-on-startup>2</load-on-startup>
29 </servlet>
30 <servlet-mapping>
31 <servlet-name>dispatcher</servlet-name>
32 <url-pattern>*.htm</url-pattern>
33 </servlet-mapping>
34 <listener>
35 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
36 </listener>
37 <listener>
38 <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
39 </listener>
40 <listener>
41 <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
42 </listener>
43 <listener>
44 <listener-class>com.sun.faces.application.WebappLifecycleListener</listener-class>
45 </listener>
46
47 <!-- Config:MyFaces -->
48
49 <filter>
50 <filter-name>MyFacesExtensionsFilter</filter-name>
51 <filter-class>
52 org.apache.myfaces.webapp.filter.ExtensionsFilter
53 </filter-class>
54 <init-param>
55 <param-name>uploadMaxFileSize</param-name>
56 <param-value>100m</param-value>
57 </init-param>
58 <init-param>
59 <param-name>uploadThresholdSize</param-name>
60 <param-value>80k</param-value>
61 </init-param>
62 </filter>
63 <filter-mapping>
64 <filter-name>MyFacesExtensionsFilter</filter-name>
65 <servlet-name>Faces Servlet</servlet-name>
66 </filter-mapping>
67 <filter-mapping>
68 <filter-name>MyFacesExtensionsFilter</filter-name>
69 <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
70 </filter-mapping>
71
72 <!-- Config:QFaces -->
73
74 <servlet>
75 <servlet-name>QFaces</servlet-name>
76 <servlet-class>name.huliqing.qfaces.FacesServlet</servlet-class>
77 </servlet>
78 <servlet-mapping>
79 <servlet-name>QFaces</servlet-name>
80 <url-pattern>*.qfaces</url-pattern>
81 </servlet-mapping>
82
83 <!-- End -->
84
85 <servlet>
86 <servlet-name>Faces Servlet</servlet-name>
87 <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
88 <load-on-startup>1</load-on-startup>
89 </servlet>
90 <servlet-mapping>
91 <servlet-name>Faces Servlet</servlet-name>
92 <url-pattern>*.faces</url-pattern>
93 </servlet-mapping>
94 <session-config>
95 <session-timeout>
96 30
97 </session-timeout>
98 </session-config>
99 <welcome-file-list>
100 <welcome-file>welcome.jsp</welcome-file>
101 </welcome-file-list>
102 </web-app>
103
3.faces-config.xml
文件位置: WEB-INF/faces-config.xml
1 <?xml version='1.0' encoding='UTF-8'?>
2
3 <!-- =========== FULL CONFIGURATION FILE ================================== -->
4
5 <faces-config version="1.2"
6 xmlns="http://java.sun.com/xml/ns/javaee"
7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
9 <application>
10 <!-- 國際化支持 -->
11 <locale-config>
12 <default-locale>zh</default-locale>
13 <supported-locale>zh</supported-locale>
14 <supported-locale>en</supported-locale>
15 </locale-config>
16 <message-bundle>resource</message-bundle>
17 <resource-bundle>
18 <base-name>resource</base-name>
19 <var>text</var>
20 </resource-bundle>
21 <!-- Facelet, Spring -->
22 <view-handler>
23 com.sun.facelets.FaceletViewHandler
24 </view-handler>
25 <variable-resolver>
26 org.springframework.web.jsf.DelegatingVariableResolver
27 </variable-resolver>
28 </application>
29 </faces-config>
重點注意Facelets view-handler及Spring variable-resolver的配置就可以。2
3 <!-- =========== FULL CONFIGURATION FILE ================================== -->
4
5 <faces-config version="1.2"
6 xmlns="http://java.sun.com/xml/ns/javaee"
7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
9 <application>
10 <!-- 國際化支持 -->
11 <locale-config>
12 <default-locale>zh</default-locale>
13 <supported-locale>zh</supported-locale>
14 <supported-locale>en</supported-locale>
15 </locale-config>
16 <message-bundle>resource</message-bundle>
17 <resource-bundle>
18 <base-name>resource</base-name>
19 <var>text</var>
20 </resource-bundle>
21 <!-- Facelet, Spring -->
22 <view-handler>
23 com.sun.facelets.FaceletViewHandler
24 </view-handler>
25 <variable-resolver>
26 org.springframework.web.jsf.DelegatingVariableResolver
27 </variable-resolver>
28 </application>
29 </faces-config>
4.dispatcher-servlet.xml
文件位置:WEB-INF/dispatcher-servlet.xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
這也是Spring的默認配置<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
5.applicationContext.xml
文件位置:WEB-INF/applicationContext.xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-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">
<aop:aspectj-autoproxy/>
<context:annotation-config/>
<context:component-scan base-package="name.huliqing.magic"/>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
<bean id="_data_source" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<alias name="_data_source" alias="dataSource"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="SpringJPADbUnit"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${jdbc.dialect}"/>
<property name="showSql" value="${jdbc.showSql}"/>
<property name="generateDdl" value="${jdbc.generateDdl}"/>
</bean>
</property>
</bean>
<bean id="jDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaDialect" ref="jDialect"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-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">
<aop:aspectj-autoproxy/>
<context:annotation-config/>
<context:component-scan base-package="name.huliqing.magic"/>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
<bean id="_data_source" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<alias name="_data_source" alias="dataSource"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="SpringJPADbUnit"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${jdbc.dialect}"/>
<property name="showSql" value="${jdbc.showSql}"/>
<property name="generateDdl" value="${jdbc.generateDdl}"/>
</bean>
</property>
</bean>
<bean id="jDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaDialect" ref="jDialect"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
<aop:aspectj-autoproxy/> 提供對AspectJ的支持
<context:annotation-config/> 提供對annotation的支持
<context:component-scan base-package="name.huliqing.magic"/> 指定需要被Spring進行掃描的類包,base-package下的類及子包都會被掃描以提供依賴注入,注意修改為自己的包名。
<tx:annotation-driven transaction-manager="transactionManager"/> 對Annotation進行事務管理的支持。
其它定義的一些bean主要是對數據源的配置,更詳細的信息請查閱相關的資料。
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
注意這里指定了數據源配置文件的位置classpath:jdbc.properties.
6.jdbc.properties
文件位置 classpath:jdbc.properties
jdbc.dialect = org.hibernate.dialect.MySQLDialect
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/magic?characterEncoding=UTF-8
jdbc.username = root
jdbc.password =
jdbc.showSql = false
jdbc.generateDdl = false
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/magic?characterEncoding=UTF-8
jdbc.username = root
jdbc.password =
jdbc.showSql = false
jdbc.generateDdl = false
上面是jdbc文件的配置內容,下面顯示了文件的位置,同時顯示了Spring的兩個配置文件的位置。

上面提供了對數據庫的連接信息,數據庫magic,用戶root,密碼空?;旧螶SF+Spring+Hibernate+Facelets就是這個配置了。
下面為了測試環境,將在magic庫中創建一個數據表test,并創建一些相應的類,進行測試一下。
7.測試環境
首先創建一個數據表magic.test
DROP TABLE IF EXISTS magic.test;
CREATE database IF NOT EXISTS magic DEFAULT charset utf8 COLLATE utf8_general_ci;
use magic;
create table magic.test (
num int not null auto_increment,
id varchar(32) not null,
password varchar(64) not null,
des varchar(64) not null,
primary key (num)
) engine = InnoDB default charset = utf8;
CREATE database IF NOT EXISTS magic DEFAULT charset utf8 COLLATE utf8_general_ci;
use magic;
create table magic.test (
num int not null auto_increment,
id varchar(32) not null,
password varchar(64) not null,
des varchar(64) not null,
primary key (num)
) engine = InnoDB default charset = utf8;
接下來將創建以下東東:
Dao.java - Dao接口:
DaoBase.java - Dao基類,實現Dao.java的接口
TestDa.java - Dao,繼承DaoBase.java
TestEn.java - Entity,持久化類,對應數據表magic.test
TestSe.java - Service,業務邏輯層
TestWe.java - BackingBean
test.xhtml - 測試頁面
下面是目錄結構,因為這是測試,所以我并沒有把它們放在相應的目錄。其它幾個類可以不管。

下面是各個類的代碼:
TestEn.java
package name.huliqing.magic.test;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.Table;
@Entity
@Table(name = "test")
@NamedQueries({})
public class TestEn implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Basic(optional = false)
@Column(name = "num")
private Integer num;
@Basic(optional = false)
@Column(name = "id")
private String id;
@Basic(optional = false)
@Column(name = "password")
private String password;
@Basic(optional = false)
@Column(name = "des")
private String des;
public TestEn() {
}
public TestEn(Integer num) {
this.num = num;
}
public TestEn(Integer num, String id, String password, String des) {
this.num = num;
this.id = id;
this.password = password;
this.des = des;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
@Override
public int hashCode() {
int hash = 0;
hash += (num != null ? num.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof TestEn)) {
return false;
}
TestEn other = (TestEn) object;
if ((this.num == null && other.num != null) || (this.num != null && !this.num.equals(other.num))) {
return false;
}
return true;
}
@Override
public String toString() {
return "name.huliqing.magic.domain.TestEn[num=" + num + "]";
}
}
這個Entity是Netbeans通過數據表magic.test生成的代碼,相關的注解都看到了,不明白的可以查閱一下相關資料import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.Table;
@Entity
@Table(name = "test")
@NamedQueries({})
public class TestEn implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Basic(optional = false)
@Column(name = "num")
private Integer num;
@Basic(optional = false)
@Column(name = "id")
private String id;
@Basic(optional = false)
@Column(name = "password")
private String password;
@Basic(optional = false)
@Column(name = "des")
private String des;
public TestEn() {
}
public TestEn(Integer num) {
this.num = num;
}
public TestEn(Integer num, String id, String password, String des) {
this.num = num;
this.id = id;
this.password = password;
this.des = des;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
@Override
public int hashCode() {
int hash = 0;
hash += (num != null ? num.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof TestEn)) {
return false;
}
TestEn other = (TestEn) object;
if ((this.num == null && other.num != null) || (this.num != null && !this.num.equals(other.num))) {
return false;
}
return true;
}
@Override
public String toString() {
return "name.huliqing.magic.domain.TestEn[num=" + num + "]";
}
}
接口Dao.java
package name.huliqing.magic.dao;
import java.io.Serializable;
public interface Dao<T, PK extends Serializable>{
public T save(final T t);
public T update(final T t);
public void delete(final T t);
public T find(final PK id);
}
import java.io.Serializable;
public interface Dao<T, PK extends Serializable>{
public T save(final T t);
public T update(final T t);
public void delete(final T t);
public T find(final PK id);
}
基類:BaseDao.java
package name.huliqing.magic.dao;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTemplate;
public class DaoBase<T, PK extends Serializable> implements Dao<T, PK>{
protected Class<T> type;
protected JpaTemplate jpaTemplate;
protected EntityManagerFactory entityManagerFactory;
protected DriverManagerDataSource dateSource;
public DaoBase(Class<T> type) {
this.type = type;
}
@PersistenceUnit
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
this.jpaTemplate = new JpaTemplate(entityManagerFactory);
}
@Autowired
public void setDataSource(DriverManagerDataSource dateSource) {
this.dateSource = dateSource;
}
public T save(T t) {
this.jpaTemplate.persist(t);
this.jpaTemplate.flush();
return t;
}
public T update(T t) {
this.jpaTemplate.merge(t);
this.jpaTemplate.flush();
return t;
}
public void delete(T t) {
T _o = this.jpaTemplate.merge(t);
this.jpaTemplate.remove(_o);
this.jpaTemplate.flush();
}
public T find(PK id) {
return (T) this.jpaTemplate.find(type, id);
}
public List<T> findByObject(T t, String
fuzzy) {
EntityManagerFactory emf = this.jpaTemplate.getEntityManagerFactory();
EntityManager em = emf.createEntityManager();
Query q = DaoQueryMake.makeQuery(em, t, fuzzy);
List<T> result = q.getResultList();
return result;
}
}
Dao.java, DaoBase.java都使用了泛型,import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTemplate;
public class DaoBase<T, PK extends Serializable> implements Dao<T, PK>{
protected Class<T> type;
protected JpaTemplate jpaTemplate;
protected EntityManagerFactory entityManagerFactory;
protected DriverManagerDataSource dateSource;
public DaoBase(Class<T> type) {
this.type = type;
}
@PersistenceUnit
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
this.jpaTemplate = new JpaTemplate(entityManagerFactory);
}
@Autowired
public void setDataSource(DriverManagerDataSource dateSource) {
this.dateSource = dateSource;
}
public T save(T t) {
this.jpaTemplate.persist(t);
this.jpaTemplate.flush();
return t;
}
public T update(T t) {
this.jpaTemplate.merge(t);
this.jpaTemplate.flush();
return t;
}
public void delete(T t) {
T _o = this.jpaTemplate.merge(t);
this.jpaTemplate.remove(_o);
this.jpaTemplate.flush();
}
public T find(PK id) {
return (T) this.jpaTemplate.find(type, id);
}
public List<T> findByObject(T t, String

EntityManagerFactory emf = this.jpaTemplate.getEntityManagerFactory();
EntityManager em = emf.createEntityManager();
Query q = DaoQueryMake.makeQuery(em, t, fuzzy);
List<T> result = q.getResultList();
return result;
}
}
Dao.java主要定義了相關的基本接口,
DaoBase.java主要提供了Spring對數據源的注入及管理,同時實現了Dao.java的接口,這樣其它Dao只要繼承自DaoBase.java就可以毫不費勁的獲得幾個很基本的功能:save, update, delete, find
測試類Dao: TestDa.java
package name.huliqing.magic.test;
import name.huliqing.magic.dao.*;
import org.springframework.stereotype.Component;
@Component
public class TestDa extends DaoBase{
public TestDa() {
super(TestEn.class);
}
}
import name.huliqing.magic.dao.*;
import org.springframework.stereotype.Component;
@Component
public class TestDa extends DaoBase{
public TestDa() {
super(TestEn.class);
}
}
測試類Service: TestSe.java
package name.huliqing.magic.test;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class TestSe {
@Autowired
private TestDa testDa;
@Transactional
public TestEn save(TestEn testEn) {
return (TestEn) testDa.save(testEn);
}
@Transactional
public TestEn update(TestEn testEn) {
return (TestEn) testDa.update(testEn);
}
@Transactional
public void delete(TestEn testEn) {
testDa.delete(testEn);
}
public List<TestEn> findByObject(Object o, String... fuzzy) {
return testDa.findByObject(o, fuzzy);
}
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class TestSe {
@Autowired
private TestDa testDa;
@Transactional
public TestEn save(TestEn testEn) {
return (TestEn) testDa.save(testEn);
}
@Transactional
public TestEn update(TestEn testEn) {
return (TestEn) testDa.update(testEn);
}
@Transactional
public void delete(TestEn testEn) {
testDa.delete(testEn);
}
public List<TestEn> findByObject(Object o, String... fuzzy) {
return testDa.findByObject(o, fuzzy);
}
}
測試類Backing: TestWe.java
package name.huliqing.magic.test;
import name.huliqing.magic.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("request")
public class TestWe implements java.io.Serializable{
@Autowired
private TestSe testSe;
private TestEn testEn;
public TestWe() {
this.testEn = new TestEn();
}
public TestEn getTestEn() {
return testEn;
}
public void setTestEn(TestEn testEn) {
this.testEn = testEn;
}
public void save() {
TestEn _testEn = testSe.save(testEn);
if (_testEn != null) {
Message.addInfoMessage("注冊成功");
}
}
}
看一下幾個Test類,主要用到幾個注解:@Component @Autowired @Transactionalimport name.huliqing.magic.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("request")
public class TestWe implements java.io.Serializable{
@Autowired
private TestSe testSe;
private TestEn testEn;
public TestWe() {
this.testEn = new TestEn();
}
public TestEn getTestEn() {
return testEn;
}
public void setTestEn(TestEn testEn) {
this.testEn = testEn;
}
public void save() {
TestEn _testEn = testSe.save(testEn);
if (_testEn != null) {
Message.addInfoMessage("注冊成功");
}
}
}
@Component 標明了獲得Spring管理的Bean, 默認名稱為類名的首字母小寫,主要注意Component的保存scope。
@Autowired 實現Bean的快速注入。
@Transactional,通過這個注解,方法將自動獲得事務支持。
下面是測試頁面:test.xhtml
1 <ui:composition xmlns="http://www.w3.org/1999/xhtml"
2 xmlns:h="http://java.sun.com/jsf/html"
3 xmlns:f="http://java.sun.com/jsf/core"
4 xmlns:t="http://myfaces.apache.org/tomahawk"
5 xmlns:ui="http://java.sun.com/jsf/facelets"
6 template="/WEB-INF/layout/template.xhtml">
7 <ui:define name="content">
8 <ui:insert name="messages">
9 <h:messages globalOnly="true" showDetail="true" infoClass="colorGreen" errorClass="colorRed" fatalClass="colorOrange"/>
10 </ui:insert>
11 <h:form>
12 <h:panelGrid columns="3" styleClass="border">
13 <h:outputText value="用戶ID" />
14 <h:inputText id="id" value="#{testWe.testEn.id}" />
15 <h:outputText value="請填寫你的ID" />
16
17 <h:outputText value="設置密碼" />
18 <h:inputSecret id="password" value="#{testWe.testEn.password}" />
19 <h:outputText value="建議由字母與數字混合組成" />
20
21 <h:outputText value="個人說明" />
22 <h:inputTextarea id="des" value="#{testWe.testEn.des}" />
23 <h:outputText value="個人的一些備注" />
24
25 <h:panelGroup />
26 <h:commandButton value="申請" action="#{testWe.save}" />
27 <h:panelGroup />
28 </h:panelGrid>
29 </h:form>
30 </ui:define>
31 </ui:composition>
關于Facelets視圖技術,不明白的請查閱相關的資料,下面是最終測試結果。2 xmlns:h="http://java.sun.com/jsf/html"
3 xmlns:f="http://java.sun.com/jsf/core"
4 xmlns:t="http://myfaces.apache.org/tomahawk"
5 xmlns:ui="http://java.sun.com/jsf/facelets"
6 template="/WEB-INF/layout/template.xhtml">
7 <ui:define name="content">
8 <ui:insert name="messages">
9 <h:messages globalOnly="true" showDetail="true" infoClass="colorGreen" errorClass="colorRed" fatalClass="colorOrange"/>
10 </ui:insert>
11 <h:form>
12 <h:panelGrid columns="3" styleClass="border">
13 <h:outputText value="用戶ID" />
14 <h:inputText id="id" value="#{testWe.testEn.id}" />
15 <h:outputText value="請填寫你的ID" />
16
17 <h:outputText value="設置密碼" />
18 <h:inputSecret id="password" value="#{testWe.testEn.password}" />
19 <h:outputText value="建議由字母與數字混合組成" />
20
21 <h:outputText value="個人說明" />
22 <h:inputTextarea id="des" value="#{testWe.testEn.des}" />
23 <h:outputText value="個人的一些備注" />
24
25 <h:panelGroup />
26 <h:commandButton value="申請" action="#{testWe.save}" />
27 <h:panelGroup />
28 </h:panelGrid>
29 </h:form>
30 </ui:define>
31 </ui:composition>
以上整合配置有經過實際正式上線項目驗證,如果你覺得有什么錯漏,請多多指教。
1.示例源碼下載,沒帶jar,需要自己去下載上面所說的相關jar包。(94K)
http://www.aygfsteel.com/Files/huliqing/Magic-JSH-Facelets-Annotation.rar
2.示例源碼下載,完整版,包含所有相關jar,不過網盤可能不夠穩定。(38M)
http://cid-1c243f9a849aade7.skydrive.live.com/self.aspx/.Public/Magic/Magic%7C5JSF+Spring+Hibernate+Facelets+Annotation%7C6.rar
- huliqing@huliqing.name
- http://www.huliqing.name
posted on 2009-03-30 18:11 huliqing 閱讀(2960) 評論(3) 編輯 收藏 所屬分類: JSF