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

MyBatis-plus字段類型處理器、自動填充和樂觀鎖詳解

 更新時間:2026年03月13日 08:44:37   作者:NE_STOP  
文章主要內(nèi)容涵蓋了MyBatis-plus的邏輯刪除、枚舉使用、字段類型處理器、自動填充、防止全表更新與刪除插件、MyBatisX插件的使用、樂觀鎖實(shí)現(xiàn)、代碼生成器等技術(shù)點(diǎn)的介紹和配置方法,感興趣的朋友跟隨小編一起看看吧

MyBatis-plus拓展

邏輯刪除

邏輯刪除就是增加一個字段表示這個數(shù)據(jù)的狀態(tài),通過狀態(tài)來顯示數(shù)據(jù)或隱藏?cái)?shù)據(jù),而不是真正的刪除。

MyBatis-plus使用@TableLogic注解來標(biāo)注邏輯刪除字段:

public class User extends Model<User> {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;
    // 配置當(dāng)前字段為邏輯刪除字段
    // 默認(rèn)值是1,刪除狀態(tài)的值是0
    @TableLogic(value = "1",delval = "0")
    private Integer status;
}

此時如果調(diào)用Mapper的刪除方法,實(shí)際對應(yīng)的sql語句是更新操作。將邏輯刪除字段的值更新為0,而不是真正的刪除。

而且此時Mapper的查詢方法,不會查出這條數(shù)據(jù)。生成的sql語句會自動拼接where條件:status = 1

邏輯刪除也可以在配置文件中進(jìn)行全局配置:

mybatis-plus:
  global-config:
    banner: false
    db-config:
      id-type: assign_id
      # 邏輯刪除字段為status
      logic-delete-field: status
      # 刪除狀態(tài)的值
      logic-delete-value: 0
      # 未刪除狀態(tài)的值
      logic-not-delete-value: 1

使用全局配置后就不用使用@TableLogic注解了。

通用枚舉

假如要表示性別:只有男和女兩個值,我們就可以使用枚舉來描述。

數(shù)據(jù)庫表中使用gender (int 類型)表示性別,0表示女性,1表示男性。

使用@EnumValue來標(biāo)注將哪個變量的值插入到數(shù)據(jù)庫。

先創(chuàng)建枚舉類

public enum GenderEnum {
    MAN(1,"男"),WOMAN(0,"女");
    @EnumValue // 表示將這個變量的值插入到數(shù)據(jù)庫
    private Integer gender;
    private String genderName;
    GenderEnum(Integer gender, String genderName) {
        this.gender = gender;
        this.genderName = genderName;
    }
}

給Pojo類添加枚舉屬性

public class User extends Model<User> {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;
    // 配置當(dāng)前字段為邏輯刪除字段
    // 默認(rèn)值是1,刪除狀態(tài)的值是0
    @TableLogic(value = "1",delval = "0")
    private Integer status;
    private GenderEnum gender;
}

調(diào)用正常的插入方法即可實(shí)現(xiàn)。

字段類型處理器

某些場景下,實(shí)體類中使用map集合作為屬性接收前端傳來的數(shù)據(jù),但是把這些輸出存到數(shù)據(jù)庫時,使用json格式的字符串存儲。那怎么把map類型轉(zhuǎn)換成字符串類型呢?這里就需要使用字段類型處理器。

需要@TableName注解和@TableField注解配合使用。

實(shí)體類代碼如下:

// autoResultMap = true 表示查詢時,自動將contact字段json格式的字符串轉(zhuǎn)換為Map類型
@TableName(autoResultMap = true)
public class User extends Model<User> {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;
    // 配置當(dāng)前字段為邏輯刪除字段
    // 默認(rèn)值是1,刪除狀態(tài)的值是0
    @TableLogic(value = "1",delval = "0")
    private Integer status;
    private GenderEnum gender;
    // 指定類型處理器,在新增或更新時,自動將Map類型轉(zhuǎn)換成json格式的字符串
    // 這個處理器依賴于Fastjson,所以要在pom文件中引入Fastjson依賴
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private Map<String, String> contact; // 聯(lián)系方式
}

自動填充

在實(shí)際應(yīng)用中,有一些屬性,其實(shí)不需要我們每次都手動填充,可以設(shè)置為自動填充,比如創(chuàng)建時間、更新時間等可以設(shè)置為自動填充。

注意時區(qū)的設(shè)置:

  1. mysql數(shù)據(jù)庫設(shè)置時區(qū):set global time_zone = '+8:00'

查看時區(qū)對不對?執(zhí)行select now() 看時間能不能對上。

  1. 項(xiàng)目中的時區(qū)設(shè)置:在數(shù)據(jù)庫連接Url中設(shè)置。
url: jdbc:mysql://localhost:3306/spring6?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&useUnicode=true

把serverTimezone=UTC改為serverTimezone=Asia/Shanghai。

  1. 使用@TableField注解設(shè)置填充時機(jī)
// autoResultMap = true 表示查詢時,自動將contact字段json格式的字符串轉(zhuǎn)換為Map類型
@TableName(autoResultMap = true)
public class User extends Model<User> {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;
    // 配置當(dāng)前字段為邏輯刪除字段
    // 默認(rèn)值是1,刪除狀態(tài)的值是0
    @TableLogic(value = "1",delval = "0")
    private Integer status;
    private GenderEnum gender;
    // 指定類型處理器,在新增或更新時,自動將Map類型轉(zhuǎn)換成json格式的字符串
    // 這個處理器依賴于Fastjson,所以要在pom文件中引入Fastjson依賴
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private Map<String, String> contact; // 聯(lián)系方式
    // 指定插入時填充
    @TableField(fill = FieldFill.INSERT)
    private Data creatTime;
    // 指定插入或更新時填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Data modifyTime;
}

編寫自定義處理器設(shè)置填充策略

//自定義Handler,設(shè)置填充策略,這里需要實(shí)現(xiàn)MetaObjectHandler接口
@Component
public class MyMetaHandler implements MetaObjectHandler {
    // 插入時的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        setFieldValByName("creatTime",new Date(),metaObject);
        setFieldValByName("modifyTime",new Date(),metaObject);
    }
    // 更新時的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        setFieldValByName("modifyTime",new Date(),metaObject);
    }
}

此時在新增或更新時,無需手動設(shè)置創(chuàng)建時間更新時間,系統(tǒng)會自動填充時間到數(shù)據(jù)庫表中。

防止全表更新與刪除插件

配置攔截規(guī)則:插件默認(rèn)攔截沒有指定條件的 updatedelete 語句。

當(dāng)觸發(fā)攔截時,會拋出MyBatisPlusException異常。

通過在MybatisPlusConfig 這個配置類中加入對應(yīng)的攔截器來阻止全表更新與刪除:

@Configuration
@MapperScan("com.ali.mapper")
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 防止全表更新與刪除插件
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多個插件, 切記分頁最后添加
        // 如果有多數(shù)據(jù)源可以不配具體類型, 否則都建議配上具體的 DbType
        return interceptor;
    }
}

MyBatisX快速開發(fā)插件

MyBatisX是一款idea提供的插件,目的是為了簡化MyBatis和MyBatis-plus框架。

  • MyBatisX先安裝插件:
  • File -- > Settings -->Plugins -- >搜索 MyBatisX,然后安裝
  • MyBatisX插件的快速定位:
  • 這個插件把Mapper接口的方法和映射文件的sql進(jìn)行了一一對應(yīng)??梢詮腗apper接口方法快速跳到對應(yīng)的映射文件對應(yīng)的sql。

同樣,也可以在映射文件點(diǎn)擊小鳥快速跳轉(zhuǎn)到對應(yīng)的Mapper接口

  • MyBatisX插件的逆向工程:
  • 通過數(shù)據(jù)庫表,快速生成以下項(xiàng)目文件:
  • 實(shí)體類
    • Mapper接口
    • Mapper映射文件
    • Service接口
    • Service實(shí)現(xiàn)類
  • 首先使用idea連接數(shù)據(jù)庫:

 2. 選擇對應(yīng)的數(shù)據(jù)庫表,然后右鍵選擇MyBatisX-generate

  1. 最后一步設(shè)置

這樣就生成了對應(yīng)的項(xiàng)目文件。注意這里的Mapper接口文件要手動加上@Mapper注解。

樂觀鎖

并發(fā)請求就是在同一時刻有多個請求去請求同一個服務(wù)器資源。如果是獲取信息,不會出現(xiàn)問題,但是如果做修改操作,就會出現(xiàn)并發(fā)問題。

比如:三個人去買同樣的商品,商品剩余一件。購買時一般先查詢庫存再購買后數(shù)量減一,并發(fā)請求就是同一時刻,三個人都查到了商品剩余1個,然后同時進(jìn)行購買。這樣只能一個人買到,另外兩人肯定買不到,此時就發(fā)生了超賣行為。這就是經(jīng)典的并發(fā)問題。

常見的數(shù)據(jù)庫鎖類型有兩種,悲觀鎖和樂觀鎖:

悲觀鎖:查詢時就鎖定數(shù)據(jù),在請求完成之前不會釋放鎖。完成后才釋放鎖。釋放鎖以后,其他請求才可以對數(shù)據(jù)進(jìn)行讀寫。

這樣雖解決了并發(fā)問題,但是效率較低。實(shí)際開發(fā)中很少使用悲觀鎖。

樂觀鎖:通過表字段完成設(shè)計(jì)。樂觀鎖的核心思想是:在讀取的時候不加鎖,其他請求仍可以讀取這個數(shù)據(jù),在修改的時候,判斷一個數(shù)據(jù)是否有被修改過,如果修改過,那本次請求的修改操作失效。

具體設(shè)計(jì)如下:

增加一個字段version。購買商品時先查詢,此時能獲取到version的值。

在執(zhí)行購買操作時,更新庫存數(shù)量前再查詢一次version的值,如果兩次的version值一樣,表示可以進(jìn)行更新庫存操作,更新時進(jìn)行 version = version +1,表示我執(zhí)行了一次。這樣就完成了樂觀鎖的操作。

如果兩次的version 值不一致,說明有人對庫存數(shù)據(jù)進(jìn)行了更新,此時不能直接進(jìn)行購買。需要重新進(jìn)行先查詢后購買的操作。

MyBatis-plus中樂觀鎖實(shí)現(xiàn)步驟如下:

在實(shí)體類中使用@Version注解指定版本字段

// autoResultMap = true 表示查詢時,自動將contact字段json格式的字符串轉(zhuǎn)換為Map類型
@TableName(autoResultMap = true)
public class User extends Model<User> {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;
    // 配置當(dāng)前字段為邏輯刪除字段
    // 默認(rèn)值是1,刪除狀態(tài)的值是0
    @TableLogic(value = "1",delval = "0")
    private Integer status;
    private GenderEnum gender;
    // 指定類型處理器,在新增或更新時,自動將Map類型轉(zhuǎn)換成json格式的字符串
    // 這個處理器依賴于Fastjson,所以要在pom文件中引入Fastjson依賴
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private Map<String, String> contact; // 聯(lián)系方式
    // 指定插入時填充
    @TableField(fill = FieldFill.INSERT)
    private Data creatTime;
    // 指定插入或更新時填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Data modifyTime;
    @Version // 表示將此字段作為版本信息
    private Integer version;// 版本
}

在MybatisPlusConfig配置類中加入樂觀鎖攔截器

@Configuration
@MapperScan("com.ali.mapper")
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 樂觀鎖攔截器
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        // 防止全表更新與刪除插件
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多個插件, 切記分頁最后添加
        // 如果有多數(shù)據(jù)源可以不配具體類型, 否則都建議配上具體的 DbType
        return interceptor;
    }
}

測試代碼:

// 第一次查詢:執(zhí)行成功   version是1
User user1 = userService.getById(1L);
// 第二次查詢:執(zhí)行成功   version是1
User user5 = userService.getById(1L);
user1.setAge(12);
// 第一次更新:執(zhí)行成功,因?yàn)樵俅潍@取到version還是1,和上次保持一致。
// 更新后 version +1 此時version是2
userService.updateById(user1);
user5.setAge(22);
// 第二次更新:執(zhí)行失敗,因?yàn)樵俅潍@取到version的值是2,和上次獲取的值不一樣,不執(zhí)行更新操作。
userService.updateById(user5);

代碼生成器

代碼生成器和逆向功能的區(qū)別在于,代碼生成器可以生成更多的結(jié)構(gòu),更多的內(nèi)容,允許配置更多的內(nèi)容。

具體步驟如下:

引入相關(guān)依賴

<!--代碼生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!--freemarker 模板依賴-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>

編寫生成類(可以在mybatis-plus官網(wǎng)直接copy):

public class CodeGeneratorTest {
    public static void main(String[] args) {
        // 使用 FastAutoGenerator 快速配置代碼生成器
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8", "root", "password")
                .globalConfig(builder -> {
                    builder.author("Your Name") // 設(shè)置作者
                            .outputDir("src/main/java"); // 輸出目錄
                })
                .packageConfig(builder -> {
                    builder.parent("com.example") // 設(shè)置父包名
                            .entity("model") // 設(shè)置實(shí)體類包名
                            .mapper("dao") // 設(shè)置 Mapper 接口包名
                            .service("service") // 設(shè)置 Service 接口包名
                            .serviceImpl("service.impl") // 設(shè)置 Service 實(shí)現(xiàn)類包名
                            .xml("mappers"); // 設(shè)置 Mapper XML 文件包名
                })
                .strategyConfig(builder -> {
                    builder.addInclude("table1", "table2") // 設(shè)置需要生成的表名
                            .entityBuilder()
                            .enableLombok() // 啟用 Lombok
                            .enableTableFieldAnnotation() // 啟用字段注解
                            .controllerBuilder()
                            .enableRestStyle(); // 啟用 REST 風(fēng)格
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用 Freemarker 模板引擎
                .execute(); // 執(zhí)行生成
    }
}

執(zhí)行sql打印分析

通過sql分析來獲取sql語句的執(zhí)行時間。

具體步驟如下:

由于該功能依賴于p6spy組件,p6spy是一個強(qiáng)大的工具,它為MyBatis-Plus用戶提供了便捷的SQL分析與打印功能。通過合理配置,你可以在開發(fā)和測試階段有效地監(jiān)控和優(yōu)化SQL語句。然而,由于性能損耗,建議在生產(chǎn)環(huán)境中謹(jǐn)慎使用。所以先引入依賴:

<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.9.1</version>
</dependency>

在application.yml中修改配置

spring:
  datasource:
    username: root
    password: root
    url: jdbc:p6spy:mysql://localhost:3306/spring6?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&useUnicode=true
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver

在resource下,創(chuàng)建spy.properties配置文件

# 模塊列表,根據(jù)版本選擇合適的配置
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定義日志格式
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
# 日志輸出到控制臺
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 取消JDBC驅(qū)動注冊
deregisterdrivers=true
# 使用前綴
useprefix=true
# 排除的日志類別
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 實(shí)際驅(qū)動列表
# driverlist=org.h2.Driver
# 開啟慢SQL記錄
outagedetection=true
# 慢SQL記錄標(biāo)準(zhǔn)(單位:秒)
outagedetectioninterval=2
# 過濾 flw_ 開頭的表 SQL 打印
filter=true
exclude=flw_*

多數(shù)據(jù)源

先引入依賴

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>

dynamic-datasource 是一個開源的 Spring Boot 多數(shù)據(jù)源啟動器,提供了豐富的功能,包括數(shù)據(jù)源分組、敏感信息加密、獨(dú)立初始化表結(jié)構(gòu)等

配置數(shù)據(jù)源

spring:
  datasource:
    dynamic:
    # 默認(rèn)數(shù)據(jù)源名為 master,可通過 spring.datasource.dynamic.primary 修改。
      primary: master
      strict: false
      datasource:
        master:
          url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_1:
          url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: ENC(xxxxx)
          username: ENC(xxxxx)
          password: ENC(xxxxx)
          driver-class-name: com.mysql.jdbc.Driver

使用 @DS 切換數(shù)據(jù)源:

@Service
@DS("master")
public class UserServiceImpl implements UserService {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    @DS("slave_1")
    public List selectByCondition() {
        return jdbcTemplate.queryForList("select * from user where age >10");
    }
}

到此這篇關(guān)于MyBatis-plus字段類型處理器、自動填充和樂觀鎖詳解的文章就介紹到這了,更多相關(guān)MyBatis-plus字段類型處理器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaWeb文件上傳下載功能示例解析

    JavaWeb文件上傳下載功能示例解析

    這篇文章主要介紹了JavaWeb中的文件上傳和下載功能的實(shí)現(xiàn),文件上傳和下載功能是非常常用的功能,需要的朋友可以參考下
    2016-06-06
  • Java進(jìn)階教程之String類

    Java進(jìn)階教程之String類

    這篇文章主要介紹了Java進(jìn)階教程之String類,String類對象是不可變對象(immutable object),String類是唯一一個不需要new關(guān)鍵字來創(chuàng)建對象的類,需要的朋友可以參考下
    2014-09-09
  • 將Java(SpringBoot)項(xiàng)目打包為Docker鏡像的三種方法

    將Java(SpringBoot)項(xiàng)目打包為Docker鏡像的三種方法

    這篇文章主要介紹了將Java(SpringBoot)項(xiàng)目打包為Docker鏡像的三種方法,分別是手動構(gòu)建、使用Dockerfile和使用SpringBootMaven插件,每種方法都有其特點(diǎn)和適用場景,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-03-03
  • 詳解lambda表達(dá)式foreach性能分析

    詳解lambda表達(dá)式foreach性能分析

    這篇文章主要介紹了詳解lambda表達(dá)式foreach性能分析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Spring?Boot集成Redisson實(shí)現(xiàn)延遲隊(duì)列

    Spring?Boot集成Redisson實(shí)現(xiàn)延遲隊(duì)列

    本文詳細(xì)介紹了電商支付場景中利用Redisson的RDelayedQueue實(shí)現(xiàn)訂單的延遲關(guān)閉功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-08-08
  • Java寫出生肖年判斷

    Java寫出生肖年判斷

    本篇文章主要給大家分享一篇關(guān)于用JAVA寫出生肖判斷的小功能,有興趣的跟著學(xué)習(xí)下。
    2018-02-02
  • Springboot mybatisplus如何解決分頁組件IPage失效問題

    Springboot mybatisplus如何解決分頁組件IPage失效問題

    這篇文章主要介紹了Springboot mybatisplus如何解決分頁組件IPage失效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java實(shí)現(xiàn)撲克牌洗牌和發(fā)牌

    Java實(shí)現(xiàn)撲克牌洗牌和發(fā)牌

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)撲克牌洗牌和發(fā)牌,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式

    SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式

    這篇文章主要介紹了SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式,分別就轉(zhuǎn)發(fā)和重定向做了概念解說,結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-11-11
  • Spring Task定時任務(wù)的完整使用教學(xué)

    Spring Task定時任務(wù)的完整使用教學(xué)

    Spring Task是Spring框架提供的輕量級定時任務(wù)工具,它無需依賴額外的第三方庫,直接集成在Spring核心包中,在SpringBoot中,Spring Task提供了自動配置支持,只需少量注解即可快速實(shí)現(xiàn)定時任務(wù)功能,本文給大家介紹了Spring Task定時任務(wù)的完整使用教學(xué)
    2026-06-06

最新評論

镇远县| 富民县| 安丘市| 吐鲁番市| 盱眙县| 林芝县| 儋州市| 鄂温| 华容县| 略阳县| 福建省| 高陵县| 沙河市| 黄龙县| 四子王旗| 宁陕县| 松滋市| 大城县| 台南市| 道真| 渝北区| 安福县| 德庆县| 勃利县| 梅州市| 金寨县| 曲麻莱县| 余庆县| 岢岚县| 讷河市| 衡阳市| 富宁县| 昌邑市| 嘉黎县| 天镇县| 五大连池市| 富蕴县| 唐海县| 泾源县| 民乐县| 安康市|