内容如下:
<?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; }
无论你是用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&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>
这样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开源框架灵活,有点鸡肋的感觉。