本節內容須要瞭解JPA封裝內容,請參見筆者 上篇博文。java
爲了演示JPA接入,須要先準備以下:mysql
新建測試表 student
建表語句以下:git
DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `stu_id` int(10) NOT NULL AUTO_INCREMENT COMMENT '學生編號', `stu_name` varchar(255) NOT NULL COMMENT '學生姓名', `stu_age` tinyint(2) NOT NULL COMMENT '學生年齡', `stu_sex` tinyint(1) NOT NULL COMMENT '學生性別(1:男 2:女)', `stu_state` tinyint(2) NOT NULL COMMENT '學生狀態(0:刪除 1:在用)', PRIMARY KEY (`stu_id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
新建以下實體類Student,對應測試表studentgithub
/** * <p> 學生表對應的實體類 </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ @Entity @Table(name = "student") public class Student implements FleaEntity { private static final long serialVersionUID = 1267943552214677159L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "STUDENT_SEQ") @SequenceGenerator(name = "STUDENT_SEQ") @Column(name = "stu_id", unique = true, nullable = false) private Long stuId; // 學生編號 @Column(name = "stu_name", nullable = false) private String stuName; // 學生姓名 @Column(name = "stu_age", nullable = false) private Integer stuAge; // 學生年齡 @Column(name = "stu_sex", nullable = false) private Integer stuSex; // 學生性別(1:男 2:女) @Column(name = "stu_state", nullable = false) private Integer stuState; // 學生狀態(0:刪除 1:在用) // ... 省略get和set方法 }
上篇博文說到,增長一個持久化單元配置,便須要增長一個持久化單元DAO層實現。針對本次演示新增持久化單元 fleajpa,持久化配置文件 fleajpa-persistence.xml, Spring配置中新增數據庫事務管理者配置,相關內容可參考上一篇博文。下面貼出本次演示的持久化單元DAO層實現代碼:spring
/** * <p> FleaJpa數據源DAO層父類 </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public class FleaJpaDAOImpl<T> extends AbstractFleaJPADAOImpl<T> { // 持久化單元,持久化配置文件中定義,spring配置中持久化接口工廠初始化參數 @PersistenceContext(unitName="fleajpa") protected EntityManager entityManager; @Override // 持久化事務管理者, spring配置文件中定義 @Transactional("fleaJpaTransactionManager") public boolean remove(long entityId) throws Exception { return super.remove(entityId); } // ...其餘實現省略 @Override protected EntityManager getEntityManager() { return entityManager; } }
詳細配置信息,能夠參考筆者上篇博文,這裏再也不贅述。
涉及文件 fleajpa-persistence.xml 和 applicationContext.xmlsql
IStudentDAO 繼承了抽象Flea JPA DAO層接口,並定義了兩個方法,分別獲取學生信息列表(分頁)和學生總數。數據庫
/** * <p> 學生DAO層接口 </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public interface IStudentDAO extends IAbstractFleaJPADAO<Student> { /** * <p> 學生信息列表 (分頁) </p> * * @param name 學生姓名,能夠模糊查詢 * @param sex 性別 * @param minAge 最小年齡 * @param maxAge 最大年齡 * @param pageNum 查詢頁 * @param pageCount 每頁總數 * @return 學生信息列表 * @throws DaoException 數據操做層異常 * @since 1.0.0 */ List<Student> getStudentList(String name, Integer sex, Integer minAge, Integer maxAge, int pageNum, int pageCount) throws DaoException; /** * <p> 學生總數 </p> * * @param name 學生姓名,能夠模糊查詢 * @param sex 性別 * @param minAge 最小年齡 * @param maxAge 最大年齡 * @return 學生總數 * @throws DaoException 數據操做層異常 * @since 1.0.0 */ int getStudentCount(String name, Integer sex, Integer minAge, Integer maxAge) throws DaoException; }
StudentDAOImpl 是學生信息的數據操做層實現,繼承持久化單元DAO層實現類,並實現了上述學生DAO層接口自定義的兩個方法。 具體如何使用 FleaJPAQuery 能夠參見下面代碼 :併發
/** * <p> 學生DAO層實現類 </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ @Repository("studentDAO") public class StudentDAOImpl extends FleaJpaDAOImpl<Student> implements IStudentDAO { @Override @SuppressWarnings(value = "unchecked") public List<Student> getStudentList(String name, Integer sex, Integer minAge, Integer maxAge, int pageNum, int pageCount) throws DaoException { FleaJPAQuery query = initQuery(name, sex, minAge, maxAge, null); List<Student> studentList; if (pageNum > 0 && pageCount > 0) { // 分頁查詢 studentList = query.getResultList((pageNum - 1) * pageCount, pageCount); } else { // 全量查詢 studentList = query.getResultList(); } return studentList; } @Override @SuppressWarnings(value = "unchecked") public long getStudentCount(String name, Integer sex, Integer minAge, Integer maxAge) throws DaoException { FleaJPAQuery query = initQuery(name, sex, minAge, maxAge, Long.class); // 統計數目 query.countDistinct(); Object result = query.getSingleResult(); return Long.parseLong(StringUtils.valueOf(result)); } private FleaJPAQuery initQuery(String name, Integer sex, Integer minAge, Integer maxAge, Class<?> result) throws DaoException{ FleaJPAQuery query = getQuery(result); // 拼接 查詢條件 // 根據姓名 模糊查詢, attrName 爲 實體類 成員變量名,並不是表字段名 if (StringUtils.isNotEmpty(name)) { query.like("stuName", name); } // 查詢性別 if (ObjectUtils.isNotEmpty(sex)) { query.equal("stuSex", sex); } // 查詢年齡範圍 if (ObjectUtils.isNotEmpty(minAge)) { // 大於等於 query.ge("stuAge", minAge); } if (ObjectUtils.isNotEmpty(maxAge)) { // 小於等於 query.le("stuAge", maxAge); } return query; } }
IStudentSV 繼承抽象Flea JPA SV層接口,並定義兩個方法,分別獲取學生信息列表(分頁)和學生總數。app
/** * <p> 學生SV層接口定義 </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public interface IStudentSV extends IAbstractFleaJPASV<Student> { /** * <p> 學生信息列表 (分頁) </p> * * @param name 學生姓名,能夠模糊查詢 * @param sex 性別 * @param minAge 最小年齡 * @param maxAge 最大年齡 * @param pageNum 查詢頁 * @param pageCount 每頁總數 * @return 學生信息列表 * @throws DaoException 數據操做層異常 * @since 1.0.0 */ List<Student> getStudentList(String name, Integer sex, Integer minAge, Integer maxAge, int pageNum, int pageCount) throws DaoException; /** * <p> 學生總數 </p> * * @param name 學生姓名,能夠模糊查詢 * @param sex 性別 * @param minAge 最小年齡 * @param maxAge 最大年齡 * @return 學生總數 * @throws DaoException 數據操做層異常 * @since 1.0.0 */ long getStudentCount(String name, Integer sex, Integer minAge, Integer maxAge) throws DaoException; }
StudentSVImpl 繼承抽象Flea JPA SV層實現類,並實現了上述學生SV層接口的兩個自定義方法。具體實現參見以下代碼:ide
/** * <p> 學生SV層實現類 </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ @Service("studentSV") public class StudentSVImpl extends AbstractFleaJPASVImpl<Student> implements IStudentSV { // 注入學生DAO層實現類 @Autowired @Qualifier("studentDAO") private IStudentDAO studentDao; @Override public List<Student> getStudentList(String name, Integer sex, Integer minAge, Integer maxAge, int pageNum, int pageCount) throws DaoException { return studentDao.getStudentList(name, sex, minAge, maxAge, pageNum, pageCount); } @Override public long getStudentCount(String name, Integer sex, Integer minAge, Integer maxAge) throws DaoException { return studentDao.getStudentCount(name, sex, minAge, maxAge); } // 可參見AbstractFleaJPASVImpl裏的實現 @Override protected IAbstractFleaJPADAO<Student> getDAO() { return studentDao; } }
新增學生信息
private ApplicationContext applicationContext; @Before public void init() { applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); LOGGER.debug("ApplicationContext={}", applicationContext); } @Test public void testInsertStudent() { try { IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV"); Student student = new Student(); student.setStuName("張三"); student.setStuAge(18); student.setStuSex(1); student.setStuState(1); studentSV.save(student); student = new Student(); student.setStuName("李四"); student.setStuAge(19); student.setStuSex(1); student.setStuState(1); studentSV.save(student); student = new Student(); student.setStuName("王二麻子"); student.setStuAge(20); student.setStuSex(1); student.setStuState(1); studentSV.save(student); } catch (Exception e) { LOGGER.error("Exception : ", e); } }
執行結果:
@Test public void testStudentUpdate() { try { IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV"); // 根據主鍵查詢學生信息 Student student = studentSV.query(3L); LOGGER.debug("Before : {}", student); student.setStuName("王三麻子"); student.setStuAge(19); // 更新學生信息 studentSV.update(student); // 最後再根據主鍵查詢學生信息 student = studentSV.query(3L); LOGGER.debug("After : {}", student); } catch (Exception e) { LOGGER.error("Exception : ", e); } }
運行結果:
@Test public void testStudentDelete() { try { IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV"); // 根據主鍵查詢學生信息 Student student = studentSV.query(3L); LOGGER.debug("Before : {}", student); // 刪除學生信息(裏面會先去將學生實體信息查出來,而後再刪除) studentSV.remove(3L); // 最後再根據主鍵查詢學生信息 student = studentSV.query(3L); LOGGER.debug("After : {}", student); } catch (Exception e) { LOGGER.error("Exception : ", e); } }
運行結果:
查詢學生信息(按條件分頁查詢)
表裏自行再插入些數據,用於測試查詢,查詢結果因各自表數據而異;
目前我表中數據以下:
@Test public void testStudentQueryPage() { try { IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV"); List<Student> studentList = studentSV.getStudentList("張三", 1, 18, 20, 1, 5); LOGGER.debug("Student List = {}", studentList); } catch (Exception e) { LOGGER.error("Exception : ", e); } }
運行結果:
@Test public void testStudentQueryCount() { try { IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV"); long count = studentSV.getStudentCount("張三", 1, 18, 20); LOGGER.debug("Student Count = {}", count); } catch (Exception e) { LOGGER.error("Exception : ", e); } }
運行結果:
看到這裏,咱們的JPA接入工做已經成功完成,本demo工程能夠移步到GitHub查看 flea-jpa-test。在JPA封裝介紹博文中,針對Flea JPA查詢對象還存在的一個併發問題,將在後續的博文中介紹。