Mybatis-Plus: カスタム SQL の実装

目次

1 はじめに

2. SQL の特定の実装をカスタマイズする

2.1. SQLに注釈を付ける

2.2. ラッパーパラメータの受け渡し + アノテーション SQL

2.3. ラッパーパスパラメータ+XMLファイルSQL

2.4. 通常のパラメータ渡し + XMLファイルSQL

3. まとめ


1 はじめに

        Mybatis-Plus (以下、MBP) の本来の目的は開発を簡素化することであり、開発者が自分で SQL ステートメントを記述することは推奨されませんが、顧客のニーズがより複雑で、要求された条件を達成することが困難な場合があります。 MBP が提供する Service、Mapper、および Wrapper の組み合わせを使用するだけで要件を満たします。; 次に、カスタム SQL を使用します。

        Java 開発では、mybatis-plus を使用して SQL 操作を実行します。mybatis-plus は一般的に使用される多くのインターフェイスをカプセル化するため、mybatis に比べて時間と労力を節約できることがよくあります。ただし、より複雑なクエリの場合、mybatis-plus は比較すると見劣りするため、SQL ステートメントをカスタマイズする必要があります。この記事では、mybatis-plus/mybatisを利用する際のSQL文や動的SQLなどのカスタマイズ方法を紹介します。

Mybatis-Plus がカスタマイズを実装するには、いくつかの方法があります。

1) SQLに注釈を付ける

2) ラッパーパスパラメータ+アノテーションSQL

        制限事項: 複数テーブルの関連付けクエリには適していません。クエリ フィールドとコードが多すぎると乱雑になります。

3) ラッパーパラメーターの受け渡し + XML ファイル SQL:推奨

4) オブジェクトパラメータの受け渡し + XMLファイルSQL

        最も伝統的な書き方ですが、単純な単一テーブルのクエリではプロセスが煩雑で、設定も面倒です

2. SQL の特定の実装をカスタマイズする

2.1. SQLに注釈を付ける

Mybatis-plusでは、アノテーションによるSQL記述を実現するSQLアノテーション機能を提供していますが、SQLにアノテーションを付与するには、Mybatisの設定ファイルでアノテーション機能を有効にすることが前提となります。

Mapper の継承クラスで完全なカスタム SQL を使用できます。

//多数据源情况下,@DS注解用于指定数据源
@DS("zw-mysqldb")
public interface CarMapper extends BaseMapper<Car> {
 
    @Select("select * from car where car_seq = #{carSeq}")
    Car queryCar(String carSeq);

}
   @RequestMapping("/ok")
    public void testCustomSQL2() {
 
        Car car = carMapper.queryCar("11");
        System.out.println(car.toString());
    }

補充: 

1)使用@Param注解

当以下面的方式进行写SQL语句时:

    @Select("select column from table where userid = #{userid} ")
    public int selectColumn(int userid);

当你使用了使用@Param注解来声明参数时,如果使用 #{} 或 ${} 的方式都可以。

    @Select("select column from table where userid = ${userid} ")
    public int selectColumn(@Param("userid") int userid);


当你不使用@Param注解来声明参数时,必须使用使用 #{}方式。如果使用 ${} 的方式,会报错。

    @Select("select column from table where userid = ${userid} ")
    public int selectColumn(@Param("userid") int userid);
 

2)不使用@Param注解

不使用@Param注解时,参数只能有一个,并且是Javabean。在SQL语句里可以引用JavaBean的属性,而且只能引用JavaBean的属性。

    // 这里id是user的属性

    @Select("SELECT * from Table where id = ${id}")
    Enchashment selectUserById(User user);

上記のコードでは、SQL アノテーションを付ける方法が使用されており、SQL ステートメントは @Select アノテーションによって指定されています。@Param アノテーションを使用してメソッド内でパラメータ名を指定すると、パラメータの転送が容易になります。パラメータ名は SQL パラメータ名と一致するため、省略できます。

SQL にアノテーションを付ける利点は、コードが簡潔で読みやすいことと、Wrapper や他のメソッドと組み合わせて複雑な SQL を構築できることです。

2.2. ラッパーパラメータの受け渡し + アノテーション SQL

Wrapper メソッドを使用するいくつかの使用シナリオ:

1) 動的クエリ: Wrapper を使用して、さまざまなクエリ条件に従って SQL ステートメントを動的に結合し、正確なクエリを実現します。

2) 複数テーブル結合クエリ:複数テーブル結合クエリの場合、Wrapper を使用して SQL ステートメントを簡単に結合し、複数テーブル結合クエリを実現します。

3) ページング クエリ:ページング クエリでは、Wrapper を使用すると SQL ステートメントを簡単に結合してページング機能を実現できます。

4) 条件付きクエリ: Wrapper を使用して、さまざまな条件に従って SQL ステートメントを動的に結合し、条件付きクエリを実現します。

5) ソートクエリ: Wrapper を使用して SQL ステートメントを簡単に結合し、ソート機能を実現します。

