最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?Data?Jpa?復(fù)雜查詢方式總結(jié)(多表關(guān)聯(lián)及自定義分頁)

 更新時間:2022年02月23日 10:10:20   作者:ZhuPengWei_  
這篇文章主要介紹了Spring?Data?Jpa?復(fù)雜查詢方式總結(jié)(多表關(guān)聯(lián)及自定義分頁),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Spring Data Jpa復(fù)雜查詢總結(jié)

只是做一個總結(jié)所以就不多說廢話了

實體類

@Entity
@Table(name = "t_hotel")
@Data
public class THotel {
    @Id
    private int id;
    private String name;
    private String address;
    /**
     * 城市id
     */
    private String city;
}
@Entity
@Table(name = "t_city")
@Data
public class TCity {
    @Id
    private int id;
    private String name;
    private String state;
    private String country;
    private String map;
}

在啟動SpringBoot的時候 SpringDataJpa會自動的在數(shù)據(jù)庫中生成表結(jié)構(gòu).

為了查詢要求,我隨便的增加了一些數(shù)據(jù),如下圖所示

新建接口

public interface TCityRepository extends JpaRepository<TCity, Integer>, JpaSpecificationExecutor<TCity> {? 
}

單元測試類

@RunWith(SpringRunner.class)
@SpringBootTest
public class TCityRepositoryTest{
? ? ?@Autowired
? ? private TCityRepository tCityRepository;
}

1.查找出Id小于3,并且名稱帶有shanghai的記錄

/**
?* 查找出Id小于3,并且名稱帶有`shanghai`的記錄.
?*
?* @param id ? id
?* @param name 城市名稱
?* @return 城市列表
?*/
List<TCity> findByIdLessThanAndNameLike(int id, String name);

單元測試

@Test
public void findByIdLessThanAndNameLike() throws Exception {
? ? List<TCity> shanghai = tCityRepository.findByIdLessThanAndNameLike(3, "%shanghai%");
? ? Assert.assertTrue(shanghai.size() > 0);
}

2.通過旅店名稱分頁查詢旅店以及城市的所有信息

/**
?* 通過旅店名稱分頁查詢旅店以及城市的信息
?*
?* @param name ? ? 旅店名稱
?* @param pageable 分頁信息
?* @return Page<Object[]>
?*/
@Query(value = "select t1.name as cityName,t2.name as hotelName\n" +
? ? ? ? "from t_city t1\n" +
? ? ? ? " ?left join t_hotel t2 on t2.city = t1.id\n" +
? ? ? ? "where t2.name = :name",
? ? ? ? countQuery = "select count(*)" +
? ? ? ? ? ? ? ? "from t_city t1 \n" +
? ? ? ? ? ? ? ? " ?left join t_hotel t2 on t2.city = t1.id\n" +
? ? ? ? ? ? ? ? "where t2.name = :name"
? ? ? ? , nativeQuery = true)
Page<Object[]> findCityAndHotel(@Param("name") String name, Pageable pageable);

為了節(jié)約時間 我只在select 與 from 之間 分別查詢了城市的名稱以及旅店的名稱如果要查所有的信息,可以換成t1.* ,t2.*

單元測試

 @Test
public void findCityAndHotel() throws Exception {
? ? Page<Object[]> cityAndHotel = tCityRepository.findCityAndHotel("酒店", new PageRequest(0, 10));
? ? Assert.assertTrue(cityAndHotel.getTotalElements() > 0);
} ? ?

關(guān)于把List<Object[]> 轉(zhuǎn)換成List<對象> 的方法 我已經(jīng)在上一篇JPA的文章中比較清楚的說了,因此我就不再重復(fù)的敘述一遍了

3.HQL通過旅店名稱查詢旅店以及城市的所有信息

3和2其實是一樣的,為了方便我就不作出分頁查詢了

HQL可以用map來接受返回的參數(shù),具體的用法如下所示:

/**
?* HQL通過旅店名稱查詢旅店以及城市的所有信息
?*
?* @return
?*/
@Query(value = "select new map(t1,t2) from ?TCity t1 left ?join THotel t2 on t1.id=t2.city where t2.name =:name")
List<Map<String, Object>> findCityAndHotelByHQL(@Param("name") String name);

測試方法和2是差不多的 我就不粘貼了

Map<String.Object> 轉(zhuǎn)換實體類的方法也挺多的我就不多說了,如果是直接返回給前臺的話,也沒有必要轉(zhuǎn)換成對象.

4.HQL通過旅店名稱查詢旅店以及城市的所有信息 直接返回實體類

/**
?* 關(guān)聯(lián)查詢
?*
?* @return
?*/
@Query(value = "select new pers.zpw.domain.CityHohel(t1.name AS cityName,t2.name AS hotelName) from ?TCity t1 left ?join THotel t2 on t1.id=t2.city where t2.name =:name")
List<CityHohel> findCityAndHotelByHQLResultObj(@Param("name") String name);

