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
  3. You can use dark theme
What you can do with signing up
4