SQL を Wrapper と組み合わせて使用​​して複雑な SQL を構築する場合、通常は次の手順を完了する必要があります。

a) Wrapper オブジェクトを作成する

Wrapperオブジェクトを作成することで、SQLの構築や条件設定を便利に行うことができます。以下は、Wrapper オブジェクトを作成するためのサンプル コードです。

QueryWrapper<Entity> wrapper = new QueryWrapper<>(); 

b) クエリ条件を設定する

Wrapper オブジェクトのメソッド (eq、ne など) を使用してクエリ条件を設定でき、他のメソッドを使用して等しい、等しくないなどの条件を設定できます。クエリ条件を設定するサンプルコードは次のとおりです。

wrapper.eq("column1", value1)
       .ne("column2", value2)
       .like("column3", value3);

//示例
wrapper.eq("car_state", "1")
                .like("car_id", "渝A");

c) ソート条件の設定(必須ではありません)

Wrapper オブジェクトの orderBy メソッドを使用して、orderByAsc、orderByDesc などの並べ替え条件を設定できます。また、他のメソッドでは、昇順、降順、その他の条件を設定できます。以下はソート条件を設定するサンプルコードです。

wrapper.orderByAsc("car_id")

d) ページネーション条件の設定 (必須ではありません)

Wrapper オブジェクトのメソッドを使用して、ページネーションの条件を設定できます。たとえば、page メソッドでは、ページ番号や各ページのサイズなどの条件を設定できます。ページネーション条件を設定するサンプルコードは次のとおりです。

Page<Car> resultPage = new Page<>(1, 10);
carMapper.selectByPrimaryKey(resultPage,wrapper)

e) マッパーインターフェイス

@Select("select * from car ${ew.customSqlSegment}")
Page<Car> selectByPrimaryKey(Page<Car> page, @Param(Constants.WRAPPER) QueryWrapper<Car> queryWrapper);

f) SQL 操作の実行

インターフェイスのメソッドは、selectList、selectPage などの SQL 操作を実行し、その他のメソッドは SQL クエリ操作を実行でき、クエリをカスタマイズすることもできます。以下は、SQL 操作を実行するための完全なコードのサンプルです。

//分页查询方式1
QueryWrapper<Car> wrapper = new QueryWrapper<>();
Page<Car> resultPage = new Page<>(1, 10);

wrapper.eq("car_state", "1")
       .like("car_id", "渝A")
       .orderByAsc("car_id");//排序
carMapper.selectByPrimaryKey(resultPage,wrapper);


//分页查询方式2
IPage<Car> page = new Page<>(1, 10); // 分页查询
LambdaQueryWrapper<Car> qw = new LambdaQueryWrapper<Car>()
     .like(Car::getCarId, "渝A") // 车牌号 =
     .eq(Car::getCarState, 1); // 状态

//selectPage是BaseMapper自带方法
IPage<Car> userPage = carMapper.selectPage(page, qw);

知らせ:

1) QueryWrapper でカスタム uservo クラスを使用します。LambdaQueryWrapper は使用できません 

2) 上記の IPage と Page の両方をページングに使用できます。

XMLファイル

g) 実行結果:

補充:

実際のアプリケーションでは、LambdaQueryWrapper と QueryWrapper を使用して、さまざまなビジネス ニーズを満たすために、より複雑なクエリ操作を実装することもできます。たとえば、動的クエリには LambdaQueryWrapper と QueryWrapper を使用し、フロントエンドから渡されるパラメータを判断して SQL ステートメントを組み合わせることで、柔軟なクエリ操作を実現できます。 

public List<UserEntity> getUserList(String name, Integer age) {
    LambdaQueryWrapper<UserEntity> qw = new LambdaQueryWrapper<UserEntity>()
            .eq(StringUtils.isNotEmpty(name), UserEntity::getName, name) // 姓名 = name
            .gt(age != null, UserEntity::getAge, age); // 年龄 > age

    return userMapper.selectList(qw);
}

上記のコードでは、LambdaQueryWrapper を通じて動的クエリ操作を実装しました。渡された name パラメータが空でない場合は、等しいクエリ条件が追加され、渡された age パラメータが空でない場合は、より大きいクエリ条件が追加されます。

このようなクエリ操作では、フロントエンドから渡されたパラメータに従って SQL ステートメントを柔軟に組み合わせて、より多くのビジネス ニーズを実現できます。

知らせ:

        1)マッパー メソッドの @Param(Constants.WRAPPER) ラッパー クエリ オブジェクト。Constants.WRAPPER の値は新しいです。
        2)まず ew.emptyOfWhere に where 条件があるかどうかを判断し、存在する場合はそれを結合します。

        3) ew.customSqlSegment の値は WHERE + sql ステートメントであり、WHERE 文字列を含まない別の ew.sqlSegment があります。

        4) ${ew.customSqlSegment} は、Wapper クエリ条件を表すクエリ条件プレースホルダーです。 

