<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright ${license.git.copyrightYears} the original author or authors.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<document xmlns="http://maven.apache.org/XDOC/2.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">

  <properties>
    <title>MyBatis-Spring | MyBatis API の使用</title>
    <author email="hpresnall@gmail.com">Hunter Presnall</author>
    <author email="eduardo.macarron@gmail.com">Eduardo Macarron</author>
    <author email="harawata@gmail.com">Iwao AVE!</author>    
  </properties>
     
  <body>
    <section name="MyBatis API の使用">
      <p>
        MyBatis-Spring を使っている場合でも、直接 MyBatis API を呼び出すことができます。
        Spring の設定で <code>SqlSessionFactoryBean</code> を使って <code>SqlSessionFactory</code> を生成すれば、コード内で使用することができます。
      </p>
      <source><![CDATA[public class UserDaoImpl implements UserDao {
  // SqlSessionFactory would normally be set by SqlSessionDaoSupport
  private final SqlSessionFactory sqlSessionFactory;

  public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
    this.sqlSessionFactory = sqlSessionFactory;
  }

  public User getUser(String userId) {
    // note standard MyBatis API usage - opening and closing the session manually
    try (SqlSession session = sqlSessionFactory.openSession()) {
      return session.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
    }
  }
}]]></source>

      <p>
        この方法を使う場合は注意が必要です。
        なぜなら、誤った使い方をすると実行時エラーや、最悪の場合データの不整合といった問題を生じる可能性があるからです。
        MyBatis API を直接使用する場合、次のような点に注意してください。
      </p>
      <ul>
        <li>
          <p>
            API の呼び出しは Spring で管理されているトランザクション内では実行されません。
          </p>
        </li>
        <li>
          <p>
            <code>SqlSession</code> が Spring のトランザクションマネージャーが使っているのと同じ <code>DataSource</code> を使っていて、既に進行中のトランザクションが存在している場合、このコードは例外を投げます。
          </p>
        </li>
        <li>
          <p>
            MyBatis の <code>DefaultSqlSession</code> はスレッドセーフではありません。
            もしあなたの Bean に注入した場合、エラーが発生します。
          </p>
        </li>
        <li>
          <p>
            <code>DefaultSqlSession</code> を使って生成した Mapper もスレッドセーフとはなりません。
            もしあなたの Bean に注入した場合、エラーが発生します。
          </p>
        </li>
        <li>
          <p>
            <code>SqlSession</code> は常に finally ブロックでクローズする必要があります。
          </p>
        </li>
      </ul>
    </section>
  </body>
</document>
