LoginSignup
2
2

More than 5 years have passed since last update.

ClojureでDBを扱う

Last updated at Posted at 2016-12-02

書くこと

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)))
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2