JSF+Spring+JPA(Hibernate实现)的环境搭建
2010-06-23 09:24
501 查看
写之前的感受
刘岩
先说好的,文章后再说缺点。
JSF+Spring+JPA以我个人看来,应该说是Struts2+Spring+Hibernate的替代解决方案。
引入JPA去取代或者说包装或者说是升级Hibernate是为了符合JAVA EE的规范,达到ORM统一的结果。下次项目用EJB也好、用TOPLINK也好、用ibatis也罢,我们的开发人员代价会很小。在目前很多项目来说,引入此规范,能更好的代码复用,持久层和控制层相当于进一步的解耦合了,你只需要开启项目之前好好地建立领域模型。
那么用JSF取代Struts2或者更早一点的Struts1又是为何!答案依然是,它是规范。是符合某些标准的规范。不是说Struts2不好,这个因项目而定才行。我个人还是比较推崇apache的Struts2的,当然了,apache的JSF实现和JSF组件也是相当地杠杠的!!!!JSF更贴近事件比较多的web前端处理机制。想想我们一般要接收和处理页面的各种事件是用什么:js函数+ajax处理是吧(Flex我没有接触过,不知道它是怎么样的处理前后台交互的)。JSF可以采用事件监听机制,控件(JSF里面叫做控件)被触发了某些时间,直接优雅的和POJO进行了交互,配合ajax4jsf,处理大量的控件的事件是很简洁方便的。
言归正传,开始。。。
1. 首先利用IDE建立一个Web项目
2. 加入相应的jar包,注意:所有的开源框架都是加入jar包的时候最麻烦,尤其加入了Spring,搞不好就他妈的启动服务的时候报错。我已经将相应需要的jar包放到了csdn上面共享了,网址是http://download.csdn.net/source/2416493。大家可以去下载。
3. web项目加入JSF支持
修改web.xml,加入如下内容
在WEB-INF下面加入jsf_core.tld、html_basic.tld和tomahawk.taglib.xml文件、新建一个faces-config.xml文件,内容配置如下:
再加入facelets框架的标签支持包,整个环境包大致如下图所示:
4. 上面的配置好了,JSF和Spring就集成起来了。下面我们加入JPA支持,并且将JPA和Spring集成起来。
首先加入persistence.xml文件,内容如下:
之后建立一个值对象,代码如下:
之后写DAO,无论你是用IDE生成的DAO还是自己写的DAO,代码大致如下:
注意:之所以加入注解:@Transactional,是为了AOP进行事务处理。
配置Spring文件applicationContext.xml,内容如下:
5. 之后修改一下faces-config.xml里面的内容。
加入如下内容
这样Spring的DAO就注入了该Action(我还是喜欢叫它Action),至于该Action的代码由于过长,就不在此列出,很简单。无非就是注入DAO,setter和getter呗。
到此JSF+Spring+JPA的环境算是集成起来了,项目代码结构图如下:
JPA的缺点:
必须使用在JDK1.5以上的环境,否则只能望JPA而兴叹。
因为它是标准,还在不断的更新中,所以还是不太成熟,不敢保证之后会有很大的变动。
和Hibernate一样,对于多个表(对象)的联合查询,效率比纯JDBC的执行sql要慢很多。
JSF的缺点:
调试不是很方便。
无论是sun的实现还是apache的实现,都存在比较多的bug。
组件技术不如js开源框架灵活,有点鸡肋的感觉。
刘岩
先说好的,文章后再说缺点。
JSF+Spring+JPA以我个人看来,应该说是Struts2+Spring+Hibernate的替代解决方案。
引入JPA去取代或者说包装或者说是升级Hibernate是为了符合JAVA EE的规范,达到ORM统一的结果。下次项目用EJB也好、用TOPLINK也好、用ibatis也罢,我们的开发人员代价会很小。在目前很多项目来说,引入此规范,能更好的代码复用,持久层和控制层相当于进一步的解耦合了,你只需要开启项目之前好好地建立领域模型。
那么用JSF取代Struts2或者更早一点的Struts1又是为何!答案依然是,它是规范。是符合某些标准的规范。不是说Struts2不好,这个因项目而定才行。我个人还是比较推崇apache的Struts2的,当然了,apache的JSF实现和JSF组件也是相当地杠杠的!!!!JSF更贴近事件比较多的web前端处理机制。想想我们一般要接收和处理页面的各种事件是用什么:js函数+ajax处理是吧(Flex我没有接触过,不知道它是怎么样的处理前后台交互的)。JSF可以采用事件监听机制,控件(JSF里面叫做控件)被触发了某些时间,直接优雅的和POJO进行了交互,配合ajax4jsf,处理大量的控件的事件是很简洁方便的。
言归正传,开始。。。
1. 首先利用IDE建立一个Web项目
2. 加入相应的jar包,注意:所有的开源框架都是加入jar包的时候最麻烦,尤其加入了Spring,搞不好就他妈的启动服务的时候报错。我已经将相应需要的jar包放到了csdn上面共享了,网址是http://download.csdn.net/source/2416493。大家可以去下载。
3. web项目加入JSF支持
修改web.xml,加入如下内容
<!--Spring与JSF支持--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--配置JSF--> <context-param> <param-name>javax.faces.CONFIG_FILES</param-name> <param-value>/WEB-INF/faces-config.xml</param-value> </context-param> <!--Spring配置文件地址--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext.xml</param-value> </context-param> <!--客户端管理状态--> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <!—加入facelets 框架支持--> <context-param> <param-name>facelets.LIBRARIES</param-name> <param-value> /WEB-INF/facelets/tags/arcmind.taglib.xml;/WEB-INF/tomahawk.taglib.xml </param-value> </context-param> <context-param> <description>指定facelets支持的后缀</description> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.xhtml</param-value> </context-param> <!--JSF的ajax配置 AJAX4JSF--> <filter> <display-name>Ajax4jsf Filter</display-name> <filter-name>ajax4jsf</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>ajax4jsf</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <!—JSF支持--> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.faces</url-pattern> </servlet-mapping> <!—组件支持--> <filter> <description>为正确使用tomahawk组件包而配置</description> <filter-name>extensionsFilter</filter-name> <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class> <init-param> <param-name>uploadMaxFileSize</param-name> <param-value>10m</param-value> </init-param> <init-param> <param-name>uploadThresholdSize</param-name> <param-value>100</param-value> </init-param> </filter> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>*.faces</url-pattern> </filter-mapping> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>/faces/*</url-pattern> </filter-mapping> |
<!--配置facelets--> <application> <locale-config> <default-locale>zh_CN</default-locale> </locale-config> <view-handler>com.sun.facelets.FaceletViewHandler</view-handler> </application> <!—JSF与Spring集成--> <application> <variable-resolver> org.springframework.web.jsf.DelegatingVariableResolver </variable-resolver> </application> |
4. 上面的配置好了,JSF和Spring就集成起来了。下面我们加入JPA支持,并且将JPA和Spring集成起来。
首先加入persistence.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="JSJDemoPU" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>test.vo.Test</class> <properties> <!-- Hibernate 方言(只有Hibernate 才需要设置) --> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <!-- Hibernate 显示调试 SQL --> <property name="hibernate.show_sql" value="true" /> <!-- Hibernate 格式化sql --> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="update" /> </properties> </persistence-unit> </persistence> |
package mangerTeam.vo; import java.io.Serializable; import java.util.Set; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.Lob; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.Table; /** * 运动员实体 * * @author 刘岩 */ @Entity @Table(name = "player") public class PlayersVO implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", unique = true, nullable = false) private Integer id; @Column(name = "name") private String name; @ManyToOne(optional=true, fetch = FetchType.LAZY) @JoinColumn(name = "teamId") private TeamVO teamVO; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(nullable=false,name = "nationalityId") private NationalityVO nationalityVO; @Lob @Basic(fetch = FetchType.LAZY) @Column(name = "pic") private byte[] pic; @Lob @Basic(fetch = FetchType.LAZY) @Column(name = "mess") private String mess; @ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY) @JoinTable(name = "plays_position", joinColumns = { @JoinColumn(name = "playerId") }, inverseJoinColumns = { @JoinColumn(name = "positionId") }) private Set<PositionVO> positions; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<PositionVO> getPositions() { return positions; } public void setPositions(Set<PositionVO> positions) { this.positions = positions; } public TeamVO getTeamVO() { return teamVO; } public void setTeamVO(TeamVO teamVO) { this.teamVO = teamVO; } public NationalityVO getNationalityVO() { return nationalityVO; } public void setNationalityVO(NationalityVO nationalityVO) { this.nationalityVO = nationalityVO; } public byte[] getPic() { return pic; } public void setPic(byte[] pic) { this.pic = pic; } public String getMess() { return mess; } public void setMess(String mess) { this.mess = mess; } } |
package mangerTeam.dao; import java.util.HashMap; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceException; import javax.persistence.Query; import mangerTeam.vo.PlayersVO; import org.springframework.context.ApplicationContext; import org.springframework.orm.jpa.JpaCallback; import org.springframework.orm.jpa.support.JpaDaoSupport; import org.springframework.transaction.annotation.Transactional; @Transactional public class PlayerDAO extends JpaDaoSupport implements IPlayerDAO { // property constants public static final String NAME = "name"; public static final String MESS = "mess"; public static final String PIC = "pic"; public void save(PlayersVO entity) { logger.info("saving Player instance"); try { getJpaTemplate().persist(entity); logger.info("save successful"); } catch (RuntimeException re) { logger.error("save failed", re); throw re; } } public void delete(PlayersVO entity) { logger.info("deleting Player instance"); try { entity = getJpaTemplate().getReference(PlayersVO.class, entity.getId()); getJpaTemplate().remove(entity); logger.info("delete successful"); } catch (RuntimeException re) { logger.error("delete failed", re); throw re; } } public PlayersVO update(PlayersVO entity) { logger.info("updating Player instance"); try { PlayersVO result = getJpaTemplate().merge(entity); logger.info("update successful"); return result; } catch (RuntimeException re) { logger.error("update failed", re); throw re; } } public PlayersVO findById(Integer id) { logger.info("finding Player instance with id: " + id); try { PlayersVO instance = getJpaTemplate().find(PlayersVO.class, id); return instance; } catch (RuntimeException re) { logger.error("find failed", re); throw re; } } @SuppressWarnings("unchecked") public List<PlayersVO> findByProperty(String propertyName, final Object value, final int... rowStartIdxAndCount) { logger.info("finding Player instance with property: " + propertyName + ", value: " + value); try { final String queryString = "select model from PlayersVO model where model." + propertyName + "= :propertyValue"; return getJpaTemplate().executeFind(new JpaCallback() { public Object doInJpa(EntityManager em) throws PersistenceException { Query query = em.createQuery(queryString); query.setParameter("propertyValue", value); if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) { // 有分页 int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]); // 开始页 if (rowStartIdx > 0) { query.setFirstResult(rowStartIdx); } // 一页最大记录数目 if (rowStartIdxAndCount.length > 1) { int rowCount = Math.max(0, rowStartIdxAndCount[1]); if (rowCount > 0) { query.setMaxResults(rowCount); } } } return query.getResultList(); } }); } catch (RuntimeException re) { logger.error("find by property name failed", re); throw re; } } public List<PlayersVO> findByName(Object name, int... rowStartIdxAndCount) { return findByProperty(NAME, name, rowStartIdxAndCount); } public List<PlayersVO> findByMess(Object mess, int... rowStartIdxAndCount) { return findByProperty(MESS, mess, rowStartIdxAndCount); } public List<PlayersVO> findByPic(Object pic, int... rowStartIdxAndCount) { return findByProperty(PIC, pic, rowStartIdxAndCount); } public List<PlayersVO> findAll(final int... rowStartIdxAndCount) { logger.info("finding all Player instances"); try { final String queryString = "select model from PlayersVO model"; return getJpaTemplate().executeFind(new JpaCallback() { public Object doInJpa(EntityManager em) throws PersistenceException { Query query = em.createQuery(queryString); if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) { int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]); if (rowStartIdx > 0) { query.setFirstResult(rowStartIdx); } if (rowStartIdxAndCount.length > 1) { int rowCount = Math.max(0, rowStartIdxAndCount[1]); if (rowCount > 0) { query.setMaxResults(rowCount); } } } return query.getResultList(); } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 按条件的复杂查询 * * @param con * @param rowStartIdxAndCount * @return */ @SuppressWarnings("unchecked") public List<PlayersVO> serch(final HashMap<String, Object> conMap, final String con, final int... rowStartIdxAndCount) { try { String queryString = "select model from PlayersVO model WHERE 1=1 "; if (con != null && !"".equalsIgnoreCase(con)) { queryString = queryString + con; } final String jpql = queryString; return getJpaTemplate().executeFind(new JpaCallback() { public Object doInJpa(EntityManager em) throws PersistenceException { Query query = em.createQuery(jpql); for (int i = 0; i < conMap.size(); i++) { String key = "option" + i; query.setParameter(key, conMap.get(key)); } if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) { int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]); if (rowStartIdx > 0) { query.setFirstResult(rowStartIdx); } if (rowStartIdxAndCount.length > 1) { int rowCount = Math.max(0, rowStartIdxAndCount[1]); if (rowCount > 0) { query.setMaxResults(rowCount); } } } return query.getResultList(); } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 用JPQL查询计算记录总数 * @return */ public Long countNumJPQL(){ logger.info("finding all Team instances"); try { final String queryString = "select COUNT(model) from PlayersVO model"; return (Long)getJpaTemplate().executeFind(new JpaCallback() { public Object doInJpa(EntityManager em) throws PersistenceException { Query query = em.createQuery(queryString); return query.getResultList(); } }).get(0); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } public static IPlayerDAO getFromApplicationContext(ApplicationContext ctx) { return (IPlayerDAO) ctx.getBean("PlayerDAO"); } } |
配置Spring文件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" 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" xmlns:tx="http://www.springframework.org/schema/tx" default-autowire="byName"> <!--数据源连接池,使用dbcp--> <bean id="realPoolDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!--基本连接设值--> <property name="driverClassName" value="org.gjt.mm.mysql.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/jsjdemo?useUnicode=true&characterEncoding=UTF-8" /> <property name="username" value="root" /> <property name="password" value="root" /> <!--连接池参数设置--> <property name="maxIdle" value="20" /> <property name="maxWait" value="1000" /> <property name="defaultAutoCommit" value="false" /> <property name="removeAbandoned" value="true" /> <property name="removeAbandonedTimeout" value="120" /> </bean> <!-- c3p0连接池 --> <bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="org.gjt.mm.mysql.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/jsjdemo?useUnicode=true&characterEncoding=UTF-8" /> <!-- 当连接池耗尽时候,一次获得连接数--> <property name="acquireIncrement" value="5" /> <!-- 连接池最大数 --> <property name="maxPoolSize" value="20" /> <!-- 连接池最小数--> <property name="minPoolSize" value="5" /> <!-- 用户名--> <property name="user" value="root" /> <!-- 用户密码--> <property name="password" value="root"></property> </bean> <!-- 类似于hibernate的SessionFactory,指定由spring容器Bean,即:LocalContainerEntityManagerFactoryBean --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="JSJDemoPU" /> <property name="dataSource" ref="c3p0DataSource" /> </bean> <!--配置事务--> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <!--支持dao事务注解--> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- Hibernate使用的SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!--数据源配置--> <property name="dataSource"> <ref bean="c3p0DataSource" /> </property> </bean> <!--Spring注入Dao实现--> <bean id="testDAO" class="test.dao.TestDAO"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="TeamDAO" class="mangerTeam.dao.TeamDAO"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="PositionDAO" class="mangerTeam.dao.PositionDAO"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="PlayerDAO" class="mangerTeam.dao.PlayerDAO"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="NationalityDAO" class="mangerTeam.dao.NationalityDAO"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> </beans> |
加入如下内容
<managed-bean> <managed-bean-name>playersVO</managed-bean-name> <managed-bean-class> mangerTeam.vo.PlayersVO </managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>playerAction</managed-bean-name> <managed-bean-class> mangerTeam.action.PlayerAction </managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <!--从Spring得到的DAO--> <managed-property> <property-name>playerDAO</property-name> <value>#{PlayerDAO}</value> </managed-property> <managed-property> <property-name>playersVO</property-name> <value>#{playersVO}</value> </managed-property> </managed-bean> |
到此JSF+Spring+JPA的环境算是集成起来了,项目代码结构图如下:
JPA的缺点:
必须使用在JDK1.5以上的环境,否则只能望JPA而兴叹。
因为它是标准,还在不断的更新中,所以还是不太成熟,不敢保证之后会有很大的变动。
和Hibernate一样,对于多个表(对象)的联合查询,效率比纯JDBC的执行sql要慢很多。
JSF的缺点:
调试不是很方便。
无论是sun的实现还是apache的实现,都存在比较多的bug。
组件技术不如js开源框架灵活,有点鸡肋的感觉。
相关文章推荐
- spring-jpa(hibernate实现)环境搭建
- springmvc+spring-data-jpa+hibernate环境搭建与配置
- ssh(Struts+Spring+Hibernate)环境搭建,实现登录
- Spring+hibernate(jpa)+freemarker之开发环境搭建
- spring3.1+openjpa+jsf2.0框架环境搭建
- 基于james3.0 的邮件系统(struts2.3.2 +spring3.0.1+jpa(hibernate3.6.5)实现)b/s模式 .
- Struts+Spring+Hibernate (一) 集成原理和搭建环境
- Spring+Hibernate环境搭建
- Springmvc+Hibernate+JPA Maven环境搭
- Hibernate:hibernate环境搭建并实现hibernate例子
- 基于james3.0 的邮件系统(struts2.3.2 +spring3.0.1+jpa(hibernate3.6.5)实现)b/s模式
- 一步一步实现Spring4 + Hibernate4 + Freemarker2 的注解驱动开发(一. 环境搭建)
- maven+spring-data-jpa环境搭建
- 使用MyEclipse搭建Spring+Hibernate环境
- JPA(hibernate)开发环境的搭建和一个基本的实例
- 条理清晰的搭建SSH环境之整合Hibernate和Spring
- springboot jpa hibernate 实现动态查询
- SPRING BOOT:Hibernate实现的JPA中使用joda-time
- 基于james3.0 的邮件系统(struts2.3.2 +spring3.0.1+jpa(hibernate3.6.5)实现)b/s模式--java邮件系统
- JAVA-WEB的SSH(Spring Hibernate Struts)环境搭建一(Spring)