SlideShare a Scribd company logo
本日のお話
MyBatis
数億を超える
社内きっての大規模プロジェクト
可用性 99.99%
 絶対に止まらないシステム
データ件数 2億件
 ビックデータへの対応
連携装置 3万台
 負荷に対応できるシステム
このプロジェクトに
MyBatisで挑みました!
(`・ω・)
本日は
・MyBatisの紹介
・プロジェクトに適用した
 MyBatisの技術事例
についてお話をしよう
と思います!
つまりですね
これは、高可用・大規模プロジェクトに挑んだ
知られざるシステムアーキテクトの話である
主題歌「地上の星」
中島 みゆき
一般的な中堅SIer
社内きっての
大規模プロジェクト
可用性
99.99%
許される年間停止時間
53分未満
現行システムに性能遅延
連
携
装
置
3
万
台
デー
タ
件
数
 
 
2
億
件
以
上
!
移
行
時
も
シ
ス
テ
ム
停
止
は
許
さ
れ
な
い
!
インフルエンザ
の猛威!
次々倒れるチームメンバ
(平均年齢35才)
新チーム結成
シスアーキ
の意地!
負荷テストで
システムダウン!
迫られるO/R Mapperの
選択
MyBatisで行く!
押し寄せる
寝不足
ドラクエX
挑め!99.99%!
~大規模プロジェクトに見る
 MyBatisの技術事例~
presents by
すいません
お待たせしました
m(__)m
オープニングは前回の
使いまわしです。
# もう一度使ってみたかった
ちなみに
可用性 99.99%!
データ件数 2億件!
連携装置 3万台!
をどのように実現したのか
可用性 99.99%!
データ件数 2億件!
連携装置 3万台!
をどのように実現したのか
などの話はしません
話すのはMyBatisの内容ね
難しい話はできません
ごめんね
MyBatis
自己紹介自己紹介
<名前>
こざけさんじゅうはっさい
<メッセージ>
はい、ビールが好きです!
Twitter@s_kozake
<最近のお気に入り>
ニャンコ先生
MyBatis
MyBatis #とは
MyBatis入門
MyBatisの活用事例
まとめ
AgendaAgenda
MyBatis
MyBatis #とは
MyBatis入門
MyBatisの活用事例
まとめ
AgendaAgenda
MyBatis
MyBatis #とは
・XMLまたはアノテーションを用いてストアドプロシージャ
 やSQL文をオブジェクトと紐付ける永続性フレームワーク
・Apache License 2.0によるオープンソースソフトウェアとして提供
・以前はiBATISとして知られていた
wikiより転載
http://ja.wikipedia.org/wiki/MyBatis
MyBatis
MyBatis #とは
・他のO/Rマッピングフレームワークとは異なりデータベースと
 オブジェクトをマッピングするのではなく、SQL文とオブジェクト
 のマッピングを行う
・レガシーな環境や非正規化されたデータベース、またはSQL文
 の実行を完全に制御したい場合に、よい選択肢となる
・一番の特徴は、XMLに記述したSQL文を普通のオブジェクト
 と組み合わせられることである
wikiより転載
http://ja.wikipedia.org/wiki/MyBatis
特徴
MyBatis
MyBatis #とは
・他のO/Rマッピングフレームワークとは異なりデータベースと
 オブジェクトをマッピングするのではなく、SQL文とオブジェクト
 のマッピングを行う
・レガシーな環境や非正規化されたデータベース、またはSQL文
 の実行を完全に制御したい場合に、よい選択肢となる
・一番の特徴は、XMLに記述したSQL文を普通のオブジェクト
 と組み合わせられることである
wikiより転載
http://ja.wikipedia.org/wiki/MyBatis
特徴
プロジェクトにMyBatisを
採用した理由は
この特徴が大きいです。
MyBatis
MyBatis #とは
MyBatis入門
MyBatisの活用事例
まとめ
AgendaAgenda
MyBatis
MyBatis入門
・「例示は理解の試金石」 by 数学ガール
・MyBatisのSimpleなサンプル実装をMyBatisの概念図と
 紐付けて示します。
MyBatis
MyBatis #とは
用意したDB
ID INT (PK)
NAME VARCHAR(100)
SEX CHAR(1)
COMMENT CLOB
CREATED TIMESTAMP
ユーザ(USER)
ID INT (PK)
NAME VARCHAR(100)
アイテム(ITEM)
USER_ID INT (PK)
ITEM_ID INT (PK)
ユーザ所有アイテム
(USER_BELONG_ITEMS)1
*
1
*
MyBatis
MyBatis入門
MyBatis
MyBatis入門
MyBatisの設定ファイル
DB接続定義やMapper SQL Statementなどの定義
MyBatis
MyBatis入門
MyBatisの設定ファイル
DB接続定義やMapper SQL Statementなどの定義
<?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 >
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:tcp://localhost/C:MyFilesormdaoh2db;schema=orm"/>
<property name="username" value="ORM"/>
<property name="password" value="orm"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="sample/sql/UserMap.xml" />
<mapper class="sample.mapper.ItemMapper" />
</mappers>
</configuration>
MyBatis
MyBatis入門
MyBatisの設定ファイル
DB接続定義やMapper SQL Statementなどの定義
<?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 >
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:tcp://localhost/C:MyFilesormdaoh2db;schema=orm"/>
<property name="username" value="ORM"/>
<property name="password" value="orm"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="sample/sql/UserMap.xml" />
<mapper class="sample.mapper.ItemMapper" />
</mappers>
</configuration>
Databaseへの接続設定
MyBatis
MyBatis入門
MyBatisの設定ファイル
DB接続定義やMapper SQL Statementなどの定義
<?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 >
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:tcp://localhost/C:MyFilesormdaoh2db;schema=orm"/>
<property name="username" value="ORM"/>
<property name="password" value="orm"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="sample/sql/UserMap.xml" />
<mapper class="sample.mapper.ItemMapper" />
</mappers>
</configuration>
SqlMapの情報
MyBatis
MyBatis入門 SQLとオブジェクトとのマッピング定義
MyBatis
MyBatis入門 SQLとオブジェクトとのマッピング定義
<?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.mapper.UserMapper" >
<select id="selectUser" resultType="sample.entity.User" >
select * from USER where id =#{id}
</select>
</mapper>
MyBatis
MyBatis入門 SQLとオブジェクトとのマッピング定義
<?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.mapper.UserMapper" >
<select id="selectUser" resultType="sample.entity.User" >
select * from USER where id =#{id}
</select>
</mapper>
Sqlの定義
パラメータや戻り値との
Mapping指定
MyBatis
MyBatis入門
Javaオブジェクト
MyBatis
MyBatis入門
Javaオブジェクト
public class User {
private Integer id;
private String name;
private String sex;
private Date created;
private String comment;
// Define setter and getter
}
public class Item {
private Integer id;
private String name;
// Define setter and getter
}
MyBatis
MyBatis入門
ユーザーコード
MyBatis
MyBatis入門
ユーザーコード
public class MapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws IOException {
String resource = "sample/context/sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test1() {
SqlSession session = sqlSessionFactory.openSession();
try {
User user = (User) session.selectOne("sample.mapper.UserMapper.selectUser", 1);
assertThat(user.getName(), is("小酒"));
} finally {
session.close();
}
}
}
MyBatis
MyBatis入門
ユーザーコード
public class MapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws IOException {
String resource = "sample/context/sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test1() {
SqlSession session = sqlSessionFactory.openSession();
try {
User user = (User) session.selectOne("sample.mapper.UserMapper.selectUser", 1);
assertThat(user.getName(), is("小酒"));
} finally {
session.close();
}
}
}
sqlMapConfigの設定から
sqlSessionFactoryを生成
通常システム起動時に行えばよい
MyBatis
MyBatis入門
ユーザーコード
public class MapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws IOException {
String resource = "sample/context/sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test1() {
SqlSession session = sqlSessionFactory.openSession();
try {
User user = (User) session.selectOne("sample.mapper.UserMapper.selectUser", 1);
assertThat(user.getName(), is("小酒"));
} finally {
session.close();
}
}
}
sqlSessionFactoryから
SqlSessionオブジェクトの生成
SqlSessionオブジェクトは
トランザクション制御から
Query実行、Mapper提供
などのAPIを提供する、
MyBatisの主要オブジェクト
MyBatis
MyBatis入門
ユーザーコード
@Test
public void test1() {
SqlSession session = sqlSessionFactory.openSession();
try {
User user = (User) session.selectOne("sample.mapper.UserMapper.selectUser", 1);
assertThat(user.getName(), is("小酒"));
} finally {
session.close();
}
}
}
<mapper namespace="sample.mapper.UserMapper" >
<select id="selectUser" resultType="sample.entity.User" >
select * from USER where id =#{id}
</select>
</mapper>
SqlMapで定義されたSQL
を呼び出し、オブジェクトに
Mappingした結果を受け取れる。
MyBatis
MyBatis入門
ユーザーコード
@Test
public void test2() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.selectUser(1);
assertThat(user.getName(), is("小酒"));
} finally {
session.close();
}
}
public interface UserMapper {
User selectUser(int id);
}
MyBatis
MyBatis入門
ユーザーコード
@Test
public void test2() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.selectUser(1);
assertThat(user.getName(), is("小酒"));
} finally {
session.close();
}
}
public interface UserMapper {
User selectUser(int id);
}
Javaインタフェースを定義して、
型安全にSql定義と紐付けることも可能。
内部ではProxyを用いて実現している。
MyBatis
MyBatis入門
ユーザーコード
@Test
public void test3() {
SqlSession session = sqlSessionFactory.openSession();
try {
ItemMapper itemMapper = session.getMapper(ItemMapper.class);
List<Item> items = itemMapper.selectByName("天空%");
assertThat(items.size(), is(2));
assertThat(items.get(0).getName(), is("天空の剣"));
assertThat(items.get(1).getName(), is("天空の鎧"));
} finally {
session.close();
}
}
public interface ItemMapper {
@Select("select * from ITEM where name like #{id} order by id")
List<Item> selectByName(String name);
}
MyBatis
MyBatis入門
ユーザーコード
@Test
public void test3() {
SqlSession session = sqlSessionFactory.openSession();
try {
ItemMapper itemMapper = session.getMapper(ItemMapper.class);
List<Item> items = itemMapper.selectByName("天空%");
assertThat(items.size(), is(2));
assertThat(items.get(0).getName(), is("天空の剣"));
assertThat(items.get(1).getName(), is("天空の鎧"));
} finally {
session.close();
}
}
public interface ItemMapper {
@Select("select * from ITEM where name like #{id} order by id")
List<Item> selectByName(String name);
}
アノーテーションを用いてSQLを定義
することも可能。
MyBatis
・MyBatisにはデータベースのスキーマ情報を元にソースを自動生成
 してくれるGeneratorがある。
・自動生成されるソースは次のとおり。
 ・Entityオブジェクト
 ・Mapper XML
 ・Mapperインタフェース
 ・Criteriaオブジェクト
https://github.com/mybatis/generator
自動生成
MyBatis入門
MyBatis
DB
MyBatis Generater
Mapper XML
Entityオブジェクト
Criteriaオブジェクト
Mapperインターフェース
自動生成設定(XMLファイル)
自動生成リソース
MyBatis入門
MyBatis
DB
MyBatis Generater
Mapper XML
Entityオブジェクト
Criteriaオブジェクト
Mapperインターフェース
自動生成設定(XMLファイル)
自動生成リソース
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="sample2" targetRuntime="MyBatis3">
<plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<jdbcConnection driverClass="org.h2.Driver"
connectionURL="jdbc:h2:tcp://localhost/C:MyFilesormdaoh2db;schema=hoge"
userId="ORM" password="orm">
</jdbcConnection>
<javaModelGenerator targetPackage="sample.entity"
targetProject="gen" />
<sqlMapGenerator targetPackage="sample.sql"
targetProject="gen" />
<javaClientGenerator targetPackage="sample.mapper"
targetProject="gen" type="XMLMAPPER" />
<table tableName="USER" />
<table tableName="ITEM" />
</context>
</generatorConfiguration>
MyBatis入門
MyBatis
DB
MyBatis Generater
Mapper XML
Entityオブジェクト
Criteriaオブジェクト
Mapperインターフェース
自動生成設定(XMLファイル)
自動生成リソース
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="sample2" targetRuntime="MyBatis3">
<plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<jdbcConnection driverClass="org.h2.Driver"
connectionURL="jdbc:h2:tcp://localhost/C:MyFilesormdaoh2db;schema=hoge"
userId="ORM" password="orm">
</jdbcConnection>
<javaModelGenerator targetPackage="sample.entity"
targetProject="gen" />
<sqlMapGenerator targetPackage="sample.sql"
targetProject="gen" />
<javaClientGenerator targetPackage="sample.mapper"
targetProject="gen" type="XMLMAPPER" />
<table tableName="USER" />
<table tableName="ITEM" />
</context>
</generatorConfiguration>
MyBatis入門
自動生成するためのスキーマ定義を提供する
Databaseへの接続定義
MyBatis
DB
MyBatis Generater
Mapper XML
Entityオブジェクト
Criteriaオブジェクト
Mapperインターフェース
自動生成設定(XMLファイル)
自動生成リソース
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="sample2" targetRuntime="MyBatis3">
<plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<jdbcConnection driverClass="org.h2.Driver"
connectionURL="jdbc:h2:tcp://localhost/C:MyFilesormdaoh2db;schema=hoge"
userId="ORM" password="orm">
</jdbcConnection>
<javaModelGenerator targetPackage="sample.entity"
targetProject="gen" />
<sqlMapGenerator targetPackage="sample.sql"
targetProject="gen" />
<javaClientGenerator targetPackage="sample.mapper"
targetProject="gen" type="XMLMAPPER" />
<table tableName="USER" />
<table tableName="ITEM" />
</context>
</generatorConfiguration>
MyBatis入門
生成リソースのpackageや生成フォルダ、
生成リソースの種類などを定義
MyBatis
DB
MyBatis Generater
Mapper XML
Entityオブジェクト
Criteriaオブジェクト
Mapperインターフェース
自動生成設定(XMLファイル)
自動生成リソース
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="sample2" targetRuntime="MyBatis3">
<plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<jdbcConnection driverClass="org.h2.Driver"
connectionURL="jdbc:h2:tcp://localhost/C:MyFilesormdaoh2db;schema=hoge"
userId="ORM" password="orm">
</jdbcConnection>
<javaModelGenerator targetPackage="sample.entity"
targetProject="gen" />
<sqlMapGenerator targetPackage="sample.sql"
targetProject="gen" />
<javaClientGenerator targetPackage="sample.mapper"
targetProject="gen" type="XMLMAPPER" />
<table tableName="USER" />
<table tableName="ITEM" />
</context>
</generatorConfiguration>
MyBatis入門
生成するテーブルやビューを指定
MyBatis
DB
MyBatis Generater
Mapper XML
Entityオブジェクト
Criteriaオブジェクト
Mapperインターフェース
自動生成設定(XMLファイル)
自動生成リソース
MyBatis入門
C:.
├─entity
│ Item.java
│ ItemExample.java
│ User.java
│ UserExample.java
│
├─mapper
│ ItemMapper.java
│ UserMapper.java
│
└─sql
ItemMapper.xml
UserMapper.xml
MyBatis
public class MapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws IOException {
String resource = "sample/context/sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test1() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.selectByPrimaryKey(1);
assertThat(user.getName(), is("小酒"));
assertThat(user.getComment(), is("こんにちは"));
} finally {
session.close();
}
}
}
MyBatis入門
MyBatis
public class MapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws IOException {
String resource = "sample/context/sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test1() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.selectByPrimaryKey(1);
assertThat(user.getName(), is("小酒"));
assertThat(user.getComment(), is("こんにちは"));
} finally {
session.close();
}
}
}
MyBatis入門
主キーによる検索メソッドが
自動生成されている。
MyBatis
@Test
public void test2() {
SqlSession session = sqlSessionFactory.openSession();
try {
ItemMapper itemMapper = session.getMapper(ItemMapper.class);
ItemExample itemEx = new ItemExample();
itemEx.createCriteria().andNameLike("天空%");
itemEx.or().andNameEqualTo("こんぼう");
itemEx.setOrderByClause("ID desc");
List<Item> items = itemMapper.selectByExample(itemEx);
assertThat(items.size(), is(3));
assertThat(items.get(0).getName(), is("天空の鎧"));
assertThat(items.get(1).getName(), is("天空の剣"));
assertThat(items.get(2).getName(), is("こんぼう"));
} finally {
session.close();
}
}
}
MyBatis入門
MyBatis
@Test
public void test2() {
SqlSession session = sqlSessionFactory.openSession();
try {
ItemMapper itemMapper = session.getMapper(ItemMapper.class);
ItemExample itemEx = new ItemExample();
itemEx.createCriteria().andNameLike("天空%");
itemEx.or().andNameEqualTo("こんぼう");
itemEx.setOrderByClause("ID desc");
List<Item> items = itemMapper.selectByExample(itemEx);
assertThat(items.size(), is(3));
assertThat(items.get(0).getName(), is("天空の鎧"));
assertThat(items.get(1).getName(), is("天空の剣"));
assertThat(items.get(2).getName(), is("こんぼう"));
} finally {
session.close();
}
}
}
MyBatis入門
Criteriaによる検索条件を指定可能。上記の例では
select * from ITEM
where name like '天空%' or name = 'こんぼう'
ordery by ID desc
のクエリーが発行されている。
MyBatis
@Test
public void test3() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
UserExample userEx = new UserExample();
userEx.createCriteria().andNameEqualTo("小酒");
List<User> users = userMapper.selectByExample(userEx);
assertThat(users.size(), is(1));
assertThat(users.get(0).getName(), is("小酒"));
assertThat(users.get(0).getComment(), is(nullValue()));
users = userMapper.selectByExampleWithBLOBs(userEx);
assertThat(users.get(0).getComment(), is("こんにちは"));
} finally {
session.close();
}
}
MyBatis入門
MyBatis
@Test
public void test3() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
UserExample userEx = new UserExample();
userEx.createCriteria().andNameEqualTo("小酒");
List<User> users = userMapper.selectByExample(userEx);
assertThat(users.size(), is(1));
assertThat(users.get(0).getName(), is("小酒"));
assertThat(users.get(0).getComment(), is(nullValue()));
users = userMapper.selectByExampleWithBLOBs(userEx);
assertThat(users.get(0).getComment(), is("こんにちは"));
} finally {
session.close();
}
}
MyBatis入門
テーブルにBlobやClobなどのLarge Object情報が
ある場合、BlobありとBlobなしの二種類の
検索方法が自動生成で用意される。
※性能的な理由によるものと思われる。
MyBatis
@Test
public void test4() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(3); user.setName("にゃんこ先生"); user.setSex("M"); user.setCreated(new java.util.Date());
userMapper.insert(user);
session.commit();
assertThat(userMapper.countByExample(new UserExample()), is(3));
  :
} finally {
session.close();
}
}
MyBatis入門
MyBatis
@Test
public void test4() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(3); user.setName("にゃんこ先生"); user.setSex("M"); user.setCreated(new java.util.Date());
userMapper.insert(user);
session.commit();
assertThat(userMapper.countByExample(new UserExample()), is(3));
  :
} finally {
session.close();
}
}
MyBatis入門
追加はinsertメソッドで
sessionオブジェクトのcommitメソッドおよび
rollbackメソッドでトランザクションを制御できる。
MyBatis
@Test
public void test4() {
SqlSession session = sqlSessionFactory.openSession();
try {
  :
user.setComment("にゃー!");
userMapper.updateByPrimaryKeyWithBLOBs(user);
session.commit();
user = userMapper.selectByPrimaryKey(3);
assertThat(user.getName(), is("にゃんこ先生"));
assertThat(user.getComment(), is("にゃー!"));
userMapper.deleteByPrimaryKey(3);
session.commit();
assertThat(userMapper.countByExample(new UserExample()), is(2));
} finally {
session.close();
}
}
MyBatis入門
MyBatis
@Test
public void test4() {
SqlSession session = sqlSessionFactory.openSession();
try {
  :
user.setComment("にゃー!");
userMapper.updateByPrimaryKeyWithBLOBs(user);
session.commit();
user = userMapper.selectByPrimaryKey(3);
assertThat(user.getName(), is("にゃんこ先生"));
assertThat(user.getComment(), is("にゃー!"));
userMapper.deleteByPrimaryKey(3);
session.commit();
assertThat(userMapper.countByExample(new UserExample()), is(2));
} finally {
session.close();
}
}
MyBatis入門
更新はupdateメソッドで
Blobあり/なしで二種類のメソッドが自動生成されている。
主キーを用いた更新や、Criteriaを用いた条件による更新が可能
MyBatis
@Test
public void test4() {
SqlSession session = sqlSessionFactory.openSession();
try {
  :
user.setComment("にゃー!");
userMapper.updateByPrimaryKeyWithBLOBs(user);
session.commit();
user = userMapper.selectByPrimaryKey(3);
assertThat(user.getName(), is("にゃんこ先生"));
assertThat(user.getComment(), is("にゃー!"));
userMapper.deleteByPrimaryKey(3);
session.commit();
assertThat(userMapper.countByExample(new UserExample()), is(2));
} finally {
session.close();
}
}
MyBatis入門
削除はdeleteメソッドで
主キーを用いた削除や、Criteriaを用いた条件による削除が可能
MyBatis
MyBatis入門
More infomation
・公式サイトの日本語情報が充実
・http://mybatis.github.io/mybatis-3/ja/
MyBatis
MyBatis #とは
MyBatis入門
MyBatisの活用事例
まとめ
AgendaAgenda
MyBatis
・MyBatisは多機能なO/Rマッパーなので、プロジェクトに応じて
 様々な使い方ができます。
MyBatisの活用事例
・ここでは、実際のプロジェクトでMyBatisを活用した際のいくつか
 の技術事例を紹介します。
MyBatis
Sessionを管理したい
・SqlSessionのAPIでMapperオブジェクトの取得や
 commit/rollbackを制御する。
・処理間(メソッド間)でSqlSessionの引き回しはしたくない。
MyBatisの活用事例
MyBatis
Sessionを管理したい
・SqlSessionのAPIでMapperオブジェクトの取得や
 commit/rollbackを制御する。
・処理間(メソッド間)でSqlSessionの引き回しはしたくない。
MyBatisの活用事例
・SqlSessionManagerを使うことでスレッド単位でSqlSession
 を管理できる。
MyBatis
Sessionを管理したい
MyBatisの活用事例
private static SqlSessionManager sessionManager;
@BeforeClass
public static void init() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("sample/context/MapperConfig.xml");
sessionManager = SqlSessionManager.newInstance(new SqlSessionFactoryBuilder().build(inputStream));
}
@Before
public void before() { sessionManager.startManagedSession(); }
@After
public void after() { sessionManager.close(); }
@Test
public void test() {
UserMapper userMapper = sessionManager.getMapper(UserMapper.class);
User user = new User();
user.setId(3); user.setName("にゃんこ先生"); user.setSex("M"); user.setCreated(new java.util.Date());
userMapper.insert(user);
sessionManager.rollback();
assertThat(userMapper.countByExample(new UserExample()), is(2));
}
MyBatis
Sessionを管理したい
MyBatisの活用事例
private static SqlSessionManager sessionManager;
@BeforeClass
public static void init() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("sample/context/MapperConfig.xml");
sessionManager = SqlSessionManager.newInstance(new SqlSessionFactoryBuilder().build(inputStream));
}
@Before
public void before() { sessionManager.startManagedSession(); }
@After
public void after() { sessionManager.close(); }
@Test
public void test() {
UserMapper userMapper = sessionManager.getMapper(UserMapper.class);
User user = new User();
user.setId(3); user.setName("にゃんこ先生"); user.setSex("M"); user.setCreated(new java.util.Date());
userMapper.insert(user);
sessionManager.rollback();
assertThat(userMapper.countByExample(new UserExample()), is(2));
}
SqlSessionFactoryからSqlSessionManagerを生成
通常、システム起動時に一度だけ生成すればいい。
MyBatis
Sessionを管理したい
MyBatisの活用事例
private static SqlSessionManager sessionManager;
@BeforeClass
public static void init() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("sample/context/MapperConfig.xml");
sessionManager = SqlSessionManager.newInstance(new SqlSessionFactoryBuilder().build(inputStream));
}
@Before
public void before() { sessionManager.startManagedSession(); }
@After
public void after() { sessionManager.close(); }
@Test
public void test() {
UserMapper userMapper = sessionManager.getMapper(UserMapper.class);
User user = new User();
user.setId(3); user.setName("にゃんこ先生"); user.setSex("M"); user.setCreated(new java.util.Date());
userMapper.insert(user);
sessionManager.rollback();
assertThat(userMapper.countByExample(new UserExample()), is(2));
}
startManagedSessionメソッドの呼び出しで
内部的にSqlSessionインスタンスが生成され、
スレッドローカル変数で管理される。
MyBatis
Sessionを管理したい
MyBatisの活用事例
private static SqlSessionManager sessionManager;
@BeforeClass
public static void init() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("sample/context/MapperConfig.xml");
sessionManager = SqlSessionManager.newInstance(new SqlSessionFactoryBuilder().build(inputStream));
}
@Before
public void before() { sessionManager.startManagedSession(); }
@After
public void after() { sessionManager.close(); }
@Test
public void test() {
UserMapper userMapper = sessionManager.getMapper(UserMapper.class);
User user = new User();
user.setId(3); user.setName("にゃんこ先生"); user.setSex("M"); user.setCreated(new java.util.Date());
userMapper.insert(user);
sessionManager.rollback();
assertThat(userMapper.countByExample(new UserExample()), is(2));
}
SqlSessionManagerはSqlSessionインタフェースを
実装しているので、SqlSessionと同様のAPIを
提供。
MyBatis
文字化けに対処したい
・有名な「~」の文字化け
・MS932とSJISのUnicodeのマッピングの違いによって生じる。
MyBatisの活用事例
MyBatis
文字化けに対処したい
・有名な「~」の文字化け
・MS932とSJISのUnicodeのマッピングの違いによって生じる。
MyBatisの活用事例
・typeHandlerでUnicodeの文字変換を行うことで解決!
MyBatis
文字化けに対処したい
MyBatisの活用事例
<?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 >
:
<typeHandlers>
<typeHandler javaType="String" jdbcType="VARCHAR" handler="hogedriven.StringTypeHandler"/>
<typeHandler javaType="String" jdbcType="CHAR" handler="hogedriven.StringTypeHandler"/>
</typeHandlers>
:
</configuration>
MyBatis
文字化けに対処したい
MyBatisの活用事例
public final class StringTypeHandler extends BaseTypeHandler<String> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, convertTo(parameter));
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return convertTo(rs.getString(columnName));
}
:
private static final String convertTo(String str) {
StringBuffer result = new StringBuffer();
char c;
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
switch (c) {
// WAVE DASH(~)
case 0x301c:
c = 0xff5e;
break;
default:
break;
}
result.append(c);
}
return result.toString();
}
}
MyBatis
文字化けに対処したい
MyBatisの活用事例
public final class StringTypeHandler extends BaseTypeHandler<String> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, convertTo(parameter));
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return convertTo(rs.getString(columnName));
}
:
private static final String convertTo(String str) {
StringBuffer result = new StringBuffer();
char c;
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
switch (c) {
// WAVE DASH(~)
case 0x301c:
c = 0xff5e;
break;
default:
break;
}
result.append(c);
}
return result.toString();
}
}
DBからのread/writeのタイミングで、それぞれの
文字エンコーダに応じてUnicodeの文字コードを
変更してやればいい。
MyBatis
違うスキーマから自動生成したい
・自動生成ソースを作成するデータベースの参照スキーマを
 実行環境とは別のものにしたい。
MyBatisの活用事例
DB
MyBatis Generater
Mapper XML
Entityオブジェクト
Criteriaオブジェクト
Mapperインターフェース
自動生成リソース
DB
自動生成用スキーマ
実行用スキーマ
MyBatis
違うスキーマから自動生成したい
・自動生成ソースを作成するデータベースの参照スキーマを
 実行環境とは別のものにしたい。
MyBatisの活用事例
・自動生成設定のtableタグにschema属性を指定する。
・それだけだと、生成されたSQLが指定されたschemaを指定
 したクエリとなるので、
  <property name="ignoreQualifiersAtRuntime" value="true"/>
 を指定する。
MyBatis
違うスキーマから自動生成したい
MyBatisの活用事例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="sample2" targetRuntime="MyBatis3">
:
<table schema="orm" tableName="USER" >
<property name="ignoreQualifiersAtRuntime" value="true"/>
</table>
<table schema="orm" tableName="ITEM" >
<property name="ignoreQualifiersAtRuntime" value="true"/>
</table>
:
</context>
</generatorConfiguration>
MyBatis
MyBatisの活用事例
楽したい
・自動生成されたソースの検索APIが手続き型のAPI
 (コマンドクエリーAPI)で使いにくい
・自動生成されたソースはDAOのため、Entityに
 ビジネスロジックを書きたくないし、そもそも自動生成ソース
 を修正したくない。
・テーブルのメタデータだけでなく、SQLからも自動生成したい。
・てか、モデル層がないとコントローラ層にビジネスロジック
 ががが
MyBatis
MyBatisの活用事例
楽したい
・GeneratorのPluginでσ(゚∀゚)オレオレPlugin を実装!
・GeneratorはPluginを用いて自動生成ソースを追加/拡張できる!
・自動生成されたソースの検索APIが手続き型のAPI
 (コマンドクエリーAPI)で使いにくい
・自動生成されたソースはDAOのため、Entityに
 ビジネスロジックを書きたくないし、そもそも自動生成ソース
 を修正したくない。
・テーブルのメタデータだけでなく、SQLからも自動生成したい。
・てか、モデル層がないとコントローラ層にビジネスロジック
 ががが
MyBatis
MyBatisの活用事例
楽したい
DB
MyBatis Generater
+
σ(゚∀゚)オレオレPlugin Mapper XML
Entityオブジェクト
Criteriaオブジェクト
Mapperインターフェース
Modelオブジェクト
Queryオブジェクト
自動生成リソース
SQL
MapConfig XML
NEW
NEW
NEW
MyBatis
MyBatisの活用事例
自動生成クラス
Pluginで生成した
クラス
モデルクラス
自動生成ソースは修正しない!
楽したい
MyBatis
MyBatisの活用事例
楽したい
UserBelongItemsMapper.xml
User2itemq1.java
User2itemq1Example.java
User2itemq1Mapper.java
User2itemq1MoBase.java
User2itemq1Query.java
User2ItemQ1.sql
MapperConfig.xml
select user.*, item.id as item_id, item.name as item_name from USER user
join USER_BELONG_ITEMS blng on user.id = blng.user_id
join ITEM item on blng.item_id = item.id
MyBatis
MyBatisの活用事例
楽したい
UserBelongItemsMapper.xml
User2itemq1.java
User2itemq1Example.java
User2itemq1Mapper.java
User2itemq1MoBase.java
User2itemq1Query.java
User2ItemQ1.sql
MapperConfig.xml
select user.*, item.id as item_id, item.name as item_name from USER user
join USER_BELONG_ITEMS blng on user.id = blng.user_id
join ITEM item on blng.item_id = item.id
テーブルの結合条件を指定したSQLを指定
Viewを生成するイメージ
このSQLをPluginから実行し、ResultSetのメタ情報より
各種リソースを自動生成する。
MyBatis
MyBatisの活用事例
楽したい
UserBelongItemsMapper.xml
User2itemq1.java
User2itemq1Example.java
User2itemq1Mapper.java
User2itemq1MoBase.java
User2itemq1Query.java
User2ItemQ1.sql
MapperConfig.xml
:
<select id="selectByExample" resultMap="BaseResultMap"
parameterType="hogedriven.sample.dao.orm.entity.User2itemq1Example" >
select
<if test="distinct" >
distinct
</if>
<include refid="Base_Column_List" />
from (select user.*, item.id as item_id, item.name as item_name from USER user
join USER_BELONG_ITEMS blng on user.id = blng.user_id
join ITEM item on blng.item_id = item.id) User2ItemQ1
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null" >
order by ${orderByClause}
</if>
</select>
:
MyBatis
MyBatisの活用事例
楽したい
UserBelongItemsMapper.xml
User2itemq1.java
User2itemq1Example.java
User2itemq1Mapper.java
User2itemq1MoBase.java
User2itemq1Query.java
User2ItemQ1.sql
MapperConfig.xml
:
<select id="selectByExample" resultMap="BaseResultMap"
parameterType="hogedriven.sample.dao.orm.entity.User2itemq1Example" >
select
<if test="distinct" >
distinct
</if>
<include refid="Base_Column_List" />
from (select user.*, item.id as item_id, item.name as item_name from USER user
join USER_BELONG_ITEMS blng on user.id = blng.user_id
join ITEM item on blng.item_id = item.id) User2ItemQ1
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null" >
order by ${orderByClause}
</if>
</select>
:
副問い合わせによるSQLが生成された
MyBatis
MyBatisの活用事例
楽したい
<generatorConfiguration>
<context id="sample2" targetRuntime="MyBatis3">
:
<plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.queryby.SelectByPlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.queryby.UpdateByPlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.queryby.DeleteByPlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.queryby.CountByPlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.selectforupdate.SelectForUpdatePlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.custommapper.CustomMapperPlugin">
<property name="targetProject" value="sql/orm" />
</plugin>
<plugin type="hogedriven.mybatis.generator.plugins.model.ModelPlugin">
<property name="targetModelPackage" value="hogedriven.sample.app.model.orm" />
<property name="targetModelBasePackage" value="hogedriven.sample.dao.orm.model" />
<property name="targetQueryPackage" value="hogedriven.sample.dao.orm.query" />
<property name="targetModelProject" value="src_wrk/model" />
<property name="targetModelBaseProject" value="src_gen" />
<property name="targetQueryProject" value="src_gen" />
</plugin>
:
</context>
</generatorConfiguration>
MyBatis
MyBatisの活用事例
楽したい
<generatorConfiguration>
<context id="sample2" targetRuntime="MyBatis3">
:
<plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.queryby.SelectByPlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.queryby.UpdateByPlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.queryby.DeleteByPlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.queryby.CountByPlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.selectforupdate.SelectForUpdatePlugin" />
<plugin type="hogedriven.mybatis.generator.plugins.custommapper.CustomMapperPlugin">
<property name="targetProject" value="sql/orm" />
</plugin>
<plugin type="hogedriven.mybatis.generator.plugins.model.ModelPlugin">
<property name="targetModelPackage" value="hogedriven.sample.app.model.orm" />
<property name="targetModelBasePackage" value="hogedriven.sample.dao.orm.model" />
<property name="targetQueryPackage" value="hogedriven.sample.dao.orm.query" />
<property name="targetModelProject" value="src_wrk/model" />
<property name="targetModelBaseProject" value="src_gen" />
<property name="targetQueryProject" value="src_gen" />
</plugin>
:
</context>
</generatorConfiguration>
それぞれの用途に応じて作成したPlugin達
MyBatis
MyBatisの活用事例
楽したい
public class SampleTest {
@BeforeClass
public static void init() throws Exception { SqlContextManager.init("test"); }
@Before
public void before() { SqlContextManager.getContext("orm").beginTransaction(); }
@After
public void after() { SqlContextManager.getContext("orm").endTransaction(); }
@Test
public void test() {
UserMo userMo = UserMo.where().idEqualTo(1).fetchFirst(UserMo.class);
assertThat(userMo, is(notNullValue()));
assertThat(userMo.getName(), is("小酒"));
userMo.setName("こざけ");
userMo.saveSelective();
userMo.remove();
SqlContextManager.getContext("orm").rollback();
}
:
MyBatis
MyBatisの活用事例
楽したい
public class SampleTest {
@BeforeClass
public static void init() throws Exception { SqlContextManager.init("test"); }
@Before
public void before() { SqlContextManager.getContext("orm").beginTransaction(); }
@After
public void after() { SqlContextManager.getContext("orm").endTransaction(); }
@Test
public void test() {
UserMo userMo = UserMo.where().idEqualTo(1).fetchFirst(UserMo.class);
assertThat(userMo, is(notNullValue()));
assertThat(userMo.getName(), is("小酒"));
userMo.setName("こざけ");
userMo.saveSelective();
userMo.remove();
SqlContextManager.getContext("orm").rollback();
}
:
Pluginを用いて生成したモデルによる検索
流れるようなメソッドチェーンでSimpleに
かける!
MyBatis
MyBatisの活用事例
Demo
エル 知ってるか? Demoは大抵成功しない。
MyBatis
MyBatis #とは
MyBatis入門
MyBatisの活用事例
まとめ
AgendaAgenda
MyBatis
楽じゃなかった
Plugin作り過ぎたorz 。今は反省している・・
MyBatis
質問があれば

More Related Content

What's hot

Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
NTT DATA Technology & Innovation
 
Infrastructure as Code (IaC) 談義 2022
Infrastructure as Code (IaC) 談義 2022Infrastructure as Code (IaC) 談義 2022
Infrastructure as Code (IaC) 談義 2022
Amazon Web Services Japan
 
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
 
ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方
増田 亨
 
楽天における大規模データベースの運用
楽天における大規模データベースの運用楽天における大規模データベースの運用
楽天における大規模データベースの運用
Rakuten Group, Inc.
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティス
Akihiro Kuwano
 
クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計
Kouji YAMADA
 
事例で学ぶApache Cassandra
事例で学ぶApache Cassandra事例で学ぶApache Cassandra
事例で学ぶApache Cassandra
Yuki Morishita
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol Buffers
Seiya Mizuno
 
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
Shohei Koyama
 
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
Amazon Web Services Japan
 
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
Junji Nishihara
 
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
Trainocate Japan, Ltd.
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
mosa siru
 
SQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかSQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するか
Shogo Wakayama
 
Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...
Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...
Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...
Preferred Networks
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
Takuto Wada
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)
Yoshitaka Kawashima
 
AWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design Pattern
AWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design PatternAWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design Pattern
AWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design Pattern
Amazon Web Services Japan
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのこと
Amazon Web Services Japan
 

What's hot (20)

Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
 
Infrastructure as Code (IaC) 談義 2022
Infrastructure as Code (IaC) 談義 2022Infrastructure as Code (IaC) 談義 2022
Infrastructure as Code (IaC) 談義 2022
 
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
 
ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方
 
楽天における大規模データベースの運用
楽天における大規模データベースの運用楽天における大規模データベースの運用
楽天における大規模データベースの運用
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティス
 
クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計
 
事例で学ぶApache Cassandra
事例で学ぶApache Cassandra事例で学ぶApache Cassandra
事例で学ぶApache Cassandra
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol Buffers
 
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
 
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
 
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
 
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
SQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかSQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するか
 
Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...
Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...
Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)
 
AWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design Pattern
AWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design PatternAWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design Pattern
AWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design Pattern
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのこと
 

Similar to システムアーキテクト~My batis編~

jjugccc2018 app review postmortem
jjugccc2018 app review postmortemjjugccc2018 app review postmortem
jjugccc2018 app review postmortem
tamtam180
 
Android cleanarchitecture
Android cleanarchitectureAndroid cleanarchitecture
Android cleanarchitecture
Tomoaki Imai
 
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolateskoichik
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
takezoe
 
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみようWebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
mganeko
 
20101018 JJUG CCC10 WindowsAzure
20101018 JJUG CCC10 WindowsAzure20101018 JJUG CCC10 WindowsAzure
20101018 JJUG CCC10 WindowsAzure
Shinichiro Isago
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
normalian
 
Ajax basic
Ajax basicAjax basic
Ajax basic
Katsuyuki Seino
 
Nginx
NginxNginx
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Shotaro Suzuki
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
Yatabe Terumasa
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/Androidセキュアコーディング
Masaki Kubo
 
実践 NestJS
実践 NestJS実践 NestJS
実践 NestJS
Ayumi Goto
 
アドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングアドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニング
Yosuke Mizutani
 
JPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発TipsJPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発Tips
yuichi_kuwahara
 
Akkaの並行性
Akkaの並行性Akkaの並行性
Akkaの並行性
TIS Inc.
 
Implements OpenTelemetry Collector in DotNet
Implements OpenTelemetry Collector in DotNetImplements OpenTelemetry Collector in DotNet
Implements OpenTelemetry Collector in DotNet
Yoshifumi Kawai
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
tako pons
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義JPCERT Coordination Center
 

Similar to システムアーキテクト~My batis編~ (20)

jjugccc2018 app review postmortem
jjugccc2018 app review postmortemjjugccc2018 app review postmortem
jjugccc2018 app review postmortem
 
Android cleanarchitecture
Android cleanarchitectureAndroid cleanarchitecture
Android cleanarchitecture
 
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
 
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみようWebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
 
20101018 JJUG CCC10 WindowsAzure
20101018 JJUG CCC10 WindowsAzure20101018 JJUG CCC10 WindowsAzure
20101018 JJUG CCC10 WindowsAzure
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 
Ajax basic
Ajax basicAjax basic
Ajax basic
 
Nginx
NginxNginx
Nginx
 
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/Androidセキュアコーディング
 
実践 NestJS
実践 NestJS実践 NestJS
実践 NestJS
 
アドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングアドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニング
 
Ajax 応用
Ajax 応用Ajax 応用
Ajax 応用
 
JPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発TipsJPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発Tips
 
Akkaの並行性
Akkaの並行性Akkaの並行性
Akkaの並行性
 
Implements OpenTelemetry Collector in DotNet
Implements OpenTelemetry Collector in DotNetImplements OpenTelemetry Collector in DotNet
Implements OpenTelemetry Collector in DotNet
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義
 

More from Shinichi Kozake

SIerアーキテクト視点でみたKotlinの紹介
SIerアーキテクト視点でみたKotlinの紹介SIerアーキテクト視点でみたKotlinの紹介
SIerアーキテクト視点でみたKotlinの紹介
Shinichi Kozake
 
あなたとAndroid!?今すぐダウンロード
あなたとAndroid!?今すぐダウンロードあなたとAndroid!?今すぐダウンロード
あなたとAndroid!?今すぐダウンロード
Shinichi Kozake
 
Kotlinで関数拡張しちゃうぞ![修正版]
Kotlinで関数拡張しちゃうぞ![修正版]Kotlinで関数拡張しちゃうぞ![修正版]
Kotlinで関数拡張しちゃうぞ![修正版]
Shinichi Kozake
 
とある現場のシステムアーキテクチャ
とある現場のシステムアーキテクチャとある現場のシステムアーキテクチャ
とある現場のシステムアーキテクチャ
Shinichi Kozake
 
関ジャバの間においでよ!
関ジャバの間においでよ!関ジャバの間においでよ!
関ジャバの間においでよ!
Shinichi Kozake
 
あなたとAndroid 今すぐダウンロード!? Android開発で変わる SIerのJava技術事情について
あなたとAndroid 今すぐダウンロード!? Android開発で変わる SIerのJava技術事情についてあなたとAndroid 今すぐダウンロード!? Android開発で変わる SIerのJava技術事情について
あなたとAndroid 今すぐダウンロード!? Android開発で変わる SIerのJava技術事情について
Shinichi Kozake
 
Web API Design for JAX-RS
Web API Design for JAX-RSWeb API Design for JAX-RS
Web API Design for JAX-RS
Shinichi Kozake
 
ゆるふわアーキを支える技術
ゆるふわアーキを支える技術ゆるふわアーキを支える技術
ゆるふわアーキを支える技術
Shinichi Kozake
 
Nullなのはいけないと思います!
Nullなのはいけないと思います!Nullなのはいけないと思います!
Nullなのはいけないと思います!
Shinichi Kozake
 
生きろ!チーム開発! 300人月の仲間はみな死んだ
生きろ!チーム開発! 300人月の仲間はみな死んだ生きろ!チーム開発! 300人月の仲間はみな死んだ
生きろ!チーム開発! 300人月の仲間はみな死んだ
Shinichi Kozake
 
Play!30分クッキング
Play!30分クッキングPlay!30分クッキング
Play!30分クッキング
Shinichi Kozake
 
システムアーキテクト
システムアーキテクトシステムアーキテクト
システムアーキテクト
Shinichi Kozake
 
Xtend30分クッキング やきに駆動
Xtend30分クッキング   やきに駆動Xtend30分クッキング   やきに駆動
Xtend30分クッキング やきに駆動
Shinichi Kozake
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
Shinichi Kozake
 
Xtend30分クッキング
Xtend30分クッキングXtend30分クッキング
Xtend30分クッキング
Shinichi Kozake
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
Shinichi Kozake
 
鹿駆動
鹿駆動鹿駆動
鹿駆動
Shinichi Kozake
 
MyBatisで流れるようなメソッドチェーン
MyBatisで流れるようなメソッドチェーンMyBatisで流れるようなメソッドチェーン
MyBatisで流れるようなメソッドチェーンShinichi Kozake
 
play framework 勉強会 in 関西
play framework 勉強会 in 関西play framework 勉強会 in 関西
play framework 勉強会 in 関西
Shinichi Kozake
 

More from Shinichi Kozake (20)

SIerアーキテクト視点でみたKotlinの紹介
SIerアーキテクト視点でみたKotlinの紹介SIerアーキテクト視点でみたKotlinの紹介
SIerアーキテクト視点でみたKotlinの紹介
 
あなたとAndroid!?今すぐダウンロード
あなたとAndroid!?今すぐダウンロードあなたとAndroid!?今すぐダウンロード
あなたとAndroid!?今すぐダウンロード
 
Kotlinで関数拡張しちゃうぞ![修正版]
Kotlinで関数拡張しちゃうぞ![修正版]Kotlinで関数拡張しちゃうぞ![修正版]
Kotlinで関数拡張しちゃうぞ![修正版]
 
とある現場のシステムアーキテクチャ
とある現場のシステムアーキテクチャとある現場のシステムアーキテクチャ
とある現場のシステムアーキテクチャ
 
関ジャバの間においでよ!
関ジャバの間においでよ!関ジャバの間においでよ!
関ジャバの間においでよ!
 
あなたとAndroid 今すぐダウンロード!? Android開発で変わる SIerのJava技術事情について
あなたとAndroid 今すぐダウンロード!? Android開発で変わる SIerのJava技術事情についてあなたとAndroid 今すぐダウンロード!? Android開発で変わる SIerのJava技術事情について
あなたとAndroid 今すぐダウンロード!? Android開発で変わる SIerのJava技術事情について
 
Web API Design for JAX-RS
Web API Design for JAX-RSWeb API Design for JAX-RS
Web API Design for JAX-RS
 
ゆるふわアーキを支える技術
ゆるふわアーキを支える技術ゆるふわアーキを支える技術
ゆるふわアーキを支える技術
 
Nullなのはいけないと思います!
Nullなのはいけないと思います!Nullなのはいけないと思います!
Nullなのはいけないと思います!
 
生きろ!チーム開発! 300人月の仲間はみな死んだ
生きろ!チーム開発! 300人月の仲間はみな死んだ生きろ!チーム開発! 300人月の仲間はみな死んだ
生きろ!チーム開発! 300人月の仲間はみな死んだ
 
Play!30分クッキング
Play!30分クッキングPlay!30分クッキング
Play!30分クッキング
 
システムアーキテクト
システムアーキテクトシステムアーキテクト
システムアーキテクト
 
Xtend30分クッキング やきに駆動
Xtend30分クッキング   やきに駆動Xtend30分クッキング   やきに駆動
Xtend30分クッキング やきに駆動
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
 
Xtend30分クッキング
Xtend30分クッキングXtend30分クッキング
Xtend30分クッキング
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
鹿駆動
鹿駆動鹿駆動
鹿駆動
 
MyBatisで流れるようなメソッドチェーン
MyBatisで流れるようなメソッドチェーンMyBatisで流れるようなメソッドチェーン
MyBatisで流れるようなメソッドチェーン
 
About Jobs
About JobsAbout Jobs
About Jobs
 
play framework 勉強会 in 関西
play framework 勉強会 in 関西play framework 勉強会 in 関西
play framework 勉強会 in 関西
 

システムアーキテクト~My batis編~