采用JPA简化数据访问


我们可以通过纯JDBC进行数据库操作,也可以通过Spring封装的JdbcTemplate,或者用其他第三方ORM工具,如Hibernate、iBatis等;

这里介绍一种简便的方式:Spring-Data-JPA + Hibernate实现
此方式基于标准JPA规范定义了数据持久化时Java模型和表之间的映射关系,使用Spring-Data-JPA提供的数据访问接口,以及Hibernate实现,来完成数据库的操作;
因此在使用时,主要工作是模型映射、以及数据访问接口申明,接口如何实现,由Spring代理生成;

下面先提供一个样例,来简要说明如何使用JPA来完成数据的访问;

工程结构

   
  1. AlarmTrace
  2. |--src/main/java
  3. |--com.boco.alarmTrace.dao.jpa
  4. |--RecDao.java
  5. |--entity
  6. |--CommonEntity.java
  7. |--TfaAlgRec.java
  8. |--src/main/resource
  9. |--spring-jpa.xml
  10. |--src/test/java
  11. |--com.boco.alarmTrace.dao
  12. |--RecDaoTest.java
在maven工程中,需要引入下面jar依赖
   
  1. <!-- Spring org.springframework-version=4.0.3.RELEASE -->
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>${org.springframework-version}</version>
  6. <exclusions>
  7. <!-- Exclude Commons Logging in favor of SLF4j -->
  8. <exclusion>
  9. <groupId>commons-logging</groupId>
  10. <artifactId>commons-logging</artifactId>
  11. </exclusion>
  12. </exclusions>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.springframework</groupId>
  16. <artifactId>spring-webmvc</artifactId>
  17. <version>${org.springframework-version}</version>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework</groupId>
  21. <artifactId>spring-core</artifactId>
  22. <version>${org.springframework-version}</version>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework</groupId>
  26. <artifactId>spring-oxm</artifactId>
  27. <version>${org.springframework-version}</version>
  28. <scope>compile</scope>
  29. </dependency>
  30. <!-- jdbc -->
  31. <dependency>
  32. <groupId>org.springframework</groupId>
  33. <artifactId>spring-jdbc</artifactId>
  34. <version>${org.springframework-version}</version>
  35. </dependency>
  36. <dependency>
  37. <groupId>commons-dbcp</groupId>
  38. <artifactId>commons-dbcp</artifactId>
  39. <version>1.3</version>
  40. <type>jar</type>
  41. <scope>compile</scope>
  42. </dependency>
  43. <dependency>
  44. <groupId>org.hibernate</groupId>
  45. <artifactId>hibernate-core</artifactId>
  46. <version>4.3.1.Final</version>
  47. </dependency>
  48. <dependency>
  49. <groupId>org.hibernate</groupId>
  50. <artifactId>hibernate-entitymanager</artifactId>
  51. <version>4.3.0.Final</version>
  52. </dependency>
  53. <dependency>
  54. <groupId>org.springframework.data</groupId>
  55. <artifactId>spring-data-jpa</artifactId>
  56. <version>1.7.0.RELEASE</version>
  57. </dependency>

DAO接口申明

首先看DAO的定义 -- RecDao.java
   
  1. package com.boco.alarmTrace.dao.jpa;
  2. import java.sql.Timestamp;
  3. import java.util.List;
  4. import org.springframework.data.jpa.repository.JpaRepository;
  5. import org.springframework.data.jpa.repository.Query;
  6. import org.springframework.data.repository.query.Param;
  7. import com.boco.alarmTrace.dao.jpa.entity.TfaAlgRec;
  8. /**
  9. * 通过操作模型TfaAlgRec来操作表tfa_alg_rec;
  10. * <p>
  11. * 此接口继承spring的JpaRepository,可以不用自己实现,就能操作数据表;
  12. * 因为接口JpaRepository在加载时,spring会动态代理生成其实现;
  13. *
  14. * <pre>
  15. * JpaRepository接口继承关系如下
  16. * Repository {Spring Data 的一个核心接口,它不提供任何方法}
  17. * |--CrudRepository
  18. * |--PagingAndSortingRepository
  19. * |--JpaRepository
  20. *
  21. * Repository Spring Data 的一个核心接口,它不提供任何方法
  22. * CrudRepository 提供增删改查方法
  23. * PagingAndSortingRepository 提供分页查询和排序是持久层常用的功能
  24. * JpaRepository 针对 JPA 技术提供的接口,它在父接口的基础上,提供了其他一些方法,比如 flush(),saveAndFlush(),deleteInBatch() 等
  25. * </pre>
  26. *
  27. * <pre>
  28. * Spring Data JPA 在后台为持久层接口创建代理对象时,会解析方法名字,并实现相应的功能。除了通过方法名字以外,它还可以通过如下两种方式指定查询语句:
  29. * Spring Data JPA 可以访问 JPA 命名查询语句。开发者只需要在定义命名查询语句时,为其指定一个符合给定格式的名字,Spring Data JPA 便会在创建代理对象时,使用该命名查询语句来实现其功能。
  30. * 开发者还可以直接在声明的方法上面使用{@code @Query} 注解,并提供一个查询语句作为参数,Spring Data JPA 在创建代理对象时,便以提供的查询语句来实现其功能。
  31. *
  32. * </pre>
  33. *
  34. * @author DAL.feng
  35. */
  36. //@Repository("recDao")
  37. public interface RecDao extends JpaRepository<TfaAlgRec, Integer>, MyJpaDao {
  38. /**
  39. * <p>
  40. * 使用 -@Query 创建查询
  41. * </p>
  42. *
  43. * 通过自己设置查询语句,来完成数据访问;<br>
  44. * select tfaalgrec0_.id as id1_0_, tfaalgrec0_.alarm_severity as alarm_se2_0_, tfaalgrec0_.alarm_title_text as alarm_ti3_0_, tfaalgrec0_.cfp0 as cfp4_0_, tfaalgrec0_.cfp1 as cfp5_0_, tfaalgrec0_.cfp2 as cfp6_0_, tfaalgrec0_.cfp3 as cfp7_0_, tfaalgrec0_.fp0 as fp8_0_, tfaalgrec0_.fp1 as fp9_0_, tfaalgrec0_.fp2 as fp10_0_, tfaalgrec0_.fp3 as fp11_0_, tfaalgrec0_.ins_time as ins_tim12_0_, tfaalgrec0_.model_id as model_i13_0_, tfaalgrec0_.msg_serail as msg_ser14_0_, tfaalgrec0_.operate_unite as operate15_0_, tfaalgrec0_.rec_time as rec_tim16_0_, tfaalgrec0_.sc_time as sc_time17_0_, tfaalgrec0_.send_time as send_ti18_0_, tfaalgrec0_.special_id as special19_0_, tfaalgrec0_.status as status20_0_
  45. * from tfa_alg_rec tfaalgrec0_
  46. * where tfaalgrec0_.fp0=? and tfaalgrec0_.fp1=? and tfaalgrec0_.fp2=? and tfaalgrec0_.fp3=? and tfaalgrec0_.model_id=? and (tfaalgrec0_.sc_time between ? and ?)
  47. *
  48. * <p>
  49. * 注意:
  50. * 此sql可以是JPQL,基于映射后的模型对象查询,也可以是原生sql,如果是原生sql,则必须指定Query属性nativeQuery=true
  51. * </p>
  52. *
  53. * <pre>
  54. * -@Query注解的使用非常简单,只需在声明的方法上面标注该注解,同时提供一个 JPQL 查询语句即可,如下所示:
  55. * {@code
  56. * public interface UserDao extends Repository<AccountInfo, Long> {
  57. *
  58. * public AccountInfo save(AccountInfo accountInfo);
  59. *
  60. * @Query("from AccountInfo a where a.accountId = :id")
  61. * public AccountInfo findByAccountId(@Param("id")Long accountId);
  62. *
  63. * @Query("from AccountInfo a where a.balance > :balance")
  64. * public Page<AccountInfo> findByBalanceGreaterThan(@Param("balance")Integer balance,Pageable pageable);
  65. * }
  66. * }
  67. *
  68. * 此外,开发者也可以通过使用-@Query来执行一个更新操作,为此,我们需要在使用-@Query的同时,用-@Modifying来将该操作标识为修改查询,这样框架最终会生成一个更新的操作,而非查询。如下所示:
  69. * {@code
  70. * @Modifying
  71. * @Query("update AccountInfo a set a.salary = ?1 where a.salary < ?2")
  72. * public int increaseSalary(int after, int before);
  73. * }
  74. *
  75. * </pre>
  76. *
  77. * @param fp0
  78. * @param fp1
  79. * @param fp2
  80. * @param fp3
  81. * @param modelId
  82. * @param startTime
  83. * @param endTime
  84. * @return
  85. */
  86. @Query(value="from TfaAlgRec rec where rec.fp0=:fp0 and rec.fp1=:fp1 and rec.fp2=:fp2 and rec.fp3=:fp3 and rec.modelId=:modelId and rec.scTime between :startTime and :endTime")
  87. public List<TfaAlgRec> findByFp(@Param("fp0")long fp0, @Param("fp1")long fp1, @Param("fp2")long fp2, @Param("fp3")long fp3, @Param("modelId")int modelId, @Param("startTime")Timestamp startTime, @Param("endTime")Timestamp endTime);
  88. /**
  89. * <p>
  90. * 通过解析方法名创建查询
  91. * </p>
  92. *
  93. * 通过代理生成其实现方法,最后拼接的sql样例如下:<br>
  94. * select tfaalgrec0_.id as id1_0_, tfaalgrec0_.alarm_severity as alarm_se2_0_, tfaalgrec0_.alarm_title_text as alarm_ti3_0_, tfaalgrec0_.cfp0 as cfp4_0_, tfaalgrec0_.cfp1 as cfp5_0_, tfaalgrec0_.cfp2 as cfp6_0_, tfaalgrec0_.cfp3 as cfp7_0_, tfaalgrec0_.fp0 as fp8_0_, tfaalgrec0_.fp1 as fp9_0_, tfaalgrec0_.fp2 as fp10_0_, tfaalgrec0_.fp3 as fp11_0_, tfaalgrec0_.ins_time as ins_tim12_0_, tfaalgrec0_.model_id as model_i13_0_, tfaalgrec0_.msg_serail as msg_ser14_0_, tfaalgrec0_.operate_unite as operate15_0_, tfaalgrec0_.rec_time as rec_tim16_0_, tfaalgrec0_.sc_time as sc_time17_0_, tfaalgrec0_.send_time as send_ti18_0_, tfaalgrec0_.special_id as special19_0_, tfaalgrec0_.status as status20_0_
  95. * from tfa_alg_rec tfaalgrec0_
  96. * where tfaalgrec0_.fp0=? and tfaalgrec0_.fp1=? and tfaalgrec0_.fp2=? and tfaalgrec0_.fp3=?
  97. *
  98. * <pre>
  99. * 在代理生成实现时,实际是先解析接口中的方法名,其逻辑如下:
  100. *
  101. * 框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如 find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析。并且如果方法的最后一个参数是 Sort 或者 Pageable 类型,也会提取相关的信息,以便按规则进行排序或者分页查询。
  102. * 在创建查询时,我们通过在方法名中使用属性名称来表达,比如 findByUserAddressZip()。框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,详细规则如下(此处假设该方法针对的域对象为 AccountInfo 类型):
  103. *
  104. * <li>先判断 userAddressZip (根据 POJO 规范,首字母变为小写,下同)是否为 AccountInfo 的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;</li>
  105. * <li>从右往左截取第一个大写字母开头的字符串(此处为 Zip),然后检查剩下的字符串是否为 AccountInfo 的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user 为 AccountInfo 的一个属性;</li>
  106. * <li>接着处理剩下部分( AddressZip ),先判断 user 所对应的类型是否有 addressZip 属性,如果有,则表示该方法最终是根据 "AccountInfo.user.addressZip" 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 "AccountInfo.user.address.zip" 的值进行查询。</li>
  107. *
  108. * 可能会存在一种特殊情况,比如 AccountInfo 包含一个 user 的属性,也有一个 userAddress 属性,此时会存在混淆。读者可以明确在属性之间加上 "_" 以显式表达意图,比如 "findByUser_AddressZip()" 或者 "findByUserAddress_Zip()"。
  109. * 在查询时,通常需要同时根据多个属性进行查询,且查询的条件也格式各样(大于某个值、在某个范围等等),Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下:
  110. * And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
  111. * Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
  112. * Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
  113. * LessThan --- 等价于 SQL 中的 "<",比如 findBySalaryLessThan(int max);
  114. * GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min);
  115. * IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull();
  116. * IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull();
  117. * NotNull --- 与 IsNotNull 等价;
  118. * Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user);
  119. * NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user);
  120. * OrderBy --- 等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user);
  121. * Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user);
  122. * In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
  123. * NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
  124. * </pre>
  125. *
  126. * @param fp0
  127. * @param fp1
  128. * @param fp2
  129. * @param fp3
  130. * @return
  131. */
  132. public List<TfaAlgRec> findByFp0AndFp1AndFp2AndFp3(long fp0, long fp1, long fp2, long fp3);
  133. @Query("from TfaAlgRec rec where rec.cfp0=:cfp0 and rec.cfp1=:cfp1 and rec.cfp2=:cfp2 and rec.cfp3=:cfp3 and rec.modelId=:modelId and rec.scTime between :startTime and :endTime")
  134. public List<TfaAlgRec> findByCfp(@Param("cfp0")long cfp0, @Param("cfp1")long cfp1, @Param("cfp2")long cfp2, @Param("cfp3")long cfp3, @Param("modelId")int modelId, @Param("startTime")Timestamp startTime, @Param("endTime")Timestamp endTime);
  135. public List<TfaAlgRec> findByMsgSerail(String msgSerail);
  136. @Query("from TfaAlgRec rec where rec.modelId=:modelId and rec.scTime between :startTime and :endTime")
  137. public List<TfaAlgRec> findByModleidAndSctime(@Param("modelId")int modelId, @Param("startTime")Timestamp startTime, @Param("endTime")Timestamp endTime);
  138. }

