Clojure使用Korma 來訪問數據庫

使用Korma 來訪問數據庫

本章源代碼: https://github.com/LightSwordSpringBoot/clj-webhtml

##訪問數據庫java

Java 提供了標準的 JDBC 接口訪問數據庫,Clojure 的數據庫接口mysql

clojure.java.jdbc

是對 Java JDBC 的封裝。咱們只須要引用 clojure.java.jdbc 以及對應的數據庫驅動,就能夠在 Clojure 代碼中訪問數據庫。git

clojure.java.jdbc 是一個比較底層的接口。咱們使用 DSL 的模式來編寫數據庫代碼,相似 Java 的 Hibernate,選擇 Korma 來編寫訪問數據庫的代碼。github

因爲 Clojure 是 Lisp 方言,它繼承了 Lisp 強大的「代碼即數據」的功能,在 Clojure 代碼中,編寫 SQL 語句對應的 DSL 十分天然,徹底無需 Hibernate 複雜的映射配置。web

配置 MySQL 數據庫

咱們先配置好 MySQL 數據庫,而後建立一個表來測試 Clojure 代碼.sql

建立 schema數據庫

CREATE SCHEMA `cljweb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;

建立表eclipse

create table courses (
 `id` varchar(32) not null primary key,
 `name` varchar(50) not null,
 `price` real not null,
 `online` bool not null,
 `days` bigint not null
);

新建一個 db.clj 文件,選擇菜單「File」-「New」-「Other...」,選擇「Clojure」-「Clojure Namespace」,填入名稱ide

course.db

就能夠建立一個 db.clj 文件。

添加jar 包依賴

在編寫代碼前,咱們首先要在 project.clj 文件中添加依賴項。

[org.clojure/java.jdbc "0.3.6"]
[mysql/mysql-connector-java "5.1.25"]
[korma "0.3.0"]

咱們執行

lein pom

能夠發現新生成的 pom.xml, 添加了新的依賴:

<dependencies>
    <dependency>
      <groupId>org.clojure</groupId>
      <artifactId>clojure</artifactId>
      <version>1.8.0</version>
    </dependency>
    <dependency>
      <groupId>org.clojure</groupId>
      <artifactId>java.jdbc</artifactId>
      <version>0.3.6</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.25</version>
    </dependency>
    <dependency>
      <groupId>korma</groupId>
      <artifactId>korma</artifactId>
      <version>0.3.0</version>
    </dependency>
  </dependencies>

引用 Korma

使用 Korma 操做數據庫十分簡單,只須要先引用 Korma。

(ns
  ^{:author jack}
  org.lightsword.course.db
  (:use korma.db korma.core) )

數據庫鏈接的配置信息

定義數據庫鏈接

(defdb korma-db (mysql {
                        :db "cljweb",
                        :host "localhost",
                        :port 3306,
                        :user "root",
                        :password "root"
                        
                        }))

使用數據庫表 entity

而後定義一下要使用的 entity,也就是表名。

定義 entity

(declare courses)
(defentity courses)

插入一條記錄

如今,就能夠對數據庫進行操做了。插入一條記錄。

執行 insert

(insert courses
        (values {:id "007", :name "Clojure Programming", :price 45.8, :online true, :days 30})
)

使用 Clojure 內置的 map 類型,十分直觀。

查詢

查詢語句經過 select 宏實現了 SQL DSL 到 Clojure 代碼的天然映射。 執行 select

(select courses
        (where {:online true})
        (order :name :asc)
)

這徹底得益於 Lisp 的 S 表達式的威力,既不須要直接拼湊 SQL,也不須要從新發明相似 HQL 的語法。

利用 Korma 提供的 sql-only 和 dry-run,能夠打印出生成的 SQL 語句.

完整的程序

(ns org.lightsword.course.db
  (:use korma.db
        korma.core))


(defdb korma-db (mysql {
                        :db "cljweb",
                        :host "localhost",
                        :port 3306,
                        :user "root",
                        :password "root"

                        }))

(declare courses)
(defentity courses)


(defn create-course! [c]
  (println "create course:" c)
  (insert courses
          (values c)
  )
  )


(defn get-courses []
  (select courses
          (where {:online true})
          (order :name :asc)
          )
  )

(defn get-all []
  (select courses (order :name :asc))
  )

(defn init-courses! []
  (if (empty? (get-courses))
    (let [cs [{:id "s-201", :name "SQL", :price 99.9, :online false, :days 30 },
              {:id "s-202", :name "PHP", :price 69.9, :online false, :days 15},
              {:id "s-203", :name "F#",  :price 80.0, :online false, :days 20}]]

      (println "init courses ...")
      (dorun (map create-course! cs))
      )
    )

  )

(defn -main [& args]
  (init-courses!)
  (println (get-courses))

  (println (get-all))

  )

咱們配置一下 main

project.clj

(defproject org.lightsword/clj-web "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"}
  :main org.lightsword.course.db
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/java.jdbc "0.3.6"]
                 [mysql/mysql-connector-java "5.1.25"]
                 [korma "0.3.0"]
                 ])

運行

$ lein run
WARNING: update already refers to: #'clojure.core/update in namespace: korma.core, being replaced by: #'korma.core/update
WARNING: update already refers to: #'clojure.core/update in namespace: org.lightsword.course.db, being replaced by: #'korma.core/update
七月 03, 2016 1:19:55 下午 com.mchange.v2.log.MLog <clinit>
信息: MLog clients using java 1.4+ standard logging.
七月 03, 2016 1:19:55 下午 com.mchange.v2.c3p0.C3P0Registry banner
信息: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
七月 03, 2016 1:19:55 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge1619h1cm0f3t1s80nsr|d1f74b8, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge1619h1cm0f3t1s80nsr|d1f74b8, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/cljweb, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 10800, maxIdleTimeExcessConnections -> 1800, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]


[{:id 007, :name Clojure Programming, :price 45.8, :online true, :days 30}]

[{:id 007, :name Clojure Programming, :price 45.8, :online true, :days 30} {:id s-203, :name F#, :price 80.0, :online false, :days 20} {:id s-202, :name PHP, :price 69.9, :online false, :days 15} {:id s-201, :name SQL, :price 99.9, :online false, :days 30}]

從運行日誌咱們能夠看出, org.clojure/java.jdbc 底層調用的是

driverClass -> com.mysql.jdbc.Driver
相關文章
相關標籤/搜索