<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 雙表查詢 ``` public class Post { private long id; private String title; private String content; @ManyToOne private User creator; ... } public class User { private long id; private String email; private String userName; ... } ``` 此時,我們知道,Post表中creator字段存儲的是User的id。通常情況下,我們可以根據User對象來獲取某個用戶創建的所有博客: ``` List<Post> findByCreator(User user); ``` 但是在這種方式下,如果我們只知道用戶的userName,我們就必須通過UserRepository先拿到User對象,再調用上述方法得到某個用戶創建的所有博客。 實際上,我們通常會通過連表查詢的方式一次性拿到相應的數據。在JPA里面,通常有下面兩種方法: 通過方法名定義 我們可以通過如下語句去定義一個連表查詢, ``` List<Post> findByCreatorUserName(String userName); ``` 此時,Spring Data JPA將按照以下順序創建查詢語句: 首先查找Post對象中是否有creatorUserName屬性,如果有,則直接生成查詢語句… where x.creatorUserName = ?1,我們的Post對象并沒有該屬性,進入下一步 查找是否含有creatorUser屬性,如果有,則看creatorUser是否含有name屬性,如果有,則生成相應的查詢語句,我們的Post對象并沒有該屬性,進入下一步 查找是否有creator屬性,如果依然沒有,則拋出錯誤PropertyReferenceException,我們的Post對象存在該屬性,進入下一步 查找creator是否含有userName屬性,若沒有,依然拋出PropertyReferenceException,我們的User對象存在該屬性,進入下一步 由于creator存在userName屬性,生成查詢語句… where x.creator.userName = ?1 我們可以看到,屬性表達式通過字母的大小寫來與實體對象的屬性進行關聯。但是,如果在Post對象中恰巧有creatorUserName這個屬性,那么,Spring Data JPA將會在第一步就完成查詢語句的生成,但是,這并不是我們所希望的結果。此時,我們可以通過_來控制屬性表達式: ``` List<Post> findByCreator_UserName(String userName); ``` 此時,Spring Data JPA的屬性表達式將直接尋找creator屬性下的userName屬性。 通過@Query標注定義 在JPA中,實際上是可以自己寫sql語句的,方法如下: ``` @Query("select * from post inner join user on post.creator = user.id where user.userName = ?1;", nativeQuery = true) List<Post> findByUser(String userName); ``` # 多表查詢 ## 1.目的:記錄如何 用jpa來實現快速的多表查詢, 暫不深入探究jpa的內部實現 ## 2. 說明情形: @1所涉及的表為t_user(id,name,date,...);t_factory_user(id,factory_id,user_id,...), 其中表s_factory_user[user_id]==t_user[id], 為主外鍵的關聯關系 @2現狀 在entity類User中, 如下代碼: ``` @OneToMany(mappedBy = "s_factory_user", fetch = FetchType.LAZY, cascade = {CascadeType.ALL}) private FactoryUser fu = new FactoryUser(); ``` 在entity類FactoryUser中, 如下代碼: ``` @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) @JoinColumn(name = "user_id") private User user; ``` 添加代碼后, 在啟動項目后會報錯, “org.hibernate.MappingException: Could not determine type for:”, 即為在不能在Use實體類中,定義屬性fu(fu屬性類型為factoryUser); 解決:在查詢了相關文章后, “mappingexception”是指配置hibernate配置文件時錯誤或沒有加載上hbm配置文件。現在該項目中用到的是jpa的注解方式來配置hibernate映射關系,還是我在屬性的注解上有錯誤。 嘗試直接在屬性上添加屬性@Transient, 加載依然報錯,那么現在簡單了解一下@OneToMany的使用; @1.其中的mappedBy指的是關聯類FactoryUser中的屬性名user @2. 在factoryUser類中,@JoinColumn中的name屬性為‘userId’, 是對應的factoryUser的屬性userId 則正常的應該為: 在factoryUser類中 ``` private User user; @OneToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) @JoinColumn(name = "userId") public User getUser() { return user; } ``` 在User類中 ``` private FactoryUser fu; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "user") public FactoryUser getFu() { return fu; } ``` ok, 這樣項目可以正常啟動了。 3.使用jpa的查詢 @1 要集成接口類JpaSpecificationExecutor, 該類提供了幾個方法 ``` T findOne(Specification<T> spec); List<T> findAll(Specification<T> spec); Page<T> findAll(Specification<T> spec, Pageable pageable); ``` @2 具體的使用 ``` <span> </span>Specification<User> spec = new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Predicate p1 = cb.equal(root.get("userCategory").as(Integer.class), 2); // 設置sql鏈接 Join<User, FactoryUser> fuJoin = root.join(root.getModel().getSingularAttribute("fu", FactoryUser.class), JoinType.INNER); Predicate p2 = cb.equal(fuJoin.get("factoryId").as(Long.class), factoryIdFinal); query.where(cb.and(p1, p2)); // 添加排序的功能 query.orderBy(cb.desc(root.get("id").as(Long.class))); return query.getRestriction(); } }; return userDao.findAll(spec); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看