模型映射

本java接口中,定义了几个数据访问方法,以及继承的 JpaRepository 方法,会在spring加载时,自动 代理 生成其实现类;
该接口中,绑定了模型映射TfaAlgRec,此类定义如下
   
  1. package com.boco.alarmTrace.dao.jpa.entity;
  2. import java.sql.Timestamp;
  3. import java.util.List;
  4. import javax.persistence.Column;
  5. import javax.persistence.Entity;
  6. import javax.persistence.Id;
  7. import javax.persistence.Table;
  8. import javax.persistence.Transient;
  9. /**
  10. * 定义对象模型和表字段的映射关系<br>
  11. *
  12. * 通过JPA标准规范定义,采用Spring Data JPA实现,需要在pom中引入spring(4.0.3.RELEASE)、hibernate(4.3.1.Final),还需要
  13. * <pre>
  14. * {@code
  15. * <dependency>
  16. * <groupId>org.springframework.data</groupId>
  17. * <artifactId>spring-data-jpa</artifactId>
  18. * <version>1.7.0.RELEASE</version>
  19. * </dependency>
  20. * <dependency>
  21. * <groupId>org.hibernate</groupId>
  22. * <artifactId>hibernate-entitymanager</artifactId>
  23. * <version>4.3.0.Final</version>
  24. * </dependency>
  25. * }
  26. * </pre>
  27. * <pre>
  28. * spring-data-jpa
  29. * |--spring-jpa.xml jpa申明及持久化配置(此配置可去掉persistence.xml)
  30. * |--*Dao 数据访问接口申明,接口方法遵循一定规则,自己不需要实现,由spring代理实现
  31. * |--TfaAlg* 表和对象模型映射定义
  32. * </pre>
  33. *
  34. * @author DAL.feng
  35. */
  36. @Entity
  37. @Table(name="tfa_alg_rec")
  38. public class TfaAlgRec extends CommonEntity {
  39. private static final long serialVersionUID = 1L;
  40. /**
  41. * Id:标注表中pk属性,且表中id字段映射到对象属性id上
  42. */
  43. // @Id
  44. private Integer id;
  45. /** 告警唯一标识 */
  46. private String msgSerail;
  47. /** 告警状态 */
  48. private int status;
  49. /**
  50. * 将表中字段fp0映射到对象属性fp0
  51. */
  52. private long fp0;
  53. private long fp1;
  54. private long fp2;
  55. private long fp3;
  56. private long cfp0;
  57. private long cfp1;
  58. private long cfp2;
  59. private long cfp3;
  60. /** 产生模块 */
  61. private Integer modelId;
  62. /** 处理单元 */
  63. private String operateUnite;
  64. /** 特殊ID 消息平台filterid、gtft和gaia是ruleid */
  65. private Integer specialId;
  66. /** 入库时间 */
  67. private Timestamp insTime;
  68. /** 告警采集接收产生时间 */
  69. private Timestamp scTime;
  70. /** 模块接收时间 */
  71. private Timestamp recTime;
  72. /** 模块发送时间 */
  73. private Timestamp sendTime;
  74. /** 告警标题 */
  75. private String alarmTitleText;
  76. /** 告警级别 */
  77. private String alarmSeverity;
  78. /**
  79. * 用于申明和表中字段无映射关系的对象属性
  80. */
  81. // @Transient
  82. // private long curTime;
  83. // getter and setter
  84. /**
  85. * Id:标注表中pk属性,且表中id字段映射到对象属性id上
  86. * 将persistence.xml去掉后,采用自动扫描,需要将Id注解放到get方法上
  87. */
  88. @Id
  89. public Integer getId() {
  90. return id;
  91. }
  92. public void setId(Integer id) {
  93. this.id = id;
  94. }
  95. /**
  96. * 将表中字段msg_serail映射到对象属性msgSerail,并限制长度为24,且入库时值不能为空
  97. */
  98. @Column(name="msg_serail", length=24, nullable=true)
  99. public String getMsgSerail() {
  100. return msgSerail;
  101. }
  102. public void setMsgSerail(String msgSerail) {
  103. this.msgSerail = msgSerail;
  104. }
  105. @Column(name="status")
  106. public int getStatus() {
  107. return status;
  108. }
  109. public void setStatus(int status) {
  110. this.status = status;
  111. }
  112. public long getFp0() {
  113. return fp0;
  114. }
  115. public void setFp0(long fp0) {
  116. this.fp0 = fp0;
  117. }
  118. public long getFp1() {
  119. return fp1;
  120. }
  121. public void setFp1(long fp1) {
  122. this.fp1 = fp1;
  123. }
  124. public long getFp2() {
  125. return fp2;
  126. }
  127. public void setFp2(long fp2) {
  128. this.fp2 = fp2;
  129. }
  130. public long getFp3() {
  131. return fp3;
  132. }
  133. public void setFp3(long fp3) {
  134. this.fp3 = fp3;
  135. }
  136. public long getCfp0() {
  137. return cfp0;
  138. }
  139. public void setCfp0(long cfp0) {
  140. this.cfp0 = cfp0;
  141. }
  142. public long getCfp1() {
  143. return cfp1;
  144. }
  145. public void setCfp1(long cfp1) {
  146. this.cfp1 = cfp1;
  147. }
  148. public long getCfp2() {
  149. return cfp2;
  150. }
  151. public void setCfp2(long cfp2) {
  152. this.cfp2 = cfp2;
  153. }
  154. public long getCfp3() {
  155. return cfp3;
  156. }
  157. public void setCfp3(long cfp3) {
  158. this.cfp3 = cfp3;
  159. }
  160. @Column(name="model_id", nullable=true)
  161. public Integer getModelId() {
  162. return modelId;
  163. }
  164. public void setModelId(Integer modelId) {
  165. this.modelId = modelId;
  166. }
  167. @Column(name="operate_unite", length=255, nullable=true)
  168. public String getOperateUnite() {
  169. return returnEmptyIfNull(operateUnite);
  170. }
  171. public void setOperateUnite(String operateUnite) {
  172. this.operateUnite = operateUnite;
  173. }
  174. @Column(name="special_id")
  175. public Integer getSpecialId() {
  176. return specialId;
  177. }
  178. public void setSpecialId(Integer specialId) {
  179. this.specialId = specialId;
  180. }
  181. @Column(name="ins_time")
  182. public Timestamp getInsTime() {
  183. return insTime;
  184. }
  185. public void setInsTime(Timestamp insTime) {
  186. this.insTime = insTime;
  187. }
  188. public void setInsTime(String insTime) {
  189. this.insTime = changeStrTimeToTimestamp(insTime);
  190. }
  191. @Column(name="sc_time")
  192. public Timestamp getScTime() {
  193. return scTime;
  194. }
  195. public void setScTime(Timestamp scTime) {
  196. this.scTime = scTime;
  197. }
  198. public void setScTime(String scTime) {
  199. this.scTime = changeStrTimeToTimestamp(scTime);
  200. }
  201. @Column(name="rec_time")
  202. public Timestamp getRecTime() {
  203. return recTime;
  204. }
  205. public void setRecTime(Timestamp recTime) {
  206. this.recTime = recTime;
  207. }
  208. public void setRecTime(String recTime) {
  209. this.recTime = changeStrTimeToTimestamp(recTime);
  210. }
  211. @Column(name="send_time")
  212. public Timestamp getSendTime() {
  213. return sendTime;
  214. }
  215. public void setSendTime(Timestamp sendTime) {
  216. this.sendTime = sendTime;
  217. }
  218. public void setSendTime(String sendTime) {
  219. this.sendTime = changeStrTimeToTimestamp(sendTime);
  220. }
  221. @Column(name="alarm_title_text", length=255)
  222. public String getAlarmTitleText() {
  223. return returnEmptyIfNull(alarmTitleText);
  224. }
  225. public void setAlarmTitleText(String alarmTitleText) {
  226. this.alarmTitleText = alarmTitleText;
  227. }
  228. @Column(name="alarm_severity", length=64)
  229. public String getAlarmSeverity() {
  230. return returnEmptyIfNull(alarmSeverity);
  231. }
  232. public void setAlarmSeverity(String alarmSeverity) {
  233. this.alarmSeverity = alarmSeverity;
  234. }
  235. @Override
  236. public String toString() {
  237. StringBuilder builder = new StringBuilder();
  238. builder.append("TfaAlgRec [id=");
  239. builder.append(id);
  240. builder.append(", msgSerail=");
  241. builder.append(msgSerail);
  242. builder.append(", status=");
  243. builder.append(status);
  244. builder.append(", fp0=");
  245. builder.append(fp0);
  246. builder.append(", fp1=");
  247. builder.append(fp1);
  248. builder.append(", fp2=");
  249. builder.append(fp2);
  250. builder.append(", fp3=");
  251. builder.append(fp3);
  252. builder.append(", cfp0=");
  253. builder.append(cfp0);
  254. builder.append(", cfp1=");
  255. builder.append(cfp1);
  256. builder.append(", cfp2=");
  257. builder.append(cfp2);
  258. builder.append(", cfp3=");
  259. builder.append(cfp3);
  260. builder.append(", modelId=");
  261. builder.append(modelId);
  262. builder.append(", operateUnite=");
  263. builder.append(operateUnite);
  264. builder.append(", specialId=");
  265. builder.append(specialId);
  266. builder.append(", insTime=");
  267. builder.append(insTime);
  268. builder.append(", scTime=");
  269. builder.append(scTime);
  270. builder.append(", recTime=");
  271. builder.append(recTime);
  272. builder.append(", sendTime=");
  273. builder.append(sendTime);
  274. builder.append(", alarmTitleText=");
  275. builder.append(alarmTitleText);
  276. builder.append(", alarmSeverity=");
  277. builder.append(alarmSeverity);
  278. builder.append("]");
  279. return builder.toString();
  280. }
  281. @Transient
  282. @Override
  283. public String insertSql() {
  284. return "insert into tfa_alg_rec (alarm_severity, alarm_title_text, cfp0, cfp1, cfp2, cfp3, "
  285. + "fp0, fp1, fp2, fp3, ins_time, model_id, msg_serail, operate_unite, rec_time, "
  286. + "sc_time, send_time, special_id, status, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
  287. }
  288. @Transient
  289. @Override
  290. public Object[] getParams() {
  291. return new Object[] {
  292. getAlarmSeverity(),
  293. getAlarmTitleText(),
  294. getCfp0(),
  295. getCfp1(),
  296. getCfp2(),
  297. getCfp3(),
  298. getFp0(),
  299. getFp1(),
  300. getFp2(),
  301. getFp3(),
  302. getInsTime(),
  303. getModelId(),
  304. getMsgSerail(),
  305. getOperateUnite(),
  306. getRecTime(),
  307. getScTime(),
  308. getSendTime(),
  309. getSpecialId(),
  310. getStatus(),
  311. getId()
  312. };
  313. }
  314. }
    
  1. package com.boco.alarmTrace.dao.jpa.entity;
  2. import java.io.Serializable;
  3. import java.sql.Timestamp;
  4. import java.text.ParseException;
  5. import java.text.SimpleDateFormat;
  6. import java.util.Date;
  7. import org.apache.commons.lang.StringUtils;
  8. public abstract class CommonEntity implements Serializable {
  9. private static final long serialVersionUID = 341339020055925890L;
  10. public static final String EMPTY_VALUE_DEFAULT = "";
  11. public static final Timestamp TIMESTAMP_NULL = null;
  12. protected SimpleDateFormat dateToSecondFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  13. public abstract String insertSql();
  14. public abstract Object[] getParams();
  15. /**
  16. * 检测传入的字符串是否为空,如果为空,则返回默认的空字符串""
  17. *
  18. * @param val 被检测的字符串,为空的判断条件:字符串==nul,或者字符串.trim()=""
  19. * @return 字符串为空返回"",否则返回传入的字符串
  20. */
  21. public String returnEmptyIfNull(String val) {
  22. if(StringUtils.isBlank(val)) {
  23. return EMPTY_VALUE_DEFAULT;
  24. } else {
  25. return val;
  26. }
  27. }
  28. /**
  29. * 检测时间类型变量是否为空,如果为空,则返回默认空字符串"",否则返回经yyyy-MM-dd HH:mm:ss转换后的文本时间
  30. * @param val
  31. * @return
  32. */
  33. public String returnEmptyIfNull(Timestamp val) {
  34. if(val == null) {
  35. return EMPTY_VALUE_DEFAULT;
  36. }
  37. return dateToSecondFormat.format(new Date(val.getTime()));
  38. }
  39. /**
  40. * 将yyyy-MM-dd HH:mm:ss文本型时间,转换成格林威治时间
  41. * @param timeStr
  42. * @return
  43. */
  44. public Timestamp changeStrTimeToTimestamp(String timeStr) {
  45. try {
  46. return new Timestamp(dateToSecondFormat.parse(timeStr).getTime());
  47. } catch (ParseException e) {
  48. return TIMESTAMP_NULL;
  49. }
  50. }
  51. }

