本章源代码: 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 数据库,而后建立一个表来测试 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 文件。
在编写代码前,咱们首先要在 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。
(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
(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