LoginSignup
4

More than 3 years have passed since last update.

MyBatis Dynamic SQLで柔軟なORマッピング実装をしてみた

Last updated at Posted at 2019-12-21

MyBatis Dynamic SQLを使ってみよう!

今回はMyBatis Dynamic SQLを使ってSQLを発行し、データを取得する実装を試してみました!

業務でバリバリ使うことになるかもなので、備忘録として残しておきます。
実装形式としてはSeasar2のS2JDBCに似ていて、複数のメソッドチェインを行うことで発行するSQLを作成しています。

実行準備

用意したテーブルはこんな感じでシンプルなものを用意しました。
データはテキトーに数件登録しておきます。

CREATE TABLE "MEMBER" ( 
  "ID" NUMBER(8,0)
  , "BLOOD" VARCHAR2(20 BYTE)
  , "NAME" VARCHAR2(20 BYTE)
  , "CORP" VARCHAR2(20 BYTE)
);

Entityもテーブル構成に合わせて作成します。

public class Member {

    private Integer id;

    private String name;

    private String corp;

    private String blood;

    //getter・setterは省略

}

マッパーインターフェースは下記のように作成します。
今回は複数のデータをListに返却する想定で実装しています。

public interface MemberMapper {

    @SelectProvider(type=SqlProviderAdapter.class, method="select")
    @Results(id="memberResult", value={
        @Result(column="ID", property="id"),
        @Result(column="NAME", property="name"),
        @Result(column="CORP", property="corp"),
        @Result(column="BLOOD", property="blood"),
    })
    List<Member> selectMany(SelectStatementProvider selectStatement);

}

MyBatis Dynamic SQLと連携するためのサポートクラスを作成します。
取得するカラムやWHERE句の指定をするときなどに利用します。

public final class MemberDynamicSqlSupport {

    public static final Member Member = new Member();

    public static final SqlColumn <Integer> id = Member.id;
    public static final SqlColumn <String> name = Member.name;
    public static final SqlColumn <String> corp = Member.corp;
    public static final SqlColumn <String> blood = Member.blood;


    public static final class Member extends SqlTable {
        public final SqlColumn <Integer> id = column("ID", JDBCType.INTEGER);
        public final SqlColumn <String> name = column("NAME", JDBCType.VARCHAR);
        public final SqlColumn <String> corp = column("CORP", JDBCType.VARCHAR);
        public final SqlColumn <String> blood = column("BLOOD", JDBCType.VARCHAR);

        public Member() {
            super("Member");
        }
    }

}

SQL実行

上記で作成したクラスを使って実際にSQLを発行するクラスを実装してみましょう。
今回はjunitを使ってテストコードを実装してみます。

import static jp.co.stylez.support.MemberDynamicSqlSupport.*;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.isLessThan;
import static org.mybatis.dynamic.sql.SqlBuilder.select;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MybatisConfig.class)
public class Main {

    @Autowired
    ApplicationContext context;

    @Test
    public void test() {

        MemberMapper mapper = context.getBean(MemberMapper.class);

        SelectStatementProvider selectStatement = select(Member.allColumns()).from(Member).where(id, isLessThan(10))
                .and(corp, isEqualTo("stylez")).orderBy(id).build().render(RenderingStrategies.MYBATIS3);

        List<Member> members = mapper.selectMany(selectStatement);

        for (Member member : members) {
            System.out.println("********************");
            System.out.println("id:" + member.getId());
            System.out.println("name:" + member.getName());
            System.out.println("corp:" + member.getCorp());
            System.out.println("blood:" + member.getBlood());
            System.out.println("********************");
        }
    }

}

Configクラスは別途実装してDataSourceやMapperScan対象の設定をしておきます。
XML形式でも設定可能ですが、今回はJavaで設定しました。
(設定関連の解説は割愛します)

MapperScanで登録したMapperを取り出し、実際にSQLを実行しています。

実行結果は下記のようになります。

********************
id:1
name:hogehoge
corp:stylez
blood:B
********************
********************
id:2
name:test.taro
corp:stylez
blood:O
********************
********************
id:3
name:hiroya.endo
corp:stylez
blood:A
********************

指定した条件のデータが複数取得出来ていることが確認できました!

実際に使ってみて…

主にWHERE句の条件指定に関して非常に柔軟な実装が可能だと感じました。
コードの可読性としても非常に高く、コーティングもしやすいので使いやすい印象でした。

テーブル結合やサブクエリにも対応できるので、それもまた魅力の一つかと思いました。
Mapper.xmlを使用したSQLと使い分けることも可能なので、必要に応じて構成管理ができると思います。

これから使う方のよい参考になれば幸いです!

参考

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
What you can do with signing up
4