Help us understand the problem. What is going on with this article?

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

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と使い分けることも可能なので、必要に応じて構成管理ができると思います。

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

参考

https://github.com/mybatis/mybatis-dynamic-sql

https://mybatis.org/mybatis-dynamic-sql/docs/conditions.html

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした