1. MyBatisのクイックスタート
要件:MyBatisを使用してすべてのユーザーデータを取得する。
1) Spring Bootプロジェクトを作成し、MyBatisの依存関係、MySQLドライバ、Lombokを追加する。
プロジェクト作成後、pom.xmlファイルに自動的にMyBatisとMySQLドライバの依存関係が追加されます。
2) データ準備:ユーザーテーブル(user)を作成し、対応するエンティティクラスUserを作成する。
- ユーザーテーブル user(既に存在すれば作成不要)
CREATE TABLE user (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT 'ID, 主キー',
username VARCHAR(20) COMMENT 'ユーザー名',
password VARCHAR(32) COMMENT 'パスワード',
name VARCHAR(10) COMMENT '名前',
age TINYINT UNSIGNED COMMENT '年齢'
) COMMENT 'ユーザーテーブル';
INSERT INTO user(id, username, password, name, age) VALUES (1, 'daqiao', '123456', '大喬', 22),
(2, 'xiaoqiao', '123456', '小喬', 18),
(3, 'diaochan', '123456', '貂蝉', 24),
(4, 'lvbu', '123456', '吕布', 28),
(5, 'zhaoyun', '12345678', '趙雲', 27);
- エンティティクラス:エンティティクラスのプロパティ名はテーブルのフィールド名に対応します。エンティティクラスは`com.example.entity`パッケージに配置します。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id; // ID
private String username; // ユーザー名
private String password; // パスワード
private String name; // 名前
private Integer age; // 年齢
}
3) MyBatisの設定
`application.properties`でデータベース接続情報を設定します。
# データベースアクセスのURL
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
# データベースドライバクラス名
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# データベースアクセス-ユーザー名
spring.datasource.username=root
# データベースアクセス-パスワード
spring.datasource.password=root@1234
4) MyBatisプログラムの作成:MyBatisの永続層インターフェースを作成し、SQL文を定義する(アノテーションを使用)
作成したSpring Bootプロジェクト内で、ガイドクラスと同じパッケージ(`com.example`)に`mapper`パッケージを作成し、その中に`UserRepository`インターフェースを作成します。
import com.example.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserRepository {
/**
* すべて取得
*/
@Select("SELECT * FROM user")
List<User> fetchAllUsers();
}
- @Mapperアノテーション:これはMyBatisのMapperインターフェースであることを示します。
- @Selectアノテーション:これはSELECTクエリを表し、SELECTクエリ文を記述するために使用します。
5) ユニットテスト
作成したSpring Bootプロジェクト内で、src/testディレクトリに自動的にテストクラスが作成されています。また、このテストクラスにはすでに`@SpringBootTest`アノテーションが付与されており、Spring Bootと統合されていることを示しています。
@SpringBootTest
class MybatisDemoApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
public void testFetchAllUsers() {
List<User> users = userRepository.fetchAllUsers();
for (User user : users) {
System.out.println(user);
}
}
}
テストクラスは、ガイドクラスを介してSpring環境をロードします。テストしたいBeanオブジェクトがあれば、`@Autowired`アノテーションを使用して注入し、テストを行います。
2. 補足設定
2-1) SQLヒントの設定
デフォルトでは、`@Select`アノテーションでSQL文を書くとヒントが表示されません。IDEAでSQL文のヒントを得るには、IDEAでMySQLデータベースへのリンクを設定する必要があります。
設定を完了すると、SQLキーワードにヒントが表示されるようになりますが、まだテーブル名やカラム名が認識されない場合があります。
- 原因:IDEAとデータベースが接続されていないため、テーブル情報が認識されない
- 解決策:IDEAでMySQLデータベースへの接続を設定する
2-2) MyBatisログ出力の設定
デフォルトでは、MyBatisでSQL文が実行されたときにログが出力されません。`application.properties`に以下の設定を追加することで、ログを見ることができます。
# MyBatisの設定
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
この設定を有効にすると、ユニットテストを実行した際に、コンソールに実行されたSQL文が出力されます。
3. データベース接続プール
3-1) はじめに
- データベース接続プールがない場合
クライアントがSQL文を実行するには、新しいコネクションオブジェクトを作成し、SQLを実行した後、コネクションオブジェクトを閉じてリソースを解放する必要があります。これにより、頻繁なコネクションの作成と破棄が行われ、システムのパフォーマンスに影響を与えます。
- データベース接続プールがある場合
データベース接続プールは、コネクションオブジェクトを管理するためのコンテナです。
- アプリケーションが起動時に、データベース接続プール(コンテナ)内に指定数のコネクションオブジェクトを作成します。
- クライアントがSQLを実行する前に、データベース接続プールからコネクションオブジェクトを取得し、SQLを実行します。実行が完了したら、コネクションオブジェクトをプールに戻すことができます。
- 空き時間が最大空き時間を超えたコネクションオブジェクトは自動的に解放され、リソースの浪費を防ぎます。
データベース接続プールの利点:
- リソースの再利用
- システムレスポンスタイムの向上
- データベース接続の漏れ防止
デフォルトのデータベース接続プールをDruidに切り替えるには、以下の手順を実施します:
- pom.xmlファイルに依存関係を追加します。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.19</version>
</dependency>
- application.propertiesにデータベース接続設定を追加します。
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
設定を完了すると、ユニットテストを再度実行した際に、コンソール出力のログで接続プールがDruidに切り替わっていることが確認できます。
4. CRUD操作
4-1) 削除
- 要件:IDに基づいてユーザー情報を削除する
- SQL:DELETE FROM user WHERE id = 5;
- Mapperインターフェースメソッド:
/**
* IDに基づいて削除
*/
@Delete("DELETE FROM user WHERE id = #{userId}")
void deleteUserById(@Param("userId") Integer userId);
- ユニットテストメソッドを追加してテストします。
@Test
public void testDeleteUserById() {
userRepository.deleteUserById(3);
}
4-2) 追加
- 要件:ユーザーを追加する
- SQL:INSERT INTO user(username, password, name, age) VALUES('shunsuke', '123456', '松祐', 25);
- Mapperインターフェース:
/**
* ユーザーを追加
*/
@Insert("INSERT INTO user(username, password, name, age) VALUES(#{user.username}, #{user.password}, #{user.name}, #{user.age})")
void addUser(@Param("user") User user);
- ユニットテスト:
@Test
public void testAddUser() {
User newUser = new User();
newUser.setUsername("admin");
newUser.setPassword("123456");
newUser.setName("管理者");
newUser.setAge(30);
userRepository.addUser(newUser);
}
4-3) 更新
- 要件:IDに基づいてユーザー情報を更新する
- SQL:UPDATE user SET username = 'shunsuke', password = '123456', name = '松祐', age = 25 WHERE id = 1;
- Mapperインターフェースメソッド:
/**
* IDに基づいてユーザー情報を更新
*/
@Update("UPDATE user SET username = #{user.username}, password = #{user.password}, name = #{user.name}, age = #{user.age} WHERE id = #{user.id}")
void updateUser(@Param("user") User user);
- ユニットテスト:
@Test
public void testUpdateUser() {
User updatedUser = new User();
updatedUser.setId(1);
updatedUser.setUsername("adminUpdated");
updatedUser.setPassword("123456");
updatedUser.setName("管理者");
updatedUser.setAge(31);
userRepository.updateUser(updatedUser);
}
4-4) 取得
- 要件:ユーザー名とパスワードに基づいてユーザー情報を取得する
- SQL:SELECT * FROM user WHERE username = 'shunsuke' AND password = '123456'
- Mapperインターフェースメソッド:
/**
* ユーザー名とパスワードに基づいてユーザー情報を取得
*/
@Select("SELECT * FROM user WHERE username = #{username} AND password = #{password}")
User findUserByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
- ユニットテスト:
@Test
public void testFindUserByUsernameAndPassword() {
User foundUser = userRepository.findUserByUsernameAndPassword("adminUpdated", "123456");
System.out.println(foundUser);
}
5. XMLマッピング構成
MyBatisの開発は主に2つの方法があります:
- アノテーション
- XML
5-1) XMLマッピングファイルの規範
単純なCRUD機能を実現するには、MyBatisのアノテーションを使用するのが一般的ですが、複雑なSQL機能を実現するには、XMLファイルでマッピングを設定することをお勧めします。
- XMLマッピングファイルの名称は、Mapperインターフェースの名称と一致し、同じパッケージに配置します。
- XMLマッピングファイルのnamespace属性は、Mapperインターフェースの完全修飾名と一致します。
- XMLマッピングファイル内のSQL文のidは、Mapperインターフェースのメソッド名と一致し、戻り値の型も一致します。
- resultType属性:単一行レコードをエンカプシュレートする型を指します。
5-2) XMLマッピングファイルの実装
- XMLマッピングファイルを作成します。
- XMLマッピングファイルにSQL文を記述します。
<mapper namespace="com.example.mapper.UserRepository">
<select id="fetchAllUsers" resultType="com.example.entity.User">
SELECT * FROM user
</select>
</mapper>
テストクラスを実行すると、結果が表示されます。
注意:インターフェースメソッドに対応するSQL文は、アノテーションまたはXMLのいずれか一方で設定し、両方で設定しないでください。
6. application.ymlの使用
6-1) はじめに
これまで、Spring Bootプロジェクト作成後に自動的に提供される`application.properties`を使用してプロパティを設定していましたが、プロジェクトで大量のプロパティを設定する必要がある場合、`key=value`形式の`application.properties`は階層構造が不明確になり、ファイルが肥大化することがあります。
プロジェクト開発では、簡潔で明瞭でデータ中心の`application.yml`を使用することを推奨します。
6-2) 構文
- 大文字と小文字を区別します。
- 値の前にスペースが必要で、これは区切り文字として機能します。
- インデントを使用して階層関係を表現します。インデントにはTabキーではなくスペースのみを使用します。
- 同じレベルの要素の左側が揃っている必要があります。
- `#`はコメントを表し、その文字から行末までパーサーによって無視されます。
ymlファイルの基本的な構文を理解した後、次にymlファイルで一般的に使用されるデータ形式について見ていきます。ここでは最も一般的な2つを紹介します。
- オブジェクト/Mapコレクション
user:
name: yamada
age: 20
password: 123456
- 配列/List/Setコレクション
hobby:
- coding
- reading
- hiking
ymlファイルでは、値が0で始まる場合は、値を`' '`で囲む必要があります。0で始まる値はymlで8進数として扱われるためです。
ymlファイルの基本的な構文を学んだ後、以前の例で使用していた設定ファイルを`application.yml`形式に変更します。
- `application.properties`の名前を`_application.properties`に変更します(名前は何でもいいですが、読み込まれないようにします)。
- `application.yml`ファイルを作成します。
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root@1234