SlideShare ist ein Scribd-Unternehmen logo
1 von 106
Downloaden Sie, um offline zu lesen
本日のお話
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
質問があれば

Weitere ähnliche Inhalte

Was ist angesagt?

Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話JustSystems Corporation
 
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性Ohyama Masanori
 
AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料)
AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料)AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料)
AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料)NTT DATA Technology & Innovation
 
Amazon Aurora - Auroraの止まらない進化とその中身
Amazon Aurora - Auroraの止まらない進化とその中身Amazon Aurora - Auroraの止まらない進化とその中身
Amazon Aurora - Auroraの止まらない進化とその中身Amazon Web Services Japan
 
マイクロサービスにおける 結果整合性との戦い
マイクロサービスにおける 結果整合性との戦いマイクロサービスにおける 結果整合性との戦い
マイクロサービスにおける 結果整合性との戦いota42y
 
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
今こそ知りたいSpring Web(Spring Fest 2020講演資料)今こそ知りたいSpring Web(Spring Fest 2020講演資料)
今こそ知りたいSpring Web(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!mosa siru
 
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~Masahito Zembutsu
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことAmazon Web Services Japan
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンKentaro Yoshida
 
20190828 AWS Black Belt Online Seminar Amazon Aurora with PostgreSQL Compatib...
20190828 AWS Black Belt Online Seminar Amazon Aurora with PostgreSQL Compatib...20190828 AWS Black Belt Online Seminar Amazon Aurora with PostgreSQL Compatib...
20190828 AWS Black Belt Online Seminar Amazon Aurora with PostgreSQL Compatib...Amazon Web Services Japan
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
Java EE から Quarkus による開発への移行について
Java EE から Quarkus による開発への移行についてJava EE から Quarkus による開発への移行について
Java EE から Quarkus による開発への移行についてShigeru Tatsuta
 
AWS Black Belt Online Seminar AWS Direct Connect
AWS Black Belt Online Seminar AWS Direct ConnectAWS Black Belt Online Seminar AWS Direct Connect
AWS Black Belt Online Seminar AWS Direct ConnectAmazon Web Services Japan
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAkihiro Kuwano
 
SaaS テナント毎のコストを把握するための「AWS Application Cost Profiler」のご紹介
SaaS テナント毎のコストを把握するための「AWS Application Cost Profiler」のご紹介SaaS テナント毎のコストを把握するための「AWS Application Cost Profiler」のご紹介
SaaS テナント毎のコストを把握するための「AWS Application Cost Profiler」のご紹介Amazon Web Services Japan
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーToru Makabe
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説増田 亨
 
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)Koichiro Matsuoka
 

Was ist angesagt? (20)

Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
 
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
 
AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料)
AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料)AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料)
AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料)
 
Amazon Aurora - Auroraの止まらない進化とその中身
Amazon Aurora - Auroraの止まらない進化とその中身Amazon Aurora - Auroraの止まらない進化とその中身
Amazon Aurora - Auroraの止まらない進化とその中身
 
マイクロサービスにおける 結果整合性との戦い
マイクロサービスにおける 結果整合性との戦いマイクロサービスにおける 結果整合性との戦い
マイクロサービスにおける 結果整合性との戦い
 
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
今こそ知りたいSpring Web(Spring Fest 2020講演資料)今こそ知りたいSpring Web(Spring Fest 2020講演資料)
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのこと
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターン
 
20190828 AWS Black Belt Online Seminar Amazon Aurora with PostgreSQL Compatib...
20190828 AWS Black Belt Online Seminar Amazon Aurora with PostgreSQL Compatib...20190828 AWS Black Belt Online Seminar Amazon Aurora with PostgreSQL Compatib...
20190828 AWS Black Belt Online Seminar Amazon Aurora with PostgreSQL Compatib...
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Java EE から Quarkus による開発への移行について
Java EE から Quarkus による開発への移行についてJava EE から Quarkus による開発への移行について
Java EE から Quarkus による開発への移行について
 
AWS Black Belt Online Seminar AWS Direct Connect
AWS Black Belt Online Seminar AWS Direct ConnectAWS Black Belt Online Seminar AWS Direct Connect
AWS Black Belt Online Seminar AWS Direct Connect
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティス
 
SaaS テナント毎のコストを把握するための「AWS Application Cost Profiler」のご紹介
SaaS テナント毎のコストを把握するための「AWS Application Cost Profiler」のご紹介SaaS テナント毎のコストを把握するための「AWS Application Cost Profiler」のご紹介
SaaS テナント毎のコストを把握するための「AWS Application Cost Profiler」のご紹介
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説
 
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 

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

jjugccc2018 app review postmortem
jjugccc2018 app review postmortemjjugccc2018 app review postmortem
jjugccc2018 app review postmortemtamtam180
 
Android cleanarchitecture
Android cleanarchitectureAndroid cleanarchitecture
Android cleanarchitectureTomoaki 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 WindowsAzureShinichiro Isago
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~normalian
 
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
 
アドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングアドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングYosuke Mizutani
 
JPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発TipsJPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発Tipsyuichi_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 DotNetYoshifumi Kawai
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義JPCERT Coordination Center
 

Ähnlich wie システムアーキテクト~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回講義
 

Mehr von 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-RSShinichi 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
 
MyBatisで流れるようなメソッドチェーン
MyBatisで流れるようなメソッドチェーンMyBatisで流れるようなメソッドチェーン
MyBatisで流れるようなメソッドチェーンShinichi Kozake
 
play framework 勉強会 in 関西
play framework 勉強会 in 関西play framework 勉強会 in 関西
play framework 勉強会 in 関西Shinichi Kozake
 

Mehr von 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編~