1. 程式人生 > 遊戲 >Steam免費送出太空策略建造遊戲《火星求生》

Steam免費送出太空策略建造遊戲《火星求生》

JPA
  • 簡介
    • JPA 是 Java Persistence API 的簡稱,是一套 Sun 公司 Java 官方制定的 ORM(Object Relational Mapping) 方案,是規範、是標準,Sun 公司自己並沒有實現;
    • 市場上的主流的 JPA 框架有:Hibernate (JBoos)、EclipseTop(Eclipse社群)、OpenJPA (Apache基金會),Hibernate 是眾多實現者之中,效能最好的,我們引入的 JPA 框架,採用Hibernate實現,需要注意的是,引用是 javax.persistence 這個“標準”包,和 org.hibernate 實現包
    • JPA 想要做的就是儘量讓你少寫 Sql,甚至不寫 Sql,基於這種思想,JPA 實現了它自己的一套語法、註解規則,JPA 要用各種註解配合來實現資料實體間一對多、多對多等關聯關係,正因為這樣,個人覺得實體變得不那麼單純,摻雜了邏輯在裡面,這增加了實體的複雜度,對於比較複雜的業務來說,很容易造成實體間直接或間接的迴圈引用;
    • 在此,我們引入將引入 Spring Data Jpa,在 JPA 之上新增另一層抽象(Repository 層的實現),極大地簡化持久層開發;
    • Hibernate、JPA、Spring Data Jpa 之間的關係如下:
  • 引入 Jar
    • spring-context
    • spring-orm
    • mysql-connector-java
    • c3p0
    • hibernate-core
    • spring-data-jpa
    • ---------------- 已經引入的部分忽略 ----------------
    • 1 <wiz_code_mirror> 1
      <!-- Spring data jpa -->
      2
      <dependency>
      3
          <groupId>org.springframework.data</groupId>
      4
          <artifactId>spring-data-jpa</artifactId>
      5
          <version>2.3.4.RELEASE</version>
      6
      </dependency>
    • 2
  • 配置
    • 配置結構
      • applicationContext.xml ---- 全域性配置,為了避免該檔案雜亂,我們按功能拆分為子配置檔案;
        • 引入 jdbcParms.properties ---- Jdbc 配置資訊;
        • 引入 hibernateParms.properties ---- Hibernate 配置屬性資訊;
        • 引入 springJpa.xml ---- JPA 注入 Spring 配置;
    • applicationContext.xml
      • 1 <wiz_code_mirror> 1
        <!-- 載入屬性檔案 -->
        2
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        3
            <property name="locations">
        4
               <list>
        5
                  <value>classpath:config/properties/jdbcParms.properties</value>
        6
                  <value>classpath:config/properties/hibernateParms.properties</value>
        7
                </list>
        8
            </property>
        9
        </bean>
        10
        
        
        
        
        11
        
        
        <!-- 引入別的配置檔案 -->
        12
        <import resource="springJpa.xml"/>
      • 2
    • hibernateParms.properties
      • 參見 Hibernate 相關配置;
    • springJpa.xml
      • 配置鏈
        • dataSource ---- entityManagerFactory ---- transactionManager ---- jpa:repositories;
      • 1 <wiz_code_mirror> 1
        <?xml version="1.0" encoding="UTF-8"?>
        2
        <beans xmlns="http://www.springframework.org/schema/beans" 
        3
               xmlns:context="http://www.springframework.org/schema/context" 
        4
               xmlns:aop="http://www.springframework.org/schema/aop" 
        5
               xmlns:tx="http://www.springframework.org/schema/tx" 
        6
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        7
               xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
        8
               xsi:schemaLocation="http://www.springframework.org/schema/beans 
        9
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
        10
                http://www.springframework.org/schema/context 
        11
                http://www.springframework.org/schema/context/spring-context-3.0.xsd 
        12
                http://www.springframework.org/schema/mvc 
        13
                http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
        14
                http://www.springframework.org/schema/aop 
        15
                http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
        16
                http://www.springframework.org/schema/tx 
        17
                http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
        18
                http://www.springframework.org/schema/data/jpa 
        19
                http://www.springframework.org/schema/data/jpa/spring-jpa.xsd" >
        20
        
        
        
        
        21
        
        
            <!-- 資料來源,spring jdbc || c3p0 jdbc -->
        22
            <!-- <bean id="dataSourceForJpa" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        23
                <property name="driverClassName" value="${jdbc.driverClassName}"/>
        24
                <property name="url" value="${jdbc.url}"/>
        25
                <property name="username" value="${jdbc.username}"/>
        26
                <property name="password" value="${jdbc.password}"/>
        27
            </bean> -->
        28
            <!-- 配置 c3p0 資料來源 -->
        29
            <bean id="dataSourceForJpa" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        30
                <property name="driverClass" value="${jdbc.driverClassName}" />  
        31
                <property name="jdbcUrl" value="${jdbc.url}" />  
        32
                <property name="user" value="${jdbc.username}" />  
        33
                <property name="password" value="${jdbc.password}" /> 
        34
        
        
        
        
        35
        
        
                <!-- 連線池中連線用完時,c3p0 一次性建立的連線數 -->
        36
                <property name="acquireIncrement" value="${pool.acquireIncrement}" />
        37
                <!-- 初始化連線數,在 minPoolSize maxPoolSize 之間 -->
        38
                <property name="initialPoolSize" value="${pool.initialPoolSize}" />
        39
                <property name="minPoolSize" value="${pool.minPoolSize}" />
        40
                <property name="maxPoolSize" value="${pool.maxPoolSize}" />
        41
                <!-- 連線關閉時預設將所有未提交的操作回滾,預設為 false -->
        42
                <property name="autoCommitOnClose" value="${pool.autoCommitOnClose}"/>
        43
            </bean>
        44
        
        
        
        
        45
        
        
            <!-- 配置 entityManagerFactory -->
        46
            <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        47
                <!-- 設定資料來源 -->
        48
                <property name="dataSource" ref="dataSourceForJpa" />
        49
                <!-- 掃描 Entity -->
        50
                <property name="packagesToScan" value="com.sfac.springMvc.module.*.entity" />
        51
                <!-- 指定 JPA 實現廠商 -->
        52
                <property name="persistenceProvider">
        53
                    <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
        54
                </property>
        55
                <!-- 指定 JPA 供應商介面卡 -->
        56
                <property name="jpaVendorAdapter">
        57
                    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        58
                </property>
        59
                <!-- 配置 JPA 屬性 -->
        60
                <property name="jpaProperties">
        61
                    <props>
        62
                        <!-- 動態生成表策略 -->
        63
                        <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
        64
                        <!-- 命名規則隱式策略 -->
        65
                        <prop key="hibernate.implicit_naming_strategy">${hibernate.implicit_naming_strategy}</prop>
        66
                        <!-- 資料庫方言 -->
        67
                        <prop key="hibernate.dialect">${hibernate.dialect}</prop>
        68
                        <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
        69
                        <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
        70
                    </props>
        71
                </property>
        72
            </bean>
        73
        
        
        
        
        74
        
        
            <!-- 配置事務管理器 -->
        75
            <bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        76
                <property name="entityManagerFactory" ref="entityManagerFactory" />
        77
            </bean>
        78
        
        
        
        
        79
        
        
            <!-- 開啟事務註解 -->
        80
            <tx:annotation-driven transaction-manager="jpaTransactionManager"/>
        81
        
        
        
        
        82
        
        
            <!-- 配置 repository -->
        83
            <jpa:repositories base-package="com.sfac.springMvc.module.*.repository" 
        84
                transaction-manager-ref="jpaTransactionManager" 
        85
                entity-manager-factory-ref="entityManagerFactory" />
        86
        </beans>
      • 2
  • 應用
    • 主要介面和實現類
      • Repository
        • 屬性查詢
          • 介面方法命名:
            • findBy + 屬性 + 關鍵字 + 屬性(option);
            • find + Top || First(option) +By +屬性 + 關鍵字 + 屬性(option);
          • 查詢關鍵字列表
            • And ---- findByLastnameAndFirstname ---- … where x.lastname = ?1 and x.firstname = ?2;
            • Or ---- findByLastnameOrFirstname ---- … where x.lastname = ?1 or x.firstname = ?2;
            • Is,Equals ---- findByFirstname,findByFirstnameIs,findByFirstnameEquals ---- … where x.firstname = ?1;
            • Between ---- findByStartDateBetween ---- … where x.startDate between ?1 and ?2;
            • LessThan ---- findByAgeLessThan ---- … where x.age < ?1;
            • LessThanEqual ---- findByAgeLessThanEqual ---- … where x.age <= ?1;
            • GreaterThan ---- findByAgeGreaterThan ---- … where x.age > ?1;
            • GreaterThanEqual ---- findByAgeGreaterThanEqual ---- … where x.age >= ?1;
            • After ---- findByStartDateAfter ---- … where x.startDate > ?1;
            • Before ---- findByStartDateBefore ---- … where x.startDate < ?1;
            • IsNull ---- findByAgeIsNull ---- … where x.age is null;
            • IsNotNull,NotNull ---- findByAge(Is)NotNull ---- … where x.age not null;
            • Like ---- findByFirstnameLike ---- … where x.firstname like ?1;
            • NotLike ---- findByFirstnameNotLike ---- … where x.firstname not like ?1;
            • StartingWith ---- findByFirstnameStartingWith ---- … where x.firstname like ?1 (parameter bound with appended %);
            • EndingWith ---- findByFirstnameEndingWith ---- … where x.firstname like ?1 (parameter bound with prepended %);
            • Containing ---- findByFirstnameContaining ---- … where x.firstname like ?1 (parameter bound wrapped in %);
            • OrderBy ---- findByAgeOrderByLastnameDesc ---- … where x.age = ?1 order by x.lastname desc;
            • Not ---- findByLastnameNot ---- … where x.lastname <> ?1;
            • In ---- findByAgeIn(Collection<Age> ages) ---- … where x.age in ?1;
            • NotIn ---- findByAgeNotIn(Collection<Age> ages) ---- … where x.age not in ?1;
            • True ---- findByActiveTrue() ---- … where x.active = true;
            • False ---- findByActiveFalse() ---- … where x.active = false;
            • IgnoreCase ---- findByFirstnameIgnoreCase ---- … where UPPER(x.firstame) = UPPER(?1);
        • @Query 註解查詢;
          • 查詢語言
            • SQL 語言
              • 關係型資料庫查詢語言;
              • select name, age, user_id from t_user;
              • JPA 中使用 Sql 語句,只需註解中新增引數 nativeQuery = true 即可;
            • HQL 語言
              • Hibernate 造出來的物件語言,只有 Hibernate 框架能夠解析,並將其通過一系列的對映轉換,拼湊成 SQL 語言;
              • 使用 “類名” 取代 “表名”,用 “類名.屬性名” 取代 “表名.列名”,類名建議不要省略;
              • 沒有 * 查詢,使用 from 類名 代替;
              • 查詢操作使用 @Query 註解
              • 刪除修改操作使用 @Modifying + @Transactional +@Query註解,@Transactional 可加在 service 層;
            • JPQL 語言
              • EJB3.0 中的 JPA 造出來的物件查詢語言,其原型類似於 HQL,Sun 看到 Hibernate 做的 ORM 技術做的非常好,成為行業內領導 ORM 框架的主流產品,故 Sun 將其吸收進 EJB3 中,制定了一套 ORM 的 JAVA API 標準;
          • 傳參方式
            • select name,age,userId from User where userName = ?1; ---- ?加數字表示佔位符,從 1 開始;
            • select name,age,userId from User where userName=:userName; ---- :加上變數名,這裡是與方法引數中有 @PARAM 的值匹配;
      • CrudRepository
        • 添加了對資料的增刪改查的方法;
      • PagingAndSortingRepository
        • 添加了對資料的分頁和排序方法;
      • QueryByExampleExecutor
        • Example 條件查詢;
      • JpaRepository
        • 對繼承父介面中方法的返回值進行了適配,在父類介面中通常都返回迭代器,需要我們自己進行強制型別轉化,而在 JpaRepository 中,直接返回了 List;
      • JpaSpecificationExecutor
        • 主要提供了多條件查詢的支援,並且可以在查詢中新增分頁和排序,因為這個介面單獨存在,因此需要配合以上說的介面使用;
      • QueryDslPredicateExecutor
      • SimpleJpaRepository ---- 實現類;
      • QueryDslJpaRepository ---- 實現類;
    • 新增介面
      • 針對每個 Bean 書寫一個持久層介面,繼承 JpaRepository<T, ID> 介面(其中 T 是實體 bean, ID 是主鍵),新增 @Repository 註解,到此,我們一行程式碼都不用寫,即可呼叫父介面實現功能;
      • StudentRepository.java
        • 1 <wiz_code_mirror> 1
          @Repository
          2
          public interface StudentRepository extends JpaRepository<Student, Integer> {
          3
          }
        • 2
      • StudentServiceImpl.java
        • 1 <wiz_code_mirror> 1
          @Autowired
          2
          private StudentRepository studentRepository;
          3
          
          
          
          
          4
          
          
          @Override
          5
          @Transactional("jpaTransactionManager")
          6
          public ResultEntity<Student> insertStudentForJpa(Student student) {
          7
              studentRepository.saveAndFlush(student);
          8
              return new ResultEntity<Student>(ResultStatus.SUCCESS.status, "Insert success.", student);
          9
          }
        • 2
      • StudentController.java
        • 1 <wiz_code_mirror> 1
          /**
          2
           * 127.0.0.1/api/jpa/student ---- post
          3
           * {"studentName":"HymanHu"}
          4
           * {"studentName":"HymanHu", "studentCard":{"cardNo":"studentCard001"}}
          5
           */
          6
          @PostMapping(value = "/jpa/student", consumes = "application/json")
          7
          public ResultEntity<Student> insertStudentForJpa(@RequestBody Student student) {
          8
              return studentService.insertStudentForJpa(student);
          9
          }
        • 2
    • 修改介面
      • StudentServiceImpl.java
        • 1 <wiz_code_mirror> 1
          @Override
          2
          @Transactional("jpaTransactionManager")
          3
          public ResultEntity<Student> updateStudentForJpa(Student student) {
          4
              studentRepository.saveAndFlush(student);
          5
          //  int i = 1 / 0;
          6
              return new ResultEntity<Student>(ResultStatus.SUCCESS.status, "Update success.", student);
          7
          }
        • 2
      • StudentController.java
        • 1 <wiz_code_mirror> 1
          /**
          2
           * 127.0.0.1/api/jpa/student ---- put
          3
           * {"id":"2","studentName":"HymanHu1"}
          4
           * {"id":"2","studentName":"HymanHu1","studentCard":{"id":"1","cardNo":"studentCard002"}}
          5
           */
          6
          @PutMapping(value = "/jpa/student", consumes = "application/json")
          7
          public ResultEntity<Student> updateStudentForJpa(@RequestBody Student student) {
          8
              return studentService.updateStudentForJpa(student);
          9
          }
        • 2
    • 刪除介面
      • StudentServiceImpl.java
        • 1 <wiz_code_mirror> 1
          @Override
          2
          public ResultEntity<Object> deleteStudentForJpa(Integer id) {
          3
              studentRepository.deleteById(id);
          4
              return new ResultEntity<Object>(ResultStatus.SUCCESS.status, "Delete success.");
          5
          }
        • 2
      • StudentController.java
        • 1 <wiz_code_mirror> 1
          /**
          2
           * 127.0.0.1/api/jpa/student/2 ---- delete
          3
           */
          4
          @DeleteMapping("/jpa/student/{id}")
          5
          public ResultEntity<Object> deleteStudentForJpa(@PathVariable Integer id) {
          6
              return studentService.deleteStudentForJpa(id);
          7
          }
        • 2
    • 父介面查詢
      • StudentServiceImpl.java
        • 1 <wiz_code_mirror> 1
          @Override
          2
          public Student getStudentByIdForJpa(Integer id) {
          3
              return studentRepository.findById(id).orElse(null);
          4
          }
          5
          @Override
          6
          public List<Student> getStudentsForJpa() {
          7
              return studentRepository.findAll();
          8
          }
        • 2
      • StudentController.java
        • 1 <wiz_code_mirror> 1
          /**
          2
           * 127.0.0.1/api/jpa/student/9 ---- get
          3
           */
          4
          @GetMapping("/jpa/student/{id}")
          5
          public Student getStudentByIdForJpa(@PathVariable Integer id) {
          6
              return studentService.getStudentByIdForJpa(id);
          7
          }
          8
          /**
          9
           * 127.0.0.1/api/jpa/students ---- get
          10
           */
          11
          @GetMapping("/jpa/students")
          12
          public List<Student> getStudentsForJpa(@RequestParam(required = false) String studentName) {
          13
              return studentService.getStudentsForJpa();
          14
          }
        • 2
    • Example && Criteria 查詢
      • JpaRepository:<S extends T> Page<S> findAll(Example<S> example, Pageable pageable);
        • Example:動態條件查詢樣本 ----static <T> Example<T> of(T probe, ExampleMatcher matcher);
          • T:實體 bean;
          • ExampleMatcher:查詢匹配器;
            • ExampleMatcher.matchingAny() ---- 匹配條件是 or 的關係;
            • ExampleMatcher.matching() ---- 匹配條件是 and 的關係;
            • withMatcher("studentName", match -> match.contains()) ---- 模糊查詢,即 %studentName%;
            • withIgnorePaths("studentId", "createDate"); ---- 忽略欄位,可以自動忽略空值的欄位,但 id 是基本資料型別,預設值為 0,必須忽略;
        • Pageable:分頁元件 ---- public static PageRequest of(int page, int size, Sort sort);
          • page:當前頁,從 0 開始;
          • size:每頁大小;
          • sort:排序物件 ---- new Sort(direction, orderBy);
            • direction:排序方向,Sort.Direction.ASC;
            • orderBy:排序欄位;
        • Page:返回分頁物件;
      • JpaSpecificationExecutor:Page findAll(@Nullable Specification<T> spec, Pageable pageable);
        • Specification:Criteria 多條件查詢,支援時間比較、數字比較等;
        • Pageable
        • Page
      • StudentRepository.java
        • 1 <wiz_code_mirror> 1
          @Repository
          2
          public interface StudentRepository extends JpaRepository<Student, Integer>, JpaSpecificationExecutor<Student> {
          3
          }
        • 2
      • StudentServiceImpl.java
        • 1 <wiz_code_mirror> 1
          @Override
          2
          public Page<Student> getStudentsBySearchBeanForJpa(SearchBean searchBean) {
          3
              searchBean.initSearchBean();
          4
          //      Page<Student> page = exampleAndPage(searchBean);
          5
              Page<Student> page = criteriaAndPage(searchBean);
          6
              return page;
          7
          }
          8
          
          
          
          
          9
          
          
          /**
          10
           * -實現方式一:Example + Page 查詢
          11
           */
          12
          public Page<Student> exampleAndPage(SearchBean searchBean) {
          13
              // 建立 Pageable 物件
          14
              String orderBy = StringUtils.isBlank(searchBean.getOrderBy()) ? "id" : searchBean.getOrderBy();
          15
              Sort.Direction direction = StringUtils.isBlank(searchBean.getDirection()) || 
          16
                      searchBean.getDirection().equalsIgnoreCase("asc") ? Sort.Direction.ASC : Sort.Direction.DESC;
          17
              Sort sort = new Sort(direction, orderBy);
          18
              // 當前頁起始為 0
          19
              Pageable pageable = PageRequest.of(searchBean.getCurrentPage() - 1, searchBean.getPageSize(), sort);
          20
          
          
          
          
          21
          
          
              // 建立 Example 物件
          22
              Student student = new Student();
          23
              student.setStudentName(searchBean.getKeyWord());
          24
              student.setCreateDate(LocalDateTime.of(2021, 1, 19, 0, 0));
          25
              // matchingAny 相當於 or 連線查詢條件,matching 相當於 and 連線查詢條件
          26
              ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny()
          27
                      // 模糊查詢,即 %{studentName} %
          28
                      .withMatcher("studentName", match -> match.contains())
          29
                      // 時間型別不支援模糊查詢,生成的語句為createDate=?,同時也不支援 id > startId && id < endId 這樣的操作
          30
                      .withMatcher("createDate", match -> match.contains())
          31
                      // 忽略基本資料型別欄位,如果使用包裝類則無需忽略
          32
                      .withIgnorePaths("id");
          33
              Example<Student> example = Example.of(student, exampleMatcher);
          34
          
          
          
          
          35
          
          
              return studentRepository.findAll(example, pageable);
          36
          }
          37
          
          
          
          
          38
          
          
          /**
          39
           * -實現方式:Criteria + Page
          40
           */
          41
          public Page<Student> criteriaAndPage(SearchBean searchBean) {
          42
              // 建立 Pageable 物件
          43
              String orderBy = StringUtils.isBlank(searchBean.getOrderBy()) ? "id" : searchBean.getOrderBy();
          44
              Sort.Direction direction = StringUtils.isBlank(searchBean.getDirection()) || 
          45
                      searchBean.getDirection().equalsIgnoreCase("asc") ? Sort.Direction.ASC : Sort.Direction.DESC;
          46
              Sort sort = new Sort(direction, orderBy);
          47
              // 當前頁起始為 0
          48
              Pageable pageable = PageRequest.of(searchBean.getCurrentPage() - 1, searchBean.getPageSize(), sort);
          49
          
          
          
          
          50
          
          
              // 建立 Specification 物件
          51
              Specification<Student> specification = new Specification<Student>() {
          52
                  private static final long serialVersionUID = 1L;
          53
          
          
          
          
          54
          
          
                  /**
          55
                   * -構造語句 select * from test_student where createDate>=? and 
          56
                   * (studentName like ? or id between 10 and 20) order by id desc limit ?
          57
                   */
          58
                  @Override
          59
                  public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, 
          60
                          CriteriaBuilder criteriaBuilder) {
          61
          
          
          
          
          62
          
          
                      return criteriaBuilder.and(
          63
                          criteriaBuilder.greaterThanOrEqualTo(
          64
                              root.get("createDate").as(LocalDateTime.class), 
          65
                              LocalDateTime.of(2021, 1, 20, 0, 0)),
          66
                          criteriaBuilder.or(
          67
                              criteriaBuilder.like(root.get("studentName").as(String.class), 
          68
                                      String.format("%%%s%%", searchBean.getKeyWord())),
          69
                              criteriaBuilder.between(root.get("id"), 10, 20)
          70
                          )
          71
                      );
          72
                  }
          73
              };
          74
          
          
          
          
          75
          
          
              return studentRepository.findAll(specification, pageable);
          76
          }
        • 2
      • StudentController.java
        • 1 <wiz_code_mirror> 1
          /**
          2
           * 127.0.0.1/api/jpa/students ---- post
          3
           * {"currentPage":1, "pageSize":5, "keyWord":"hy", "orderBy":"id", "direction":"desc"}
          4
           * {"currentPage":1, "pageSize":5, "keyWord":"hu", "orderBy":"studentName", "direction":"asc"}
          5
           * -注意:排序欄位不能使用下劃線
          6
           * 
          7
           */
          8
          @PostMapping(value = "/jpa/students", consumes = "application/json")
          9
          public Page<Student> getStudentsBySearchBeanForJpa(@RequestBody SearchBean searchBean) {
          10
              return studentService.getStudentsBySearchBeanForJpa(searchBean);
          11
          }
        • 2
    • 屬性查詢
      • StudentRepository.java
        • 1 <wiz_code_mirror> 1
          List<Student> findByStudentName(String studentName);
        • 2
      • StudentServiceImpl.java
        • 1 <wiz_code_mirror> 1
          @Override
          2
          public Student getStudentByNameForJpa(String studentName) {
          3
              List<Student> students = Optional.ofNullable(studentRepository.findByStudentName(studentName))
          4
                      .orElse(Collections.emptyList());
          5
              return students.isEmpty() ? null : students.get(0);
          6
          }
        • 2
      • StudentController.java
        • 1 <wiz_code_mirror> 1
          /**
          2
           * 127.0.0.1/api/jpa/student?studentName=HymanHu ---- get
          3
           */
          4
          @GetMapping("/jpa/student")
          5
          public Student getStudentByNameForJpa(@RequestParam String studentName) {
          6
              return studentService.getStudentByNameForJpa(studentName);
          7
          }
        • 2
    • Sql && Hql 查詢
      • StudentRepository.java
        • 1 <wiz_code_mirror> 1
          //@Query(nativeQuery = true, value = "select * from test_student where id = :id")
          2
          @Query(value = "from Student where id = :id")
          3
          Student getStudentById(@Param("id") Integer id);
          4
          
          
          
          
          5
          
          
          @Modifying
          6
          //@Query(nativeQuery = true, value = "update test_student set student_name = :studentName where id = :id")
          7
          @Query(value = "update Student set studentName = :studentName where id = :id")
          8
          void updateStudentName(@Param("studentName") String studentName, @Param("id") Integer id);
          9
          
          
          
          
          10
          
          
          @Modifying
          11
          @Query(nativeQuery = true, value = "update test_student " +
          12
                  "set student_name = :#{#student.studentName} where id = :#{#student.id}")
          13
          void updateStudent(@Param("student") Student student);
        • 2
      • StudentServiceImpl.java
        • 1 <wiz_code_mirror> 1
          @Override
          2
          public Student getStudentByIdV2ForJpa(Integer id) {
          3
              return studentRepository.getStudentById(id);
          4
          }
          5
          
          
          
          
          6
          
          
          @Override
          7
          @Transactional("jpaTransactionManager")
          8
          public ResultEntity<Student> updateStudentNameForJpa(Student student) {
          9
              studentRepository.updateStudentName(student.getStudentName(), student.getId());
          10
              return new ResultEntity<Student>(ResultStatus.SUCCESS.status, "Update success.", student);
          11
          }
        • 2
      • StudentController.java
        • 1 <wiz_code_mirror> 1
          /**
          2
           * 127.0.0.1/api/jpa/student/2/v2 ---- get
          3
           */
          4
          @GetMapping("/jpa/student/{id}/v2")
          5
          public Student getStudentByIdV2ForJpa(@PathVariable Integer id) {
          6
              return studentService.getStudentByIdV2ForJpa(id);
          7
          }
          8
          
          
          
          
          9
          
          
          /**
          10
           * 127.0.0.1/api/jpa/student/v2 ---- put
          11
           * {"id":"1","studentName":"HymanHu1"}
          12
           */
          13
          @PutMapping(value = "/jpa/student/v2",consumes = "application/json")
          14
          public ResultEntity<Student> updateStudentNameForJpa(@RequestBody Student student) {
          15
              return studentService.updateStudentNameForJpa(student);
          16
          }
        • 2
    • 批量介面
      • 思路
        • 方式一:父介面中有 saveAll、deleteInBatch 方法,可完成批量增刪改操作,在此不做贅述;
        • 方式二:引入 @persistencecontext 註解和 EntityManager 類,屬於 Jpa 包,用途是將 Entity 在記憶體操作,處理完成之後再一次性同步到資料庫,效率要比第一種方式高;
      • StudentServiceImpl.java
        • 1 <wiz_code_mirror> 1
          @PersistenceContext
          2
          private EntityManager entityManager;
          3
          
          
          
          
          4
          
          
          @Override
          5
          @Transactional
          6
          public ResultEntity<List<Student>> batchInsertStudentsForJpa(List<Student> students) {
          7
              // 方式一,呼叫父介面完成批量操作
          8
          //      studentRepository.saveAll(students);
          9
          //      studentRepository.flush();
          10
          
          
          
          
          11
          
          
              // 方式二,引入 entityManager 進行批量操作,效率高於第一種方式
          12
              students.stream().forEach(item -> {
          13
                  entityManager.persist(item);
          14
              });
          15
              entityManager.flush();
          16
              entityManager.clear();
          17
              return new ResultEntity<List<Student>>(ResultStatus.SUCCESS.status, "Update success.", students);
          18
          }
        • 2
      • StudentController.java
        • 1 <wiz_code_mirror> 1
          /**
          2
           * 127.0.0.1/api/jpa/students/v2 ---- post
          3
           * [{"studentName":"aa1"},{"studentName":"aa2"}]
          4
           */
          5
          @PostMapping(value = "/jpa/students/v2", consumes = "application/json")
          6
          public ResultEntity<List<Student>> batchInsertStudentsForJpa(@RequestBody List<Student> students) {
          7
              return studentService.batchInsertStudentsForJpa(students);
          8
          }
        • 2
  • 練習
    • 建立 User、Role、UserRole、Resource、RoleResource 五個 Bean,使用 Jpa 自動生成表(中間表不要外來鍵關係),使用 Mybatis Or Jpa 實現 User、 Role、Resource 的增刪改查介面;