LoginSignup
7
7

More than 5 years have passed since last update.

JavaEE7でMyBatisを利用する

Last updated at Posted at 2017-01-09

↓の続きです。
http://qiita.com/RyoTa63292153/items/ec0eaf0bd0a5820c4be6


依存ライブラリを追加

build.gradledependenciescompile 'org.mybatis:mybatis:3.4.2'を追加します。


設定ファイルを追加

src/main/resources/mybatis-config.xmlを作成します。

GlassFishに登録したJDBCリソースを利用するため、dataSourcetypeJNDIに設定します。
propertydata_sourceの値は、glassfish-resources.xmlで設定しているjndi-nameです。

transactionManagertypeMANAGEDに設定します。

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>
    <!--
    Glassfishに登録したJNDIリソースを利用する
    data_sourceの指定が必須
    -->
    <environments default="apple">
        <!-- apple -->
        <environment id="apple">
            <transactionManager type="MANAGED">
                <property name="closeConnection" value="false"/>
            </transactionManager>
            <dataSource type="JNDI">
                <property name="data_source" value="jdbc/apple_data_source"/>
            </dataSource>
        </environment>
        <!-- pineapple -->
        <environment id="pineapple">
            <transactionManager type="MANAGED">
                <property name="closeConnection" value="false"/>
            </transactionManager>
            <dataSource type="JNDI">
                <property name="data_source" value="jdbc/pineapple_data_source"/>
            </dataSource>
        </environment>
    </environments>
    <!-- Mapperの登録が必須 -->
    <mappers>
        <mapper class="sample.payara.mybatis.mapper.AppleMyBatisMapper"/>
        <mapper class="sample.payara.mybatis.mapper.AppleMyBatisXmlMapper"/>
        <mapper class="sample.payara.mybatis.mapper.PineappleMyBatisMapper"/>
    </mappers>
</configuration>

SqlSessionを取得するためのBeanを作成

SqlSessionのインスタンスを、SQLを実行する度にSqlSessionFactory#openSessionして取得しないようにします。

SqlSessionを利用するクラスでは、以下のようにインスタンスを取得することができます。

@Inject
private SqlSession sqlSession;
sample.payara.mybatis.provider.MyBatisSqlSessionProvidor
@Stateless
public class MyBatisSqlSessionProvidor {
    /*
     * SqlSessionFactoryのインスタンスをCDI経由でインジェクションする
     * 下記で宣言している`appleSessionFactory`と`pineappleSessionFactory`がCDIに登録するメソッド
     */
    @AppleDataSource
    @Inject
    private SqlSessionFactory appleSessionFactory;

    @PineappleDataSource
    @Inject
    private SqlSessionFactory pineappleSessionFactory;

