書くこと
ClojureとKormaを使ってDBアクセスする。
Korma
https://github.com/korma/Korma
http://sqlkorma.com/
必要なことはここに全て書いてあるので、英語だけど読めば下の記事は読む必要がない。
前準備
Leiningenは入ってるものとする。
適当にプロジェクトを作ってdependenciesにkormaを追加しておく。
今回はRDBMSにMySQLを使用するので、MySQLのドライバもいれておく。
init.sh
lein new default app
cd app
vim project.clj
project.clj
(defproject app "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [
[org.clojure/clojure "1.6.0"]
[korma "0.4.3"]
[mysql/mysql-connector-java "5.1.38"]
])
init.sh
lein test
テストはコケるものが用意されているので正常にコケる
DBに接続する
vim src/app/core.clj
src/app/core.clj
(ns app.core)
(use 'korma.db)
(use 'korma.core)
; DB接続を作成する
(defdb mydb
(mysql
{
:db "app_database"
;手元の環境ではSSL証明書はないので使わなようにしておく。
:subname "//127.0.0.1:3306/app_database?useSSL=false"
:user "app_database"
:excess-timeout 1000
:idle-timeout 1000
:initial-pool-size 1
:minimum-pool-size 1
:maximum-pool-size 1
:password "app_database"}))
; 使用するテーブルを呼び出しておく
(defentity app)
; 既存のテスト関数
(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!"))
テスト用のDBを作っておく。
init.sql
CREATE DATABASE app_database;
GRANT ALL ON *.* TO 'app_database'@'%' IDENTIFIED BY 'app_detabase';
USE app_database;
CREATE TABLE app ( id INT(10) AUTO_INCREMENT PRIMARY KEY , name VARCHAR(20) , integer_value INT (10) DEFAULT 0);
INSERT INTO app ( name , integer_value) VALUES ("name1" , 1) ;
INSERT INTO app ( name , integer_value) VALUES ("name2" , 2) ;
INSERT INTO app ( name , integer_value) VALUES ("name3" , 3) ;
CRUD
特に衒いがなく直感的な使いやすい形でインターフェースが揃っている。
SELECT
CRUDさえできればとりあえずのことはできる。
Seectは帰り値がArrayで帰ってくるのでわかりやすく便利。
select.clj
(def select-result (select app (fields :id :name)))
; SELECT id , name FROM app;
(println
(:id (first select-result)))
(println
(:name (first select-result)))
; WHERE句をつけて実行する。
(def where-result (select app
(fields :id :name)
(where (= :id 1))
))
(println
(:id (first where-result)))
; 集計関数を使う
(def sum-result (select app
(aggregate (sum :integer_value) :integer_value_sum)
))
(println
(:integer_value_sum (first sum-result)))
INSERT
insert.clj
(insert app
(values {
:name "name4"
:integer_value 33
}))
UPDATE
update.clj
(def update-result (update app
(where (or (= :id 1) (= :id 2) (= :id 3000))
(set-fields {
:name "updated_name"
:integer_value "20"
})))
(println update-result)
; 変更行数として2が表示される。
; id=3000の物は計上されない
DELETE
delete.clj
(delete app
(where (>= :id 3)))