もちろん、Mybatis-Plus は、selectObjs、selectByMap など、直接使用できるいくつかのカスタム SQL メソッドを提供します。次に例を示します。

List<Object> objs = userMapper.selectObjs(
    new QueryWrapper<User>().select("max(age)").eq("name", "张三")
);

2.3. ラッパーパスパラメータ+XMLファイルSQL

ラッパーパラメータの受け渡しはMybatisの高度な操作メソッドであり、クエリ時にパラメータを動的に渡すことができます。

1) マッパークラス

Car selectBySeq @Param(Constants.WRAPPER) QueryWrapper<Car> queryWrapper);

2) XML設定ファイル 

<select id="selectBySeq " resultMap="BaseResultMap">
        select * from `car` ${ew.customSqlSegment}
</select>

3) Wapper を介してクエリパラメータを渡す

Wrapper を使用してパラメータを動的に渡す

1. Wrapper 基本クラスを使用して、Where の背後にある SQL ステートメントをカスタマイズします。

2.QueryWrapperを使用する

  • 選択 | select(文字列...sqlSelect)

    例select("id", "name", "age")

上記 2 つの方法のいずれかを選択し、パラメータは Wrapper です。

    @RequestMapping("/ok")
    public void testCustomSQL2() {
        LambdaQueryWrapper<Car> query = new LambdaQueryWrapper<>();
        query.eq(Car::getCarId, "11");

        Car car= carMapper.queryCarSeq(query);

        System.out.println(car.toString());
    }

//或者
Wrapper wrapper = new QueryWrapper<Car>().eq("car_state", 1).like("cai_id", "渝");
List<Car> userList = carMapper.queryCarSeq(wrapper);

XML ファイル SQL と Wrapper パラメータを組み合わせる利点は、コードの保守性、可読性、セキュリティが向上することです。コード量が多く、複数人での共同開発が必要なシナリオに適しており、SQL の実行を防ぐことができます。注射攻撃。 

2.4. 通常のパラメータ渡し + XMLファイルSQL

リソース ディレクトリにマッパー フォルダーを作成し、UserMapper.xml などのマッパー インターフェイスと同じ名前の XML ファイルを作成して、カスタム SQL ステートメントを定義します。

 //xml文件式,myabtis原生方式   
 Car selectByAnnotationXML(String seq);

マッパーの下にファイル UserDao.xml を作成します 

 <select id="selectByAnnotationXML" parameterType="java.lang.String" resultMap="BaseResultMap">
        select *
        from car
        where car_seq = #{seq,jdbcType=VARCHAR}
    </select>

この方法は、mybatis に連絡するときの最も基本的な方法です。 

3. まとめ

        一般に、SQL を記述する方法は 2 つあり、1 つはアノテーションを使用してマッパー メソッドに直接記述する方法、もう 1 つは XML ファイルに記述する方法です。パラメータを渡す方法も 2 つあり、1 つはパラメータを直接渡す方法です。 XML ファイルで SQL をアセンブルします。1 つは、Wapper を介してパラメーター条件付きコンストラクターを渡すことです。

アノテーションの利点

        簡潔で理解しやすい: XML 構成と比較して、アノテーションの使用はより簡潔かつ直感的であり、コードがより読みやすく、保守しやすくなります。

        デバッグが簡単:アノテーション構成を Java クラスに直接記述することができるため、XML 内の SQL を検索して変更する時間を短縮できます。

        パフォーマンスの向上: 多数の CRUD 操作を実行する場合、XML 解析のオーバーヘッドがないため、アノテーション構成のパフォーマンスが向上します。

アノテーションのデメリット

        メンテナンスが困難: SQL と Java コードを結合すると、特により複雑な SQL が含まれる場合、コードのメンテナンスとリファクタリングが困難になります。

        SQL の可読性の低さ: XML で SQL を記述する場合と比較して、アノテーション内の SQL ステートメントは通常、より冗長で読みにくくなります。

XML の利点

        保守が容易: SQL が Java コードから分離されているため、特に SQL を変更する必要がある場合、コードの保守が容易になります。

        SQL の可読性の向上: SQL を XML で記述すると、SQL の形式がより明確になり、読みやすくなります。

        管理が簡単: XML 構成ファイルはグローバルに管理できるため、プロジェクトの構造がより明確になります。

XML の欠点

        複雑:注釈と比較して、XML 構成はより複雑で、より多くのコードが必要になります。

        パフォーマンスの問題:多数の操作を実行すると、XML の解析と読み取りに一定の時間がかかり、システムのパフォーマンスが低下します

つまり、アノテーションと XML の選択は、プロジェクトの実際の状況とニーズに応じて決定する必要があります。単純なクエリと操作にはアノテーションが適しており、複雑なクエリと操作には XML が適しています。

一般的な方法は公式ドキュメントを参照

おすすめ

転載: blog.csdn.net/qq_20957669/article/details/130396077