    private SqlSessionFactory create(String environment) {
        try (InputStream stream = Resources.getResourceAsStream("mybatis-config.xml")) {
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            return builder.build(stream, environment);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    /*
     * SqlSessionFactoryのインスタンスをCDIに登録
     * DataSourceを複数利用しているため、`@AppleDataSource`と`@PineappleDataSource`というannotationで識別している
     * `SqlSessionFactory`はアプリケーションが起動している間はインスタンスを破棄しないために`@ApplicationScoped`を指定する
     */
    @ApplicationScoped
    @AppleDataSource
    @Produces
    public SqlSessionFactory appleSessionFactory() {
        return this.create("apple");
    }

    @ApplicationScoped
    @PineappleDataSource
    @Produces
    public SqlSessionFactory pineappleSessionFactory() {
        return this.create("pineapple");
    }

    /*
     * `SqlSession`をインジェクションするためのメソッド
     * Request毎にopen/closeするため`@RequestScoped`を指定
     * `@Produces`でCDI経由でインスタンスを取得できるようになる
     */
    @RequestScoped
    @AppleDataSource
    @Produces
    public SqlSession appleSession() {
        return appleSessionFactory.openSession();
    }

    @RequestScoped
    @PineappleDataSource
    @Produces
    public SqlSession pineappleSession() {
        return pineappleSessionFactory.openSession();
    }

    /*
     * Requestが完了したときに`SqlSession`をcloseする
     */
    public void closeAppleSession(@Disposes @AppleDataSource SqlSession sqlSession) {
        sqlSession.close();
    }

    public void closePineappleSession(@Disposes @PineappleDataSource SqlSession sqlSession) {
        sqlSession.close();
    }
}

Mapperを作成

JavaAPIを利用したMapper

sample.payara.mybatis.mapper.AppleMyBatisMapper
public interface AppleMyBatisMapper {

    /* SQL実行結果をオブジェクトにマッピングするための設定 */
    @Results(id = "findAllMybatisUser", value = {
            @Result(property = "id", column = "id", id = true),
            @Result(property = "name", column = "name"),
            @Result(property = "created", column = "created"),
            @Result(property = "updated", column = "updated"),
    })
    /* select文 */
    @Select({
        "select *",
        "from sample_model",
    })
    public List<MyBatisUser> findAll();

    @Results(id = "findByMybatisUser", value = {
            @Result(property = "id", column = "id", id = true),
            @Result(property = "name", column = "name"),
            @Result(property = "created", column = "created"),
            @Result(property = "updated", column = "updated"),
    })
    @Select({
        "select *",
        "from sample_model s",
        "where s.id = #{id}"
    })
    public MyBatisUser findById(@Param("id") Long id);

    /* SQL文を動的に組み立てる */
    @SelectProvider(type = MyBatisMapperSqlBuilder.class, method = "findByParamSql")
    public List<MyBatisUser> findByParam(@Param("param") MyBatisUserSearchParam param);
}
sample.payara.mybatis.mapper.MyBatisMapperSqlBuilder
public class MyBatisMapperSqlBuilder {
    /*
     * SQL文の`#{param.xxx}`の部分は、このメソッドの`@Param("param")`を参照している
     * `AppleMyBatisMapper#findByParam`で指定されている`param`では無い
     */
    public String findByParamSql(@Param("param") final MyBatisUserSearchParam param) {
        SQL sql = new SQL()
                .SELECT("*")
                .FROM("sample_model s");

        if (param.hasId()) {
            sql.WHERE("s.id = #{param.id}");
        }

        if (param.hasName()) {
            sql.WHERE("s.name like #{param.name} ");
        }

        return sql.toString();
    }

}

XMLを利用したMapper

sample.payara.mybatis.mapper.AppleMyBatisXmlMapper
public interface AppleMyBatisXmlMapper {

    public MyBatisUser findById(@Param("id") final Long id);

    public List<MyBatisUser> findByParam(@Param("param") final MyBatisUserSearchParam param);

}
src/main/java/sample/payara/mybatis/mapper/AppleMyBatisXmlMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="sample.payara.mybatis.mapper.AppleMyBatisXmlMapper">
    <resultMap type="sample.payara.model.MyBatisUser" id="MyBatisUser">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="created" property="created"/>
        <result column="updated" property="updated"/>
    </resultMap>
    <select id="findById" resultMap="MyBatisUser">
        SELECT *
          FROM sample_model s
        <where>
            AND s.id = #{id}
        </where>
    </select>
    <select id="findByParam" resultMap="MyBatisUser">
        SELECT *
          FROM sample_model s
        <where>
            <if test="param.hasId()">
                AND s.id = #{param.id}
            </if>
            <if test="param.hasName()">
                <bind name="pattern" value="param.name + '%'"/>
                AND s.name LIKE #{pattern}
            </if>
        </where>
    </select>
</mapper>

Mapperを呼び出す

SqlSessionからMapperのインスタンスを取得してメソッドを実行できます。

sample.payara.mybatis.repotiroy.AppleMyBatisRepository
@Stateless
public class AppleMyBatisRepository {
    @AppleDataSource
    @Inject
    private SqlSession sqlSession;

    /*
     * `sqlSession.getMapper`でMapperのインスタンスを取得できる
     */
    private AppleMyBatisMapper mapper() {
        return sqlSession.getMapper(AppleMyBatisMapper.class);
    }

    private AppleMyBatisXmlMapper xmlMapper() {
        return sqlSession.getMapper(AppleMyBatisXmlMapper.class);
    }

    public List<MyBatisUser> findAll() {
        return mapper().findAll();
    }

    public MyBatisUser findBy(final Long id) {
        return mapper().findById(id);
    }

    public List<MyBatisUser> findBy(final MyBatisUserSearchParam param) {
        return mapper().findByParam(param);
    }

    public List<MyBatisUser> findByXmlMapper(final MyBatisUserSearchParam param) {
        return xmlMapper().findByParam(param);
    }
}

参考

参考にしました m(__)m

http://n-agetsuma.hatenablog.com/entry/2013/01/13/151303
http://qiita.com/opengl-8080/items/431de9175dca33a09ba8
http://www.mybatis.org/mybatis-3/ja/index.html

ソースは↓にあります、参考になれば幸いです
https://github.com/yamashiro0110/JavaEE/tree/master/Payara

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7