為了方便CityHohel我只封裝了2個屬性,這和HQL查詢的字段是完全一致的,也必須要保持一致.

/**
* Created by ZhuPengWei on 2018/5/12.
*/
@Data
public class CityHohel {
? ? ? ? private String cityName;
? ? ? ? private String hotelName;
? ? ? ??
? ? ? ? public CityHohel(String cityName, String hotelName) {
? ? ? ? ? ? this.cityName = cityName;
? ? ? ? ? ? this.hotelName = hotelName;
? ? ? ? }
}

當(dāng)然這個帶參的構(gòu)造方法是必須要寫的,否則會拋出轉(zhuǎn)換實體的異常

單元測試

@Test
public void findCityAndHotelByHQLResultObj() throws Exception {
? ? List<CityHohel> cityAndHotelByHQLResultObj = tCityRepository.findCityAndHotelByHQLResultObj("酒店");
? ? Assert.assertTrue(cityAndHotelByHQLResultObj.size() > 0);
}

4.HQL通過旅店名稱分頁查詢旅店以及城市的所有信息 直接返回實體類

/**
?* 關(guān)聯(lián)查詢
?*
?* @return
?*/
@Query(value = "select new pers.zpw.domain.CityHohel(t1.name AS cityName,t2.name AS hotelName) from ?TCity t1 left ?join THotel t2 on t1.id=t2.city where t2.name =:name",
? ? ? ? countQuery = "select count(*) from ?TCity t1 left ?join THotel t2 on t1.id=t2.city where t2.name =:name")
Page<CityHohel> findCityAndHotelAllSelf(@Param("name") String name, Pageable pageable);

   

@Test
public void findCityAndHotelAllSelf() throws Exception {
? ? Page<CityHohel> cityAndHotelAllSelf = tCityRepository.findCityAndHotelAllSelf("酒店", new PageRequest(0, 10));
? ? Assert.assertTrue(cityAndHotelAllSelf.getTotalElements() > 0);
}

5.動態(tài)查詢旅店以及城市的所有信息 直接返回實體類

如果是動態(tài)查詢的話當(dāng)然首先得構(gòu)造一條sql去查詢了,當(dāng)然如果不是自定義實體對象的話這樣的網(wǎng)上一大堆我就不寫了.

直接走測試

@Autowired
@PersistenceContext
private EntityManager entityManager;
@Test
public void testDynamic() throws Exception {
? ? ? ? String sql = "select new pers.zpw.domain.CityHohel(t1.name AS cityName,t2.name AS hotelName) from ?TCity t1 left ?join THotel t2 on t1.id=t2.city where t2.name ='酒店'";
? ? ? ? Query query = entityManager.createQuery(sql);
? ? ? ? List resultList = query.getResultList();
? ? ? ? Assert.assertTrue(resultList.size() > 0);
}

這樣測試是通過的,因此可以知道在業(yè)務(wù)層的方法中我們可以動態(tài)的構(gòu)造SQL語句. 比如說可以在接口中這樣子來定義一個方法

? /**
?* 自定義查詢
?* @param sql
?* @param entityManager
?* @return
?*/
default List customQuery(String sql, EntityManager entityManager) {
? ? return entityManager.createQuery(sql).getResultList();
}

然后在測試類中動態(tài)的根據(jù)條件去拼接SQL語句去調(diào)用 

JPA#復(fù)雜查詢#自定義查詢

編寫自定義SQL基于下面信息

1. SpringData JPA 在為Repository接口生成實現(xiàn)的時候,會查找是否有 "接口名稱"+"Impl"的類,如果有的話,就把這個類的方法合并到要生成的實現(xiàn)當(dāng)中。

假設(shè):要為接口StudentRepository編寫自定義sql查詢。

基于最前面的信息,要編寫自定義SQL

需要下面三步:

1. 自定義一個接口,在在接口中聲明方法StudentCoustomRepository,這個自定義接口名稱不重要;

2. 讓目標(biāo)接口繼承自定義接口,這樣目標(biāo)接口就有了相應(yīng)的方法;

3. 編寫自定義方法的實現(xiàn)類,這個類需要使用"目標(biāo)接口名稱"+"Impl"為類名,

即StudentRepositoryImpl,這樣SpringDataJpa 為StudentRepository生成實現(xiàn)的時候就會包含這里面的方法了。

public class StudentRepositoryImpl implements StudentCoustomRepository {
     
    // 這里可以寫很復(fù)雜的SQL,作為演示之用,就不弄那么復(fù)雜
    private static final String SQL = "select * from t_student where name like :name ";     
    @PersistenceContext
    private EntityManager em; 
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public List<StudentVO> findByName(String name) {
        Query query = em.createNativeQuery(SQL).setParameter("name", "%"+name+"%");
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List queryList = query.getResultList();
         
        if (queryList.size() == 0) {
            System.out.println("找不到Student name為" + name + "的記錄");
            return null;
        }         
        List<StudentVO> retVal = new ArrayList<>();
        for(Object o : queryList) {
            Map student = (Map)o;
            StudentVO vo = new StudentVO();
            try {
                // org.apache.commons.beanutils.BeanUtils;
                // 使用apaches的beanutil,直接吧map轉(zhuǎn)為實例
                BeanUtils.populate(vo, student);
                retVal.add(vo);
            } catch (IllegalAccessException | InvocationTargetException e) {
                System.out.println("解析StudentVO bean時發(fā)生異常:" + e.getMessage());
            }
        }
        return retVal;
    }
}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中Cron表達(dá)式的生成解析及計算的工具類完整代碼

    Java中Cron表達(dá)式的生成解析及計算的工具類完整代碼

    這篇文章主要給大家介紹了關(guān)于Java中Cron表達(dá)式的生成解析及計算工具類的相關(guān)資料,Cron表達(dá)式是一個字符串,字符串空格分割,每一個域代表一個含義,一個cron表達(dá)式有至少6個,需要的朋友可以參考下
    2023-12-12
  • Java并發(fā)包之CopyOnWriteArrayList類的深入講解

    Java并發(fā)包之CopyOnWriteArrayList類的深入講解

    這篇文章主要給大家介紹了關(guān)于Java并發(fā)包之CopyOnWriteArrayList類的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • SpringBoot中使用Flyway進(jìn)行數(shù)據(jù)庫遷移的詳細(xì)流程

    SpringBoot中使用Flyway進(jìn)行數(shù)據(jù)庫遷移的詳細(xì)流程

    本文介紹了如何在Spring Boot項目中使用Flyway進(jìn)行數(shù)據(jù)庫遷移,Flyway通過SQL腳本管理數(shù)據(jù)庫變更,支持自動執(zhí)行和版本控制,避免了手動執(zhí)行SQL腳本的錯誤和維護(hù)困難,需要的朋友可以參考下
    2025-02-02
  • 解決@Around對靜態(tài)方法不生效的問題

    解決@Around對靜態(tài)方法不生效的問題

    這篇文章主要介紹了解決@Around對靜態(tài)方法不生效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • SpringMVC 參數(shù)綁定之視圖傳參到控制器的實現(xiàn)代碼

    SpringMVC 參數(shù)綁定之視圖傳參到控制器的實現(xiàn)代碼

    這篇文章主要介紹了SpringMVC 參數(shù)綁定之視圖傳參到控制器的相關(guān)知識,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • mybatis框架入門學(xué)習(xí)教程

    mybatis框架入門學(xué)習(xí)教程

    MyBatis是一個支持普通SQL查詢,存儲過程和高級映射的優(yōu)秀持久層框架。這篇文章主要介紹了mybatis框架入門學(xué)習(xí)教程,需要的朋友可以參考下
    2017-02-02
  • 淺談java中BigDecimal的equals與compareTo的區(qū)別

    淺談java中BigDecimal的equals與compareTo的區(qū)別

    下面小編就為大家?guī)硪黄獪\談java中BigDecimal的equals與compareTo的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • Springboot如何使用logback實現(xiàn)多環(huán)境配置?

    Springboot如何使用logback實現(xiàn)多環(huán)境配置?

    上一篇文章中老顧介紹了logback基本配置,了解了日志配置的基本方式.我們平時在系統(tǒng)開發(fā)時,開發(fā)環(huán)境與生產(chǎn)環(huán)境的日志配置會不一樣;那今天老顧就跟大家介紹一下如何實現(xiàn)多環(huán)境配置,需要的朋友可以參考下
    2021-06-06
  • Java中的Sort排序問題

    Java中的Sort排序問題

    這篇文章主要介紹了Java中的Sort排序問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 聊聊maven與jdk版本對應(yīng)關(guān)系

    聊聊maven與jdk版本對應(yīng)關(guān)系

    這篇文章主要介紹了maven與jdk版本對應(yīng)關(guān)系,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評論

河东区| 潼南县| 和静县| 中山市| 德令哈市| 阳西县| 文水县| 金堂县| 吴旗县| 黑山县| 沈阳市| 双城市| 拜城县| 济阳县| 北京市| 泰兴市| 西充县| 安远县| 武隆县| 怀仁县| 鄱阳县| 邻水| 黄浦区| 莲花县| 甘孜| 濉溪县| 星子县| 布拖县| 读书| 巴楚县| 赤水市| 林州市| 天祝| 新津县| 宜黄县| 青州市| 天台县| 旅游| 赤壁市| 阿荣旗| 贵阳市|