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
相关文章
相关标签/搜索