spring配置

模型映射、DAO声明都已完成,接下来是spring配置文件
   
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd">
  5. <context:component-scan base-package="com.boco.alarmTrace.service.jpa"/>
  6. <!--
  7. <tx:annotation-driven transaction-manager="transactionManager"/>
  8. <jpa:repositories base-package="footmark.springdata.jpa.dao" repository-impl-postfix="Impl" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"/>
  9. -->
  10. <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
  11. <property name="driverClassName" value="com.informix.jdbc.IfxDriver" />
  12. <property name="url" value="jdbc:informix-sqli://10.10.1.52:8001/nmosdb:INFORMIXSERVER=nrmsserver;DELIMIDENT=y;informixserver=nrmsserver;newcodeset=gbk,cp1252,819;" />
  13. <property name="username" value="informix" />
  14. <property name="password" value="informix000" />
  15. </bean>
  16. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  17. <property name="dataSource" ref="ds" />
  18. </bean>
  19. <!-- 扫描Repository及其子接口,用于生成代理实现 -->
  20. <jpa:repositories base-package="com.boco.alarmTrace.dao.jpa"
  21. repository-impl-postfix="Impl" entity-manager-factory-ref="entityManagerFactory"
  22. transaction-manager-ref="transactionManager" />
  23. <!--
  24. <jpa:repository id="myJpaDao" repository-impl-ref="myJpaDaoImpl" />
  25. <bean id="myJpaDaoImpl" class="com.boco.alarmTrace.dao.jpa.MyJpaDaoImpl">
  26. <property name="jdbc" ref="jdbcTemplate" />
  27. </bean>
  28. -->
  29. <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  30. <property name="entityManagerFactory" ref="entityManagerFactory"/>
  31. </bean>
  32. <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  33. <property name="dataSource" ref="ds" />
  34. <property name="persistenceUnitName" value="spring-jpa"/>
  35. <!-- 扫描模型和表的映射类,用于持久化 -->
  36. <property name="packagesToScan" value="com.boco.alarmTrace.dao.jpa.entity" />
  37. <property name="jpaVendorAdapter">
  38. <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
  39. <property name="generateDdl" value="false"/>
  40. <property name="showSql" value="true"/>
  41. </bean>
  42. </property>
  43. <!--
  44. 下面配置就不需要再配置src/META-INF/persistence.xml ${hibernate.dialect}
  45. http://www.cnblogs.com/taven/archive/2013/10/04/3351841.html
  46. -->
  47. <property name="jpaProperties">
  48. <props>
  49. <prop key="hibernate.c3p0.min_size">50</prop>
  50. <prop key="hibernate.hbm2ddl.auto">true</prop>
  51. <prop key="hibernate.jdbc.batch_size">10</prop>
  52. <prop key="hibernate.dialect">org.hibernate.dialect.InformixDialect</prop>
  53. </props>
  54. </property>
  55. </bean>
  56. </beans>

