よくある質問
本ドキュメントには、MyBatis-Plus を使用する際によくある問題をまとめています。MyBatis-Plus を使用していて問題が発生した場合は、まずこのドキュメントをご確認ください。
以下の3つの方法のいずれかを選択してください:
-
transient
修飾子を使用private transient String noColumn; -
static
修飾子を使用private static String noColumn; -
TableField
アノテーションを使用@TableField(exist=false)private String noColumn;
除外したい親クラスのプロパティに transient
修飾子を使用します
/** * 親クラスの createTime フィールドのマッピングを無視 */private transient String createTime;
この例外は通常、設定が正しくないか、Mapper が正しくスキャンされていないことが原因です。以下の解決方法を試してください:
-
jar パッケージの競合がないか確認します。
-
Mapper.java のスキャンパスを確認します:
-
方法1:
Configuration
クラスでMapperScan
アノテーションを使用@Configuration@MapperScan("com.yourpackage.*.mapper")public class YourConfigClass{...} -
方法2:
Configuration
クラスでMapperScannerConfigurer
を設定(サンプルを参照)@Beanpublic MapperScannerConfigurer mapperScannerConfigurer(){MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer();// 環境変数から mapper のパスを取得できます。これにより mapper のスキャンを設定ファイルで構成できますscannerConfigurer.setBasePackage("com.yourpackage.*.mapper");return scannerConfigurer;}
-
-
检查是否指定了主键。如果未指定,将导致
selectById
相关 ID 无法操作。请使用注解@TableId
注解表 ID 主键。当然,@TableId
注解可以省略,但是你的主键必须叫 id(忽略大小写)。 -
不要使用原生的 SqlSessionFactory,请使用 MybatisSqlSessionFactory。
-
检查是否自定义了 SqlInjector,是否复写了
getMethodList()
方法。在该方法中是否注入了你需要的方法(可参考 DefaultSqlInjector)。 -
IDEA 默认的 build 步骤可能会导致 mapper 文件无法正常编译到对应的 resources 文件夹中。请检查 build 后相关资源文件夹是否有对应的 XML 文件。如果没有,请调整 IDEA 的 build 设置。推荐调整为 Maven 或 Gradle 的 build。
問題の説明:XML 内でカスタム SQL を定義しても呼び出せない場合。この機能は MyBatis
と同様に、XML スキャンパスの設定が必要です:
- Spring MVC の設定(mybatisplus-spring-mvc を参照)
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="typeAliasesPackage" value="xxx.entity" /> <property name="mapperLocations" value="classpath*:/mybatis/*/*.xml"/> ...</bean>
- Spring Boot の設定(mybatisplus-spring-boot を参照)
mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml
-
IDEA
シリーズのエディタでは、XML ファイルを java フォルダに配置することはできません。IDEA はデフォルトでソースコードフォルダ内の XML ファイルをコンパイルしません。以下の方法で解決できます:- 設定ファイルを resource フォルダに配置する
- Maven プロジェクトの場合、POM ファイルの resource を指定する
<build><resources><resource><!-- XMLをjavaディレクトリに配置 --><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource><!-- リソースの場所を指定(XMLをresourcesに配置する場合は指定不要) --><resource><directory>src/main/resources</directory></resource></resources></build>
-
例外1:
java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.ClassMapperScan では com.baomidou.mybatisplus.mapper.BaseMapper クラスとそのサブクラス(カスタム共通 Mapper)を除外する必要があります。例:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface SuperMapper<T> extends BaseMapper<T> {// your methods} -
例外2:
Injection of autowired原因:古いバージョンではジェネリクスの注入をサポートしていません。Spring バージョンを 4+ 以上にアップグレードしてください。
-
例外3:
java.lang.NoSuchMethodError: org.apache.ibatis.session.Configuration.getDefaultScriptingLanguageInstance() Lorg/apache/ibatis/scripting/LanguageDriverバージョンの問題:3.4.1 バージョンには存在せず、3.4.2 バージョンで追加されました!
long
ではなく Long
を使用しているか確認してください!
JavaScript では Java の long 型を正しく処理できないため精度が失われ、具体的には主キーの最後の2桁が常に 0 になります。解決方法:Long を String に変換して返します。
-
FastJson での処理方法
@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();FastJsonConfig fjc = new FastJsonConfig();// シリアル化戦略を設定fjc.setSerializerFeatures(SerializerFeature.BrowserCompatible);fastJsonConverter.setFastJsonConfig(fjc);converters.add(fastJsonConverter);} -
Jackson での処理方法
-
方法1
// アノテーション処理:ここでは共通の baseEntity の処理を設定することができます。@JsonSerialize(using=ToStringSerializer.class)public long getId() {return id;} -
方式二
// グローバル設定でシリアライズ JSON 処理を設定final ObjectMapper objectMapper = new ObjectMapper();SimpleModule simpleModule = new SimpleModule();simpleModule.addSerializer(Long.class, ToStringSerializer.instance);objectMapper.registerModule(simpleModule);
-
-
一般的な処理方法:
public String getIdStr()
メソッドを追加し、フロントエンドでidStr
を取得する
FieldStrategy には3つの戦略があります:
- IGNORED:無視
- NOT_NULL:NULL 以外、デフォルト戦略
- NOT_EMPTY:空でない
ユーザーがフィールドを空文字列または null
に更新する必要がある場合、FieldStrategy
戦略を調整する必要があります:
-
方式一:グローバル検証戦略の調整
設定 GlobalConfiguration にプロパティ fieldStrategy を注入する
-
方式二:フィールド検証アノテーションの調整
必要に応じて、更新が必要なフィールドで検証アノテーションを調整します。例:空でないことを検証:
@TableField(strategy=FieldStrategy.NOT_EMPTY) -
方式三:
UpdateWrapper
の使用 (3.x)以下の方法を使用して更新または挿入操作を行います:
//updateAllColumnById(entity) // 全フィールド更新: 3.0で削除されましたmapper.update(new User().setName("mp").setAge(3),Wrappers.<User>lambdaUpdate().set(User::getEmail, null) //emailをnullに設定.eq(User::getId, 2));//以下の書き方も参考にしてくださいmapper.update(null,Wrappers.<User>lambdaUpdate().set(User::getAge, 3).set(User::getName, "mp").set(User::getEmail, null) //emailをnullに設定.eq(User::getId, 2));
デフォルトで MySQL ドライバは tinyint(1) フィールドを boolean にマッピングします:0=false、0以外=true
MyBatis はこのマッピングを自動的に処理しません。tinyint(1) を boolean 型にマッピングしたくない場合:
- タイプを tinyint(1) から tinyint(2) または int に変更する
- 接続リクエストにパラメータ
tinyInt1isBit=false
を追加する必要があります。例:
jdbc:mysql://127.0.0.1:3306/mp?tinyInt1isBit=false
原因:2つのページングインターセプターが設定されています!設定ファイルまたはコードを確認し、1つだけを残してください!
insert 後、主キーは自動的にエンティティの ID フィールドに設定されるため、getId() を呼び出すだけで取得できます
EntityWrapper.sqlSelect 設定で検索したいフィールドを設定します
EntityWrapper<H2User> ew = new EntityWrapper<>();ew.setSqlSelect("test_id as id, name, age");//3つのフィールドのみを検索List<H2User> list = userService.selectList(ew);for(H2User u:list){ Assert.assertNotNull(u.getId()); Assert.assertNotNull(u.getName()); Assert.assertNull(u.getPrice()); // このフィールドは検索されていません}
//3.xmapper.selectList( Wrappers.<User>lambdaQuery() .select(User::getId, User::getName));// または QueryWrapper を使用mapper.selectList( new QueryWrapper<User>() .select("id","name"));
キャッシュは service 層に配置することをお勧めします。独自の BaseServiceImpl を作成し、アノテーション付きの親クラスメソッドをオーバーライドして、独自の実装を継承することができます。
MyBatis の方法でサードパーティの2次キャッシュを設定し、2.0.9 以上のバージョンを使用している場合、組み込みメソッドでキャッシュの内容を更新できない場合があります。以下の方法で解決できます(いずれかを選択):
1.コード内の MyBatis の mapper 層にキャッシュアノテーションを追加し、implementation または eviction の値を cache インターフェースの実装クラスとして宣言します
@CacheNamespace(implementation=MybatisRedisCache.class,eviction=MybatisRedisCache.class)public interface DataResourceMapper extends BaseMapper<DataResource>{}
2.対応する mapper.xml 中で既存のアノテーションをリンク式の宣言に変更し、xml ファイル内のキャッシュが正常に動作するようにします
<cache-ref namespace="com.mst.cms.dao.DataResourceMapper"></cache-ref>
jdbcTypeForNull=NULL を設定 Spring Bean 設定方法:
MybatisConfiguration configuration = new MybatisConfiguration();configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);configuration.setJdbcTypeForNull(JdbcType.NULL);configuration.setMapUnderscoreToCamelCase(true);//アンダースコアをキャメルケースに変換sqlSessionFactory.setConfiguration(configuration);
yml 設定
mybatis-plus: configuration: jdbc-type-for-null: 'null'
カスタム SQL では、Page オブジェクトは RowBounds を継承しているため、Mapper で直接取得できません。この問題を解決するために、以下の代替案を検討してください:
- カスタムの Map オブジェクトまたは通常の Java オブジェクトを使用してパラメータを渡す
- メソッドパラメータで @Param(“page”) int page, @Param(“size”) int size を使用してページ番号とページサイズを渡す
これらの方法により、カスタム SQL でパラメータを正しく渡し、コードがスムーズに実行されることを確認できます。
resultType="java.util.Map"
を使用する場合、Spring Boot でアンダースコアを自動的にキャメルケースに変換するには、以下の手順で実装できます:
Spring Boot プロジェクトに設定クラスを作成します。
@Configurationpublic class MybatisConfigurationCustomizer { @Bean public ConfigurationCustomizer configurationCustomizer() { return configuration -> configuration.setObjectWrapperFactory(new MybatisMapWrapperFactory()); }}
このように設定することで、Map 内のアンダースコアを自動的にキャメルケース形式に変換できます。これにより、MyBatis のクエリ結果が Map オブジェクトにマッピングされる際に、キー名が自動的に変換され、コード内でより簡単にデータにアクセスできるようになります。
Wrapper で limit
を使用して SQL 結果セットを制限するには、以下の方法を使用できます:
// 1行のデータのみを取得wrapper.last("limit 1");
このコードは SQL 文の末尾に limit 1 を追加し、結果セットの行数を1に制限します。
一般的なバッチ挿入操作を Service 層で処理する理由は以下の通りです:
- SQL の長さに制限がある:大量のデータを処理する場合、単一の SQL が実行できないか、メモリリークや JDBC 接続タイムアウトなどの問題が発生する可能性があります。
- 異なるデータベースの単一 SQL バッチ構文が一致しないため、汎用性が低下します。
- 解決策:ループ処理によるバッチコミットの方法を採用します。単一 SQL 挿入よりも若干パフォーマンスが低下しますが、上記の問題を解決できます。
単一 SQL 挿入方式を使用したい場合は、insertbatchsomecolumn を独自に注入するか、SQL インジェクター で提供されている方法を参照してください。
MyBatis Plus 3.x では、キーワードを自動的に認識して処理する機能は提供されなくなりました。データベースキーワードを処理する方法は以下の通りです:
-
異なるデータベースでキーワードの処理方法が異なるため、メンテナンスが困難です。データベース設計時には、キーワードをフィールド名やテーブル名として使用することを避けることをお勧めします。
-
キーワードを使用する必要がある場合は、フィールドまたはテーブル名の前後にバッククォート(`)を追加して処理できます:
@TableField(value = "`status`")private Boolean status;
結論として、問題を避けるために、データベース設計でできる限りキーワードを使用しないことをお勧めします。
MyBatis Plus 3.1.1 以降のバージョンで発生する問題:
現象:単体テストでは問題ありませんが、サーバーを起動してデバッグするとこの例外が発生します。
原因:3.1.1 バージョン以降、フィールドキャッシュの最適化が行われ、クラス名(className)の代わりに .class
をキーとして使用するようになりました。しかし、dev-tools を使用している場合、.class
が異なるクラスローダーでロードされる可能性があり、その結果、プロパティが見つからない状況が発生します。
解決策:dev-tools プラグインを削除します。これにより、異なるクラスローダーで .class
をロードすることを避け、この例外問題を解決できます。
MyBatis Plus 3.1.1 以降のバージョンで発生する問題:
現象:Druid データソースを統合する際、3.1.1 バージョン以降にアップグレードすると、java.sql.SQLFeatureNotSupportedException エラーが発生します。3.1.0 バージョン以前ではこの問題は発生しませんでした。
原因:MyBatis Plus 3.1.1 バージョン以降は新しい JDBC を採用し、新しい日付型(LocalDateTime など)の処理方法がアップグレードされました。しかし、Druid 1.1.21 バージョン以前はこの機能をサポートしていないため、この例外が発生します。詳細については 関連する質問 を参照してください。
解決策:
- Druid データソースを 1.1.21 バージョン以上にアップグレードして、この問題を解決します。
- Druid データソースをアップグレードできない場合は、MyBatis Plus のバージョンを 3.1.0 以前に維持することを選択できます。
- 最新の MyBatis Plus バージョンを引き続き使用する場合は、この例外を避けるために、新しい JDBC と互換性のある他のデータソースに切り替えることを検討してください。
MyBatis Plus を 3.1.0 以前のバージョンから上位バージョンにアップグレードし、新しい日付型(LocalDateTime など)がマッピングできないエラーが発生した場合、以下の理由が考えられます:
MP_3.1.0 以前のバージョンは MyBatis 3.5.0 に依存しています。MP_3.1.1 は MyBatis の依存関係を 3.5.1 にアップグレードしましたが、MyBatis 3.5.1 では、新しい日付型には JDBC 4.2 API をサポートする JDBC ドライバが必要です。
JDBC ドライバのバージョンが JDBC 4.2 API をサポートしていない場合、新しい日付型がマッピングできないエラーが発生します。
MyBatis 公式ブログ の内容を参照:
There is one backward incompatible changes since 3.5.0. Because of the fix for #1478 , LocalDateTypeHandler, LocalTimeTypeHandler and LocalDateTimeTypeHandler now require a JDBC driver that supports JDBC 4.2 API. [EDIT] These type handlers no longer work with Druid. Please see #1516 .
解決策:
- JDBC ドライバを JDBC 4.2 API をサポートするバージョンにアップグレードします。
- JDBC ドライバをアップグレードできない場合は、MyBatis Plus のバージョンを 3.1.0 以前にロールバックすることを検討してください。
Spring Boot のバージョンを 2.2.0 から上位バージョンにアップグレードする際にこの問題が発生した場合、以下の理由が考えられます:
現象:ローカルで起動する際は問題ありませんが、war パッケージにビルドしてサーバーにデプロイすると、この問題が発生します。
原因:Spring Boot 2.2.0 にはコンストラクタインジェクションの問題があり、MyBatis のプライベートコンストラクタが正しくプロパティをバインドできないため、MyBatis に依存するフレームワーク(MyBatis Plus など)でエラーが発生します。詳細については 関連 issue を参照してください。この問題は Spring Boot 2.2.1 で修正されました。
解決策:
- Spring Boot を 2.1.x バージョンにダウングレードするか、2.2.1 バージョン以上にアップグレードします。より良い安定性と修正を得るために、Spring Boot 2.2.2 バージョンに直接アップグレードすることをお勧めします。
現象:開発ツールで実行する際は問題ありませんが、プロジェクトをビルドしてサーバーにデプロイした後、Lambda 式を実行すると ClassNotFoundException が発生します。
MyBatis Plus 3.3.2 以前のバージョンで、ビルドを分離してデプロイした際に ClassNotFoundException が発生する場合、逆シリアライズ操作を実行する際にクラスローダーでエラーが発生している可能性があります。
解決策:
spring-boot-maven-plugin
プラグインを削除してビルドするか、- MyBatis Plus 3.3.2 バージョンにアップグレードします。例として 分離ビルド を参照してください。
MyBatis 内部ログを有効にするには、以下の2つの方法があります:
方式一:
application.yml
または application.properties
ファイルに以下の設定を追加します:
mybatis-plus: configuration: # プロジェクトにログフレームワークがない場合、org.apache.ibatis.logging.stdout.StdOutImpl を指定することができます(実際の本番環境では使用しないでください)。 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
これにより、MyBatis の組み込み StdOutImpl ログ実装を使用してログをコンソールに出力します。
方式二:
application.yml
または application.properties
ファイルにログレベル設定を追加して、特定のパッケージのログレベルを指定します。例:
logging: level: com.baomidou.example.mapper: debug
これにより、com.baomidou.example.mapper パッケージのログレベルが debug に設定されます。必要に応じてレベルを調整できます。
上記の設定により、MyBatis 内部ログを有効にし、必要に応じてログレベルを調整できます。
更新操作時にフィールドをインクリメントしたい場合、MyBatis Plus が提供する Wrapper
を使用して更新できます。以下は実行可能な解決策です:
UpdateWrapper<Entity> wrapper = new UpdateWrapper<>();wrapper.setSql("column = column + 1");
// または Lambda 式を使用UpdateWrapper<Entity> wrapper = new UpdateWrapper<>();wrapper.setSql("column = column + 1");
// update メソッドを呼び出すbaseMapper.update(null, wrapper);
これにより、更新時にフィールドをインクリメントできます。setSql
メソッドで直接 SQL 更新文を指定する必要があることに注意してください。
データベースキーワードをグローバルに処理したい場合、MyBatis Plus が提供するグローバル設定を使用できます。以下は設定例です(MySQL の場合):
mybatis-plus: global-config: db-config: column-format: "`%s`"
この設定により、MyBatis Plus は SQL 文を生成する際に、データベースフィールド名をバッククォート(“)で囲み、データベースキーワードとの競合を防ぎます。
注意点:
@TableField
アノテーションを使用し、グローバルフォーマットを維持したい場合は、パラメータkeepGlobalFormat=true
を設定する必要があります。@TableField
アノテーションで直接固定形式のデータベースキーワードを指定することもできます。例:@TableField("'status'")
。
上記の設定により、データベースキーワードをグローバルに処理し、生成される SQL 文がキーワードの影響を受けないようにできます。
XML でデータベースタイプに基づいて異なる SQL フラグメントを選択したい場合、MyBatis Plus が提供する database-id
パラメータを使用できます。以下は設定例です(MySQL の場合):
mybatis-plus: configuration: database-id: mysql
この設定により、MyBatis Plus は SQL 文を実行する際に、database-id
パラメータに基づいて異なる SQL フラグメントを選択します。
XML では、2通りの書き方で判断を実施できます:
- 変数
_databaseId
を使用:
<select id="selectAllNames" resultType="java.lang.String">select<choose> <when test="_databaseId == 'mysql'"> GROUP_CONCAT(name SEPARATOR ',') </when> <otherwise> array_to_string(ARRAY_AGG(name), ',') </otherwise></choose>form user</select>
- タグ属性
databaseId
を使用:
<select id="selectAllNames" databaseId="mysql" resultType="java.lang.String"> select GROUP_CONCAT(name SEPARATOR ',') form user</select><select id="selectAllNames" databaseId="pgsql" resultType="java.lang.String"> select array_to_string(ARRAY_AGG(name), ',') form user</select>
上記の設定により、異なるデータベースタイプに基づいて異なる SQL フラグメントを選択できます。
MyBatis Plus が複合主キーをサポートせず、一意の ID を強制する理由は以下の通りです:
-
テーブル間の相互依存性が増加:複合主キーを使用すると、テーブル間の関係がより複雑になり、メンテナンスと管理の難易度が増加します。
-
データの複雑な制約やルールが増加:複合主キーはデータの制約やルールを増加させます。例えば、一意性の制約が必要ですが、これは完全に結合インデックスで実現できます。
-
データ更新の制限が増加:データを更新する際に、すべての複合主キーの値を更新する必要があり、更新操作の制限と複雑さが増加します。
-
深刻なデータ冗長性と更新異常の問題:複合主キーはデータ冗長性と更新異常の問題を引き起こす可能性があり、特に大規模システムでは更新異常が発生する可能性があります。
-
パフォーマンスの問題:複合主キーを使用する場合、特定の ID をクエリする際にインデックスを使用できないため、パフォーマンスが低下します。
結論として、複合主キーを使用すると ID フィールドを1つ省略できますが、この方法の欠点は利点を上回るため、推奨されません。MyBatis Plus はデータ管理のシンプルさ、保守性、パフォーマンスを確保するために、一意の ID を使用し続けています。
-
デフォルトの Snowflake ID の初期化が原因です。
- ローカルホスト名を確認
- システムの hosts ファイルを編集し、ローカルホスト名を hosts ファイルに書き込む
# 例:ホスト名が nieqiurong-PC の場合、hosts ファイルに以下のように設定します127.0.0.1 localhost nieqiurong-PC -
データベース接続プールの初期化を確認
Linux システムで hikari を使用する際に、起動が遅くなる問題に遭遇しました
解決策:
Java 起動コマンドで -Djava.security.egd=file:/dev/urandom を指定し、乱数取得方式を /dev/random から /dev/urandom に変更します
例: java -Djava.security.egd=file:/dev/urandom -jar xxxx.jar
- 原因:ドライバ設定の非互換性
解決策:ドライバ接続から
rewriteBatchedStatements=true
設定を削除
- 原因:mybatis のデフォルトでは、返される行のすべての列が空の場合(プロパティが自動マッピングできない場合も含む)、デフォルトで null を返します
解決策:returnInstanceForEmptyRow を true に設定
mybatis-plus: configuration: return-instance-for-empty-row: true
- 原因:mybatis のデフォルトでは、null が返される場合、put メソッドが呼び出されません
解決策:callSettersOnNulls を true に設定
mybatis-plus: configuration: call-setters-on-nulls: true
インターフェースメソッドのオーバーライドは、default メソッドと抽象インターフェースメソッドを区別する必要があります。オーバーライドするメソッドは、最終的に呼び出される実際のメソッドに基づく必要があります。
抽象インターフェースメソッド:XML で直接このメソッドをオーバーライドすることで完了できます
default メソッド:実際に呼び出されるメソッドを直接オーバーライドするか、元の default を実際のインターフェースメソッドとしてオーバーライドし、XML またはアノテーション方式で実行文をオーバーライドします。
// 方式一: BaseMapper の selectPage メソッドをアノテーション方式でオーバーライド(低バージョンではインターフェースメソッドである可能性があります。ここでは新バージョンの default を例としています)@Override@Select("select * from h2user")<P extends IPage<H2User>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<H2User> queryWrapper);
// 方式二: BaseMapper の selectPage メソッドを XML 方式でオーバーライド(低バージョンではインターフェースメソッドである可能性があります。ここでは新バージョンの default を例としています)@Override<P extends IPage<H2User>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<H2User> queryWrapper);// ここで、XML 内で selectPage のクエリ文をオーバーライドします
// 方式三: BaseMapper の selectPage メソッドをオーバーライド@Overridedefault <P extends IPage<User>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper) { return xxxx(); //実際に呼び出される、独自に定義した実際のインターフェースメソッド}
- 原因:https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-m3-generating-default-methods-in-interfaces/
解決策:コンパイルプラグインのコンパイルパラメータ -Xjvm-default=all を設定
<plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <configuration> <args> <arg>-Xjsr305=strict</arg> <arg>-Xjvm-default=all</arg> </args> </configuration></plugin>
compileKotlin { kotlinOptions { freeCompilerArgs = ['-Xjvm-default=all'] }}
-
原因:
jsqlParser
4.9 から、連続する改行はステートメントの終了と見なされるようになりました。参考リンク: https://github.com/JSQLParser/JSqlParser/issues/1988
MyBatis-Plus はバージョン 3.5.3.2 から、フレームワーク内蔵の SQL 注入文に対して改行処理を行うようになりましたが、プロジェクト内で独自に記述した SQL 文については、開発者が自ら改行処理を行う必要があります。
-
注意: 3.5.10 と 3.5.10.1 バージョンではプロジェクト内の改行に対応しましたが、単一行コメント (
--
または#
) の処理はサポートされていません。3.5.11 バージョン以降はこの処理は行われません。
方法1:
static { JsqlParserGlobal.setParserMultiFunc((sql)-> { String formatSql = CCJSqlParserUtil.sanitizeSingleSql(sql); return CCJSqlParserUtil.parseStatements(formatSql, JsqlParserGlobal.getExecutorService(), null); }); JsqlParserGlobal.setParserSingleFunc((sql)-> { String formatSql = CCJSqlParserUtil.sanitizeSingleSql(sql); return CCJSqlParserUtil.parse(formatSql, JsqlParserGlobal.getExecutorService(), null); });}
// 如果jsqlParser低于5.0,请把如下方法复制到自己工程里,代码来源JsqlParser5.0版本。public static String sanitizeSingleSql(String sqlStr) { Pattern SQL_DELIMITER_SPLIT = Pattern.compile("((?:'[^']*+'|[^\\n])*+)"); StringBuilder builder = new StringBuilder(); Matcher matcher = SQL_DELIMITER_SPLIT.matcher(sqlStr); while(matcher.find()) { for(int i = 1; i <= matcher.groupCount(); ++i) { if (!matcher.group(i).isEmpty()) { builder.append("\n").append(matcher.group(i)); } } } return builder.toString();}
方法2: MyBatis の改行削除機能を有効にします (汎用性はあまり高くない可能性があり、単一行コメント --
や #
は処理できません)。
mybatis-plus: configuration: shrink-whitespaces-in-sql: true
メンテナンスされなくなるため、使用しないことをお勧めします。生成する必要がある場合は、以下の手順に従って Service
を Repository
に変換してください。
AutoGenerator generator = new AutoGenerator(DATA_SOURCE_CONFIG);generator.packageInfo(new PackageConfig.Builder() //-- 変換開始 ---- .service("repository") .serviceImpl("repository.impl") //-- 変換終了 ---- .build());generator.strategy( new StrategyConfig.Builder() //-- 変換開始 ---- .serviceBuilder().convertServiceFileName(entityName -> "I" + entityName + "Repository") .superServiceClass(IRepository.class).convertServiceImplFileName(entityName -> entityName + "Repository") .superServiceImplClass(CrudRepository.class) //-- 変換終了 ---- .build());generator.execute();