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

Spring?Data?JPA系列QueryByExampleExecutor使用詳解

 更新時(shí)間:2022年09月28日 15:31:39   作者:AKone  
這篇文章主要為大家介紹了Spring?Data?JPA系列QueryByExampleExecutor使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1、QueryByExampleExecutor用法

在前面章節(jié)中,我們介紹了DMQ 和 @Query兩種查詢方法,除此之外,還有QueryByExampleExecutor查詢方法。

1.1 介紹

QueryByExampleExecutor是一種用戶友好的查詢技術(shù),具有簡單的接口,它允許動(dòng)態(tài)創(chuàng)建,并且不需要填寫包含字段名稱的查詢。

1.2 QueryByExampleExecutor接口

public interface QueryByExampleExecutor<T> {
   // 根據(jù)實(shí)體查詢條件、查找一個(gè)對(duì)象
   <S extends T> Optional<S> findOne(Example<S> example);
   // 根據(jù)實(shí)體查詢條件、查詢一批對(duì)象
   <S extends T> Iterable<S> findAll(Example<S> example);
   // 根據(jù)實(shí)體查詢條件并排序、查詢一批對(duì)象
   <S extends T> Iterable<S> findAll(Example<S> example, Sort sort);
   // 根據(jù)實(shí)體查詢條件并分頁,查詢一批對(duì)象
   <S extends T> Page<S> findAll(Example<S> example, Pageable pageable);
   // 根據(jù)實(shí)體查詢條件、查詢符合條件的對(duì)象個(gè)數(shù)
   <S extends T> long count(Example<S> example);
   // 根據(jù)實(shí)體查詢條件、判斷是否有符合條件的對(duì)象
   <S extends T> boolean exists(Example<S> example);
   // 根據(jù)實(shí)體查詢條件、判斷是否有符合條件的對(duì)象
   <S extends T, R> R findBy(Example<S> example, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction);
}

1.3 QueryByExampleExecutor實(shí)踐

第一步 :創(chuàng)建User實(shí)體和UserAddress實(shí)體

// User表
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString(exclude = "address")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String name;
    private String email;
    private Integer age;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    @OneToMany(mappedBy = "user",fetch = FetchType.LAZY)
    private List<UserAddress> address;
}
// Address表
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString(exclude = "user")
public class UserAddress {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String address;
    @ManyToOne(cascade = CascadeType.ALL)
    private User user;
}

第二步: 編寫DAO層,JpaRepository已經(jīng)繼承QueryByExampleExceutor

public interface UserAddressRepo extends JpaRepository<UserAddress,Integer>  {
}

第三步:測試

@Test
public void test01 () {
    User user = User.builder()
            .name("jack")
            .email("123456@126.com")
            .age(20)
            .build();
    userAddressRepo.saveAll(Lists.newArrayList(UserAddress.builder()
            .address("shanghai").user(user).build(),UserAddress.builder()
            .address("beijing").user(user).build()));
}
@Test
public void testQBEE() throws JsonProcessingException {
    User user = User.builder()
            .name("jack")
            .age(20)
            .email("12345")
            .build();
    UserAddress userAddress = UserAddress.builder()
            .address("shanghai")
            .user(user)
            .build();
    ObjectMapper objectMapper = new ObjectMapper();
    // 創(chuàng)建匹配器,構(gòu)建動(dòng)態(tài)查詢條件
    ExampleMatcher exampleMatcher = ExampleMatcher.matching()
            .withMatcher("user.email",ExampleMatcher.GenericPropertyMatchers.startsWith())
            .withMatcher("address",ExampleMatcher.GenericPropertyMatchers.startsWith());
    Page<UserAddress> u = userAddressRepo.findAll(Example.of(userAddress,exampleMatcher), PageRequest.of(0,2));
    System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(u));
}

一開始寫這個(gè)代碼的時(shí)候,我也比較懵逼, Example是什么?ExampleMatcher是什么? 下面我一一介紹。

1.4 Example語法詳解

首先:我們先看Example的源碼

