Spring+JSF+JPA(Hibernate)的环境搭建(二)
Spring+JSF+JPA(Hibernate)的环境搭建(二)
码上中国博客 发表于3年前
Spring+JSF+JPA(Hibernate)的环境搭建(二)
  • 发表于 3年前
  • 阅读 292
  • 收藏 4
  • 点赞 0
  • 评论 2

新睿云服务器60天免费使用,快来体验!>>>   

摘要: Jsf做为Web框架,Spring做为业务层框架,两者可以结合起来用,它应该说是Struts2+Spring+Hibernate的替代解决方案,我参考了网上的很多资料(刘岩先生的文章给我很大帮助),以及结合自己的项目,来给朋友们讲解一下如何搭建Spring+JSF+Hibernate的环境。

下面我们加入JPA支持,并且将JPA和Spring集成起来。

(1).首先加入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>

(2).之后建立一个值对象

代码如下:

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;
    }

(3).之后写DAO

无论你是用IDE生成的DAO还是自己写的DAO,代码大致如下:

@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;
       }
    }
 
         
    public static IPlayerDAO getFromApplicationContext(ApplicationContext ctx) {
       return (IPlayerDAO) ctx.getBean("PlayerDAO");
    }
}

(4).配置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&amp;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&amp;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>

(5)修改faces-config.xml里面的内容

加入如下内容

<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>

这样Spring的DAO就注入了该Action(我还是喜欢叫它Action),至于该Action的代码由于过长,就不在此列出,很简单。无非就是注入DAO,setter和getter呗。

到此JSF+Spring+JPA的环境算是集成起来了,项目代码结构图如下:

最后说一下JPA的缺点:

(1)必须使用在JDK1.5以上的环境,否则只能望JPA而兴叹。

(2)因为它是标准,还在不断的更新中,所以还是不太成熟,不敢保证之后会有很大的变动。

(3)和Hibernate一样,对于多个表(对象)的联合查询,效率比纯JDBC的执行sql要慢很多。

JSF的缺点:

(1)调试不是很方便。

(2)无论是sun的实现还是apache的实现,都存在比较多的bug。

(3)组件技术不如js开源框架灵活,有点鸡肋的感觉。




  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
码上中国博客
粉丝 50
博文 71
码字总数 69104
作品 1
评论 (2)
MartinBock
听你这么一说都不敢用jsf了,调试不方便·········坑爹啊
码上中国博客

引用来自“MartinBock”的评论

听你这么一说都不敢用jsf了,调试不方便·········坑爹啊
在浏览器中调试primefaces,简直太难了,主要是由于它对jquery和html封装性太强了。
×
码上中国博客
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: