Spring BootでのDB操作 ~JDBC編~
Spring BootでDBアクセスの色々なパターンを試してみようと思います。 今回はSpring Frameworkが提供しているJDBC data sourceを利用して、JdbcTemplateを使った実装をしてみます。
DB準備
ローカルのMySQL(5.7系)を利用します。インストール等の手順は省略。 今回はサンプルーデータとして、下記のようなデータを作成しました。
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; USE mydb; CREATE TABLE users ( userid BIGINT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(32) ); CREATE TABLE stores ( storeid BIGINT AUTO_INCREMENT PRIMARY KEY, storename VARCHAR(32) ); CREATE TABLE reserves ( reserve_id BIGINT AUTO_INCREMENT PRIMARY KEY, userid BIGINT NOT NULL, storeid BIGINT NOT NULL, reservetime TIMESTAMP DEFAULT current_timestamp(), FOREIGN KEY (userid) REFERENCES users (userid), FOREIGN KEY (storeid) REFERENCES stores (storeid) ); INSERT INTO users (username) VALUES ('tanaka'), ('katou'), ('yoshida'); INSERT INTO stores (storename) VALUES ('a_store'), ('b_store'), ('c_store'); INSERT INTO reserves (userid, storeid) VALUES (1, 1), (2, 1), (3, 2);
目指すところ
@RestController
アノテーションを付けたコントローラーで、以下の全予約情報をjson形式で返却するところまで実装します。
- username : ユーザー名
- storename : 店舗名
- reservetime : 予約情報
実装
1. pom.xmlに以下の依存関係を追加
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>
2. JDBC datasourceの設定
resources配下に以下のようにapplication.ymlを追加。
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/mydb username: root password: 794Uguisu driverClassName: com.mysql.jdbc.Driver
3. SpringBootのメイン処理
@SpringBootApplication public class MybootApplication { public static void main(String[] args) { SpringApplication.run(MybootappApplication.class, args); } }
4. DAOの作成
public class ReserveDao { private String username; private String storename; private String reservetime; // getter, setter省略 }
5. Controller作成
Modelに当たる実装もControllerに含めてしまっています。
上記設定をするだけで、JdbcTemlateがAutowiredできるので手軽です。
@RestController public class SampleController { @Autowired JdbcTemplate jdbcTemplate; @Transactional public List<Reserve> findAllReserve() { RowMapper<Reserve> mapper = new BeanPropertyRowMapper<>(Reserve.class); String sql = "SELECT u.username, s.storename, r.reservetime " + "FROM ( reserves AS r LEFT JOIN users as u ON r.userid = u.userid ) " + "LEFT JOIN stores AS s ON r.storeid = s.storeid;"; List<Reserve> rs = jdbcTemplate.query(sql, mapper); // 代わりに`queryForList`を利用して以下のようにも書けるらしいが不便 // List<Reserve> rs = new ArrayList<>(); // List<Map<String, Object>> sqlResults = jdbcTemplate.queryForList(sql); // for( Map<String, Object> map : sqlResults ) { // Reserve reserve = new Reserve(); // reserve.setUsername(map.get("username").toString()); // reserve.setStorename(map.get("storename").toString()); // reserve.setReservetime((Timestamp) map.get("reservetime")); // reserveList.add(reserve); //} return rs; } @RequestMapping("/") public List<Reserve> index() { return findAllReserve(); } }