public interface Example<T> {
   static <T> Example<T> of(T probe) {
      return new TypedExample<>(probe, ExampleMatcher.matching());
   }
   static <T> Example<T> of(T probe, ExampleMatcher matcher) {
      return new TypedExample<>(probe, matcher);
   }
   T getProbe();
   ExampleMatcher getMatcher();
   @SuppressWarnings("unchecked")
   default Class<T> getProbeType() {
      return (Class<T>) ProxyUtils.getUserClass(getProbe().getClass());
   }
}
  • probe:實(shí)際實(shí)體類,即查詢條件的封裝類(又可以理解為查詢條件參數(shù))
  • ExampleMatcher :匹配器,匹配特定字段的匹配規(guī)則。
  • Example:由probe 和 ExampleMatcher租車,由于創(chuàng)建查詢,即組合查詢參數(shù)和參數(shù)的匹配規(guī)則。

創(chuàng)建Example的兩個(gè)方法 :

  • static Example of(T probe):需要一個(gè)實(shí)體參數(shù),即查詢條件。而里面的ExampleMatcher采用默認(rèn)的ExamoleMatcher.matching(); 表示忽略NULL,所有字段采用精準(zhǔn)匹配
  • static Example of(T probe, ExampleMatcher matcher):需要兩個(gè)參數(shù)構(gòu)建Example,也就表示ExampleMatcher自由組合規(guī)則,正如我們上面的測試用例里面的代碼一樣。

1.5 ExampleMatcher語法分析

上圖是ExampleMatcher向外暴露的方法,我們只要關(guān)心返回值為ExampleMatcher類型的方法。

其中有三個(gè)方法我們需要注意一下:

static ExampleMatcher matching() {
   return matchingAll();
}
static ExampleMatcher matchingAll() {
   return new TypedExampleMatcher().withMode(MatchMode.ALL);
}

上述的這兩種方法表達(dá)的意思是一樣的。兩者采用的都是MatcheMode.ALL的模式,即AND模式,生成的SQL如下:

Hibernate: select count(useraddres0_.id) as col_0_0_ from user_address useraddres0_ inner join user user1_ on useraddres0_.user_id=user1_.id where (useraddres0_.address like ? escape ?) and user1_.name=? and (user1_.email like ? escape ?) and user1_.age=20

可以看到,這些查詢條件都是AND的關(guān)系。再看另外一種方法

static ExampleMatcher matchingAny() {
   return new TypedExampleMatcher().withMode(MatchMode.ANY);
}

當(dāng)前方法與上面兩個(gè)方法不一樣的地方在于:第三個(gè)MatchMode.Any,表示查詢條件是or的關(guān)系

Hibernate: select count(useraddres0_.id) as col_0_0_ from user_address useraddres0_ inner join user user1_ on useraddres0_.user_id=user1_.id where useraddres0_.address like ? escape ? or user1_.name=? or user1_.email like ? escape ? or user1_.age=20

以上就是初始化ExampleMatcher實(shí)例的方法,你在運(yùn)用中需要注意and 和 or的關(guān)系

2、ExampleMatcher語法暴露常用方法

2.1 忽略大小寫

// 哪些屬性的paths忽略大小寫,可以指定多個(gè)參數(shù)
ExampleMatcher withIgnoreCase(String... propertyPaths);
// 提供一個(gè)默認(rèn)的實(shí)現(xiàn)方法,忽略大小寫
default ExampleMatcher withIgnoreCase() {
   return withIgnoreCase(true);
}
// 默認(rèn)忽略大小寫的方式,默認(rèn)false
ExampleMatcher withIgnoreCase(boolean defaultIgnoreCase);

2.2 NULL值的Property的處理方式

暴露的Null值處理方式如下所示:

ExampleMatcher withNullHandler(NullHandler nullHandler);

NullHandler枚舉值如下所示:INCLUDE(包括)、IGNORE(忽略),

enum NullHandler {
   INCLUDE, IGNORE
}

需要注意的是: 標(biāo)識(shí)作為條件的實(shí)體對(duì)象中,一個(gè)屬性值(條件值)為NULL時(shí),是否參與過濾;
當(dāng)該選項(xiàng)值是INCLUDE時(shí),標(biāo)識(shí)仍參與過濾,會(huì)匹配數(shù)據(jù)庫表中該字段值是NULL的記錄;

若為IGNORE值,表示不參與過濾;

// 把(實(shí)體類中)NULL屬性值作為查詢條件
default ExampleMatcher withIncludeNullValues() {
   return withNullHandler(NullHandler.INCLUDE);
}
// 提供一個(gè)默認(rèn)實(shí)現(xiàn)方法,忽略(實(shí)體類中)NULL屬性
default ExampleMatcher withIgnoreNullValues() {
   return withNullHandler(NullHandler.IGNORE);
}

我們來看一下,把(實(shí)體類中)NULL屬性值作為查詢條件使用,執(zhí)行的SQL如下所示:

Hibernate: select count(useraddres0_.id) as col_0_0_ from user_address useraddres0_ inner join user user1_ on useraddres0_.user_id=user1_.id where useraddres0_.id is null or useraddres0_.address like ? escape ? or user1_.name=? or user1_.email like ? escape ? or user1_.id is null or user1_.age=20 

2.3 忽略某些屬性列表,不參與查詢過濾條件

// 忽略某些屬性(可以是多個(gè)),不參與查詢過濾條件
ExampleMatcher withIgnorePaths(String... ignoredPaths);

2.4 字符串默認(rèn)的匹配規(guī)則

ExampleMatcher withStringMatcher(StringMatcher defaultStringMatcher);

默認(rèn)字符串的匹配方式有以下幾種 ,如下所示:

enum StringMatcher {
   DEFAULT,
   EXACT,
   STARTING,
   ENDING,
   CONTAINING,
   REGEX;
}

DEFAULT:默認(rèn),作用和EXACT一樣
EXACT:相等
STARTING:開始匹配
ENDING:結(jié)束匹配
CONTAINING:包含、模糊匹配
REGEX:正則表達(dá)式

使用方法如下

withStringMatcher(ExampleMatcher.StringMatcher.ENDING)

或指定某些字符串屬性匹配規(guī)則

ExampleMatcher withMatcher(String propertyPath, GenericPropertyMatcher genericPropertyMatcher);

3、實(shí)踐出真理

就從上面介紹的方法,我們手動(dòng)練習(xí)一下。

新建一張Dog表

@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_dog")
public class Dog {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(columnDefinition = "int(11) NOT NULL COMMENT '主鍵' ")
    private Integer id;
    @Column(columnDefinition = "varchar(30) DEFAULT '' COMMENT '寵物名'")
    private String name;
    @Column(columnDefinition = "int(11) DEFAULT NULL COMMENT '年齡'")
    private Integer age;
}

3.1 AND查詢

解釋:根據(jù)當(dāng)前dog對(duì)象的屬性值作為查詢條件去查詢

@Test
public void testBy01(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .build();
    // AND 查詢
    ExampleMatcher matcher = ExampleMatcher.matching(); //ExampleMatcher.matchingAll()  也可以
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

Hibernate: select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_ from tb_dog dog0_ where dog0_.name=? and dog0_.age=2

3.2 OR 查詢

解釋:根據(jù)當(dāng)前dog對(duì)象的屬性值作為查詢條件去查詢

@Test
public void testBy02(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .build();
    // OR 查詢
    ExampleMatcher matcher = ExampleMatcher.matchingAny(); 
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_ from tb_dog dog0_ where dog0_.name=? or dog0_.age=2

3.3 忽略大小寫查詢

解釋:指定"name"屬性忽略大小寫

@Test
public void testBy03(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .build();
    ExampleMatcher matcher = ExampleMatcher.matching()
            .withIgnoreCase("name");
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_ from tb_dog dog0_ where lower(dog0_.name)=? and dog0_.age=2

在Dog表中添加type字段

@Column(columnDefinition = "varchar(20) DEFAULT NULL COMMENT '種類'")
private String type;

3.3.1 忽略大小寫 不指定屬性

解釋:不指定屬性,默認(rèn)為所有查詢字符串條件加上忽略大小寫條件

@Test
public void testBy04(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .type("L")
            .build();
    ExampleMatcher matcher = ExampleMatcher.matching()
            .withIgnoreCase();
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_, dog0_.type as type4_3_ from tb_dog dog0_ where lower(dog0_.name)=? and lower(dog0_.type)=? and dog0_.age=2

3.4 NULL值的處理

3.4.1 NULL屬性值作為查詢條件

解釋:把(實(shí)體類中)NULL屬性值作為查詢條件使用

@Test
public void testBy05(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .type("L")
            .build();
    ExampleMatcher matcher = ExampleMatcher.matching()
            .withIgnoreCase()
                    .withIncludeNullValues();
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_, dog0_.type as type4_3_ from tb_dog dog0_ where lower(dog0_.type)=? and (dog0_.id is null) and dog0_.age=2 and lower(dog0_.name)=?

3.4.2 忽略(實(shí)體類中)NULL屬性

解釋:把(實(shí)體類中)NULL屬性值忽略

@Test
public void testBy06(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .type("L")
            .build();
    ExampleMatcher matcher = ExampleMatcher.matching()
            .withIgnoreNullValues();
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_, dog0_.type as type4_3_ from tb_dog dog0_ where dog0_.name=? and dog0_.type=? and dog0_.age=2

3.5 忽略某些屬性不做篩選

解釋:把(實(shí)體類中)某些屬性忽略掉,不做篩選

@Test
public void testBy07(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .type("L")
            .build();
    // 忽略掉"name" 和 "type"兩個(gè)屬性
    ExampleMatcher matcher = ExampleMatcher.matching()
            .withIgnorePaths("name","type");
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_, dog0_.type as type4_3_ from tb_dog dog0_ where dog0_.age=2

3.6 字符串匹配規(guī)則

3.6.1 DEFAULT和EXACT 相等

解釋:把(實(shí)體類中)所有字符串屬性匹配規(guī)則設(shè)置為 EXACT (相等)

@Test
public void testBy08(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .type("L")
            .build();
    ExampleMatcher matcher = ExampleMatcher.matching()
                     // 字符串屬性提供的匹配規(guī)則 EXACT相等
                    .withStringMatcher( ExampleMatcher.StringMatcher.EXACT);
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_, dog0_.type as type4_3_ from tb_dog dog0_ where dog0_.name=? and dog0_.age=2 and dog0_.type=?

3.6.2 STARTING和ENDING 模糊查詢【開始匹配(?1 + %) 和 結(jié)束匹配(% + ?1 )) 】

解釋:把(實(shí)體類中)所有字符串屬性匹配規(guī)則設(shè)置為 STARTING/ENDING (模糊查詢)

public void testBy09(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .type("L")
            .build();
    ExampleMatcher matcher = ExampleMatcher.matching()
                     // 設(shè)置為開始匹配
                    .withStringMatcher(ExampleMatcher.StringMatcher.STARTING);
                     // 設(shè)置為結(jié)束匹配
                  //.withStringMatcher(ExampleMatcher.StringMatcher.ENDING);
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_, dog0_.type as type4_3_ from tb_dog dog0_ where dog0_.age=2 and (dog0_.type like ? escape ?) and (dog0_.name like ? escape ?)

3.6.3 Containing 包含模糊匹配【% + ?1 + %】

解釋:把(實(shí)體類中)所有字符串屬性匹配規(guī)則設(shè)置為 Containing (包含模糊查詢)

@Test
public void testBy11(){
    Dog dog = Dog.builder()
            .name("TIMI")
            .age(2)
            .type("L")
            .build();
    ExampleMatcher matcher = ExampleMatcher.matching()
             // 包含模糊查詢
            .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);
    System.out.println(dogRepo.findAll(Example.of(dog, matcher)));
}

執(zhí)行SQL結(jié)果如下所示:

select dog0_.id as id1_3_, dog0_.age as age2_3_, dog0_.name as name3_3_, dog0_.type as type4_3_ from tb_dog dog0_ where dog0_.age=2 and (dog0_.type like ? escape ?) and (dog0_.name like ? escape ?)

以上就是Spring Data JPA系列QueryByExampleExecutor使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring Data JPA QueryByExampleExecutor的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java繼承概念詳細(xì)解讀

    Java繼承概念詳細(xì)解讀

    這篇文章主要介紹了Java繼承概念詳細(xì)解讀,涉及繼承的概念,合成的語法等相關(guān)內(nèi)容,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java中IdentityHashMap與HashMap區(qū)別詳解

    Java中IdentityHashMap與HashMap區(qū)別詳解

    這篇文章主要介紹了Java中IdentityHashMap與HashMap區(qū)別詳解,很多人不曉得IdentityHashMap的存在,其中不乏工作很多年的Java開發(fā)者,他們看到就說是第三方j(luò)ar包,實(shí)際上它是Jdk源碼自帶的集合類,需要的朋友可以參考下
    2023-11-11
  • 詳解如何使用MongoDB+Springboot實(shí)現(xiàn)分布式ID的方法

    詳解如何使用MongoDB+Springboot實(shí)現(xiàn)分布式ID的方法

    這篇文章主要介紹了詳解如何使用MongoDB+Springboot實(shí)現(xiàn)分布式ID的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java程序啟動(dòng)時(shí)初始化數(shù)據(jù)的四種方式

    Java程序啟動(dòng)時(shí)初始化數(shù)據(jù)的四種方式

    本文主要介紹了Java程序啟動(dòng)時(shí)初始化數(shù)據(jù)的四種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • Java稀疏數(shù)組詳細(xì)圖文教程

    Java稀疏數(shù)組詳細(xì)圖文教程

    當(dāng)一個(gè)數(shù)組中的大部分元素為相同的值,可使用稀疏數(shù)組來保存該數(shù)組,可以將稀疏數(shù)組看做是普通數(shù)組的壓縮,這篇文章主要給大家介紹了關(guān)于Java稀疏數(shù)組的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • Java第三方庫JodaTime的具體使用

    Java第三方庫JodaTime的具體使用

    本文主要介紹了Java第三方庫JodaTime的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 關(guān)于Spring AOP使用時(shí)的一些問題匯總

    關(guān)于Spring AOP使用時(shí)的一些問題匯總

    這篇文章主要給大家匯總介紹了關(guān)于Spring AOP使用時(shí)的一些問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • 淺談Java編程中的內(nèi)存泄露情況

    淺談Java編程中的內(nèi)存泄露情況

    這篇文章主要介紹了Java編程中的內(nèi)存泄露情況,牽扯到JVM的垃圾回收相關(guān)知識(shí),需要的朋友可以參考下
    2015-10-10
  • java中TestNG使用教程詳解

    java中TestNG使用教程詳解

    TestNG是Java中的一個(gè)測試框架, 類似于JUnit 和NUnit, 本文主要介紹了java中TestNG使用教程詳解,具有一定的參考價(jià)值,感興趣的可以了解一下
    2021-12-12
  • SpringBoot如何使用過濾器進(jìn)行XSS防御

    SpringBoot如何使用過濾器進(jìn)行XSS防御

    想對(duì)全局的請(qǐng)求都進(jìn)行XSS防御可以使用servlet中的過濾器或者spring mvc中的攔截器,下面我們就來看看如何使用servlet中的過濾器進(jìn)行XSS防御吧
    2024-11-11

最新評(píng)論

电白县| 九台市| 清远市| 皋兰县| 亳州市| 雅安市| 上犹县| 商丘市| 西华县| 西华县| 乌兰县| 来安县| 新平| 长白| 桂平市| 齐河县| 轮台县| 启东市| 九龙县| 乐陵市| 义马市| 共和县| 屯门区| 鲁甸县| 连城县| 福泉市| 金昌市| 丹寨县| 徐水县| 青浦区| 安福县| 桐城市| 宜阳县| 利辛县| 昌吉市| 舟山市| 朝阳县| 赫章县| 正阳县| 侯马市| 弋阳县|