6

今日はSpring Bootを使った例、Spring-MyBatisの次にデータアクセス通信にMyBatisを使った例を準備していました。関連するプロジェクト構成は次のとおりです(mavenを使用):

src/main/java
- edu.home.ltmj.controller
  + CategoryController.java
- edu.home.ltmj.dao
  + CategoryDao.java
- edu.home.ltmj.domain
  + Category.java
src/main/resources
- edu.home.ltmj.dao
  + CategoryMapper.xml

ファイルの関連コンテンツ:

カテゴリDao.java:

package edu.home.ltmj.dao;

public interface CategoryDao {
    List<Category> getAllCategories();
}

CategoryMapper.xml:

<mapper namespace="edu.home.ltmj.dao.CategoryDao">
    <resultMap id="categoryMap"
        type="edu.home.ltmj.domain.Category">
        <id property="id" column="id" />
        <result property="name" column="name" />
    </resultMap>
    <select id="getAllCategories" resultMap="categoryMap">
        SELECT id, nombre
        FROM category
    </select>
</mapper>

次に、この dao のインスタンスを (テスト目的で) リクエスト コントローラーに次のように挿入します。

package edu.home.ltmj.controller;

@RestController
public class CategoryController {
    @Autowired
    private CategoryDao dao;

    @RequestMapping(value="/category/all",
        method=RequestMethod.GET,
        produces=MediaType.APPLICATION_JSON_VALUE)
    public List<Categoria> getAllCategories() {
        return dao.getAllCategories();
    }
}

プロジェクトを実行し、実行をテストしてcurl localhost:8080/category/allから、JSON 形式で結果が表示されることを期待していましたが、代わりに次の例外が発生しました。

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): edu.home.ltmj.dao.CategoryDao.getAllCategories
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:189)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:43)
at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:51)
at com.sun.proxy.$Proxy45.getAllCategories(Unknown Source)
at edu.home.ltmj.controller.CategoryRestController.getAllCategories(CategoryRestController.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
(...)

この原因がわかりません。インターフェイスがあり、と一致CategoryDaoする適切なメソッドがあります。これでしばらく遊んだ後、dao インターフェイスの名前を に変更し、CategoryMapper.xml の名前空間を更新しました。これを行った後、すべてが正常に機能しました。また、クラスとxmlに同じ名前を付けた後、daoクラスとxmlマッパーを別のパッケージに移動し(まだ両方に同じ名前を使用しています:CategoryMapper.)、xmlファイルの名前空間を更新しましたが、同じ例外が発生しました、dao インターフェイスのパッケージの名前を表示するようにメッセージが更新されています。しかし、もう一度、両方のファイルを同じパッケージに移動すると、すべてが再び機能しました。getAllCategories<select id="getAllCategories">CategoryMapper

私の質問は、なぜ MyBatis はインターフェイスと xml マッパー ファイルが同じ名前で、同じパッケージにある必要があるのですか? これは MyBatis の設計ですか、それとも Spring MyBatis の問題ですか?

4

2 に答える 2

6

MyBatis Config ファイルもありますか?

私が正しく覚えていれば、インターフェイスと同じ名前の XML ファイルの同じ場所は、追加の構成なしで機能するセットアップが必要な場合です。

XML マッパーが別の場所にある場合は、MyBatis 構成<mappers>内の要素を使用して XML ファイルのクラスパスを手動で指定できます。

注入マッパーのドキュメントから:

UserMapper の対応する MyBatis XML マッパー ファイルがマッパー インターフェースと同じクラスパスの場所にある場合、それは MapperFactoryBean によって自動的に解析されます。マッパー XML ファイルが別のクラスパスの場所にない限り、MyBatis 構成ファイルでマッパーを指定する必要はありません。詳細については、SqlSessionFactoryBean の configLocation プロパティを参照してください。

だからこれを試してください:

  1. これを含むmybatis-config.xmlファイルを内部に作成します。src/main/resources

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
      PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
      <mappers>
        <mapper resource="com/test/path/etc/etc/WhateverNameYouWant.xml"/>
      </mappers>
    </configuration>
    

    WhateverNameYouWant.xmlあなたの内容がどこに含まれているかCategoryMapper.xml

  2. 構成ファイルの場所を設定します (以下の Java 構成またはapplicationContextファイル内の Bean)。

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        // ....
        sessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
        // ....
        return sessionFactory;
    }
    
于 2015-05-16T12:49:11.873 に答える
1

次のように @MapperScan なしで次の方法を使用しました。

1) 上記のステップ 2 と同様に mybatis-config.xml をセットアップします。

@Bean
public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    // ....
    sessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
    // ....
    return sessionFactory;
}

2) CategoryDao の設定

@Bean
public CategoryDao getCategoryDao() throws Exception{
    SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean());
    return sessionTemplate.getMapper( CategoryDao.class );
}

3) mybatis-config.xml 内のセットアップ

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

    <settings>
        <setting name="logImpl" value="COMMONS_LOGGING"/>
    </settings>

    <mappers>

        <mapper class="CategoryMapper.xml"/>
    </mappers>

</configuration>
于 2015-05-17T01:45:11.297 に答える