测试及结果

最后,测试JPA是否好用,运行测试及结果
   
  1. package com.boco.alarmTrace.dao;
  2. import static org.junit.Assert.fail;
  3. import java.sql.Timestamp;
  4. import java.util.ArrayList;
  5. import java.util.LinkedList;
  6. import java.util.List;
  7. import org.apache.commons.lang.StringUtils;
  8. import org.junit.After;
  9. import org.junit.Assert;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12. import org.springframework.context.ApplicationContext;
  13. import org.springframework.context.support.ClassPathXmlApplicationContext;
  14. import com.boco.alarmTrace.dao.jpa.RecDao;
  15. import com.boco.alarmTrace.dao.jpa.entity.TfaAlgRec;
  16. public class RecDaoTest {
  17. ApplicationContext ctx = null;
  18. RecDao dao = null;
  19. @Before
  20. public void setUp() throws Exception {
  21. ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-jpa.xml");
  22. dao = ctx.getBean("recDao", RecDao.class);
  23. }
  24. @After
  25. public void tearDown() {
  26. // ctx.
  27. }
  28. /**
  29. * 测试DAO接口在spring初始化后是否能自动生成实现
  30. */
  31. @Test
  32. public void testDaoIsNull() {
  33. Assert.assertNotNull(dao);
  34. }
  35. /**
  36. * 测试接口方法
  37. * <pre>
  38. * 表中记录
  39. * TfaAlgRec [id=4994287, msgSerail=##0QP01l0000000D543F6F11, status=1, fp0=1399144828, fp1=819453314, fp2=2286674142, fp3=1448780389, cfp0=2992234056, cfp1=3657354290, cfp2=3986893009, cfp3=2088807446, modelId=20001, operateUnite=108125-111, specialId=null, insTime=null, scTime=2014-10-16 15:09:05.0, recTime=2014-10-16 15:09:05.768, sendTime=2014-10-16 15:09:05.774, alarmTitleText=null, alarmSeverity=故障警告]
  40. * </pre>
  41. */
  42. @Test
  43. public void testFindByFp() {
  44. try {
  45. System.out.println("000000000");
  46. String sTime = "2014-10-16 15:00:00";
  47. String eTime = "2014-10-16 15:59:59";
  48. TfaAlgRec entity = new TfaAlgRec();
  49. entity.setFp0(1399144828);
  50. entity.setFp1(819453314);
  51. entity.setFp2(2286674142l);
  52. entity.setFp3(1448780389);
  53. entity.setModelId(ModelDict.MODEL_RT);
  54. Timestamp startTime = entity.changeStrTimeToTimestamp(sTime);
  55. Timestamp endTime = entity.changeStrTimeToTimestamp(eTime);
  56. List<TfaAlgRec> l = dao.findByFp(entity.getFp0(), entity.getFp1(), entity.getFp2(), entity.getFp3(),
  57. entity.getModelId(), startTime, endTime);
  58. System.out.println("l " + (l==null || l.isEmpty()));
  59. System.out.println(l);
  60. Assert.assertEquals(l.get(0).getFp0(), 1399144828);
  61. } catch(Exception e) {
  62. e.printStackTrace();
  63. }
  64. }
  65. /**
  66. * 测试接口方法
  67. * <pre>
  68. * 表中记录
  69. * TfaAlgRec [id=4994287, msgSerail=##0QP01l0000000D543F6F11, status=1, fp0=1399144828, fp1=819453314, fp2=2286674142, fp3=1448780389, cfp0=2992234056, cfp1=3657354290, cfp2=3986893009, cfp3=2088807446, modelId=20001, operateUnite=108125-111, specialId=null, insTime=null, scTime=2014-10-16 15:09:05.0, recTime=2014-10-16 15:09:05.768, sendTime=2014-10-16 15:09:05.774, alarmTitleText=null, alarmSeverity=故障警告]
  70. * </pre>
  71. */
  72. @Test
  73. public void testFindByFp0AndFp2AndFp2AndFp3() {
  74. TfaAlgRec entity = new TfaAlgRec();
  75. entity.setFp0(1399144828);
  76. entity.setFp1(819453314);
  77. entity.setFp2(2286674142l);
  78. entity.setFp3(1448780389);
  79. List<TfaAlgRec> l = dao.findByFp0AndFp1AndFp2AndFp3(entity.getFp0(), entity.getFp1(), entity.getFp2(), entity.getFp3());
  80. System.out.println("l " + (l==null || l.isEmpty()));
  81. System.out.println(l);
  82. Assert.assertEquals(l.get(0).getFp0(), 1399144828);
  83. }
  84. /**
  85. * 测试接口方法
  86. * <pre>
  87. * 表中记录
  88. * TfaAlgRec [id=4994287, msgSerail=##0QP01l0000000D543F6F11, status=1, fp0=1399144828, fp1=819453314, fp2=2286674142, fp3=1448780389, cfp0=2992234056, cfp1=3657354290, cfp2=3986893009, cfp3=2088807446, modelId=20001, operateUnite=108125-111, specialId=null, insTime=null, scTime=2014-10-16 15:09:05.0, recTime=2014-10-16 15:09:05.768, sendTime=2014-10-16 15:09:05.774, alarmTitleText=null, alarmSeverity=故障警告]
  89. * </pre>
  90. */
  91. @Test
  92. public void testFindByCfp() {
  93. System.out.println("------- " + (dao==null));
  94. TfaAlgRec entity = new TfaAlgRec();
  95. Timestamp sTime = entity.changeStrTimeToTimestamp("2014-10-16 15:00:00");
  96. Timestamp eTime = entity.changeStrTimeToTimestamp("2014-10-16 15:59:59");
  97. List<TfaAlgRec> l = dao.findByCfp(2992234056l, 3657354290l, 3986893009l, 2088807446l, 20001, sTime, eTime);
  98. Assert.assertEquals(l.get(0).getCfp0(), 2992234056l);
  99. }
  100. @Test
  101. public void testFindByMsgSerail() {
  102. // fail("Not yet implemented");
  103. }
  104. @Test
  105. public void testFindByModleidAndSctime() {
  106. // fail("Not yet implemented");
  107. }
  108. }
测试用例运行结构








转载于:https://my.oschina.net/u/1997676/blog/467710

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值