概要
MyBatis Generatorで生成したMapperを呼び出そうとしたところ、以下のようなエラーが出ました:
There was an unexpected error (type=Internal Server Error, status=500).
Invalid bound statement (not found): com.example.demo.dao.FileTypeMapper.selectByExample
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.demo.dao.FileTypeMapper.selectByExample
	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
...
この記事では、このエラーが出る原因と解決方法について調べた結果を共有します。
原因
Mapperインターフェース(*Mapper.java)とMapper XML(*Mapper.xml)のクラスパスが一致していない場合に、上のようなエラーが出てしまうようです。
このことが公式ドキュメントに書かれていないか調べてみたのですが、以下のあたりが該当しているのでしょうか・・・(?)
http://mybatis.org/spring/mappers.html
If the UserMapper has a corresponding MyBatis XML mapper file in the same classpath location as the mapper interface, it will be parsed automatically by theMapperFactoryBean. There is no need to specify the mapper in a MyBatis configuration file unless the mapper XML files are in a different classpath location.
自分の環境でエラーが出た原因ですが、MySQLで以下のようなデータベースを作成し・・・
CREATE TABLE DEMODB.FILE_TYPE (
    TYPE_ID INT NOT NULL PRIMARY KEY,
    NAME VARCHAR(256) NOT NULL
);
CREATE TABLE DEMODB.FILE (
    TYPE_ID INT NOT NULL PRIMARY KEY,
    NAME VARCHAR(256) NOT NULL,
    CONTENT LONGBLOB NOT NULL
);
・・・そして、上のデータベースに対して、MyBatis GeneratorのgeneratorConfig.xmlを以下のように設定してMapperを生成していました。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
	<classPathEntry
		location="C:\Users\hiroki\.m2\repository\com\mysql\mysql-connector-j\8.0.31\mysql-connector-j-8.0.31.jar" />
	<context id="MySQLTables" targetRuntime="MyBatis3">
		<commentGenerator>
			<property name="suppressDate" value="true" />
		</commentGenerator>
		<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/DEMODB" userId="dev"
			password="password1234">
		</jdbcConnection>
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>
		<javaModelGenerator
			targetProject="mybatis-generator-example/src/main/java"
			targetPackage="com.example.demo.model">
			<property name="enableSubPackages" value="true" />
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
		<sqlMapGenerator
			targetProject="mybatis-generator-example/src/main/resources"
			targetPackage="xml">
			<property name="enableSubPackages" value="true" />
		</sqlMapGenerator>
		<javaClientGenerator type="XMLMAPPER"
			targetProject="mybatis-generator-example/src/main/java"
			targetPackage="com.example.demo.dao">
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>
		<table schema="DEMODB" tableName="FILE_TYPE">
			<property name="useActualColumnNames" value="true" />
		</table>
		<table schema="DEMODB" tableName="FILE">
			<property name="useActualColumnNames" value="true" />
		</table>
	</context>
</generatorConfiguration>
ここで、generatorConfig.xmlの中で
sqlMapGenerator.targetPackage="xml"
javaClientGenerator.targetPackage="com.example.demo.dao"
となっており、両者が一致していないため、エラーが出たようです。
解決方法
解決方法は2つあります。
- 
generatorConfig.xmlでtargetPackageの値を一致させる。 - 
application.propertiesでMapperの場所を明示的に指定する。 
これらの方法をそれぞれ解説していきます。
1. generatorConfig.xmlでtargetPackageの値を一致させる
以下のように、generatorConfig.xmlの中でsqlMapGeneratorとjavaClientGeneratorのtargetPackageの値が一致するように修正します。
その後、再びMyBatis Generatorを実行してMapperを再生成すると、最初に載せたエラーが出なくなります。
具体的には、generatorConfig.xmlを以下のように修正します。
...
<sqlMapGenerator
    targetProject="mybatis-generator-example/src/main/resources"
    targetPackage="com.example.demo.dao">        <-- ここを一致させる
    <property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER"
    targetProject="mybatis-generator-example/src/main/java"
    targetPackage="com.example.demo.dao">        <-- ここを一致させる
    <property name="enableSubPackages" value="true" />
</javaClientGenerator>
...
2. application.propertiesでMapperの場所を明示的に指定する
generatorConfig.xmlで指定したsqlMapGenerator.targetPackageの場所を、application.propertiesのmybatis.mapper-locationsで指定します。
具体的には、以下のように設定します。
...
<sqlMapGenerator
    targetProject="mybatis-generator-example/src/main/resources"
    targetPackage="xml">        <-- このようにパスを指定した場合・・・
    <property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER"
    targetProject="mybatis-generator-example/src/main/java"
    targetPackage="com.example.demo.dao">
    <property name="enableSubPackages" value="true" />
</javaClientGenerator>
...
mybatis.mapper-locations:classpath*:xml/*.xml        <-- このように記載する