zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Clojure 学习入门(7)- 连接mysql

2023-09-14 09:16:11 时间
Clojure的contrib包中实现了对现有JDBC的封装,在wiki上有连接,该页面上包含了对不同的 数据库 的连接方法和基本的操作,但是这个页面上没有提供足够的信息,足够一个初学者能够使用Clojure来完成一个SQL操作。本文中我们将利用Clojure和Lein工具,简介一下做开发的基础。当然网上也有非常多对Clojure的SQL操作进行封装的库,我们这里没有使用。

首先,配置你的MySQL数据库,创建数据库、表、数据。

其次,在和MySQL的操作中,我们需要两个库,一个是clojure.contrib,另外一个是mysql-connector-Java-xxx.jar。为了管理和配置这两个库,我们需要配置一下project.clj文件,在depedencies中加上两条:org.clojure/clojure-contrib “1.2.0” 和 mysql/mysql-connector-java “5.1.6”。这样运行 lein deps,就会自动下载并且安装到Leiningen dependencies lib目录下。

接着,在需要使用sql库的地方要导入这些库

在ns宏中加载如下内容:(:use [clojure.contrib.sql :as sql :only ()]),这样在本文件中就可以直接使用sql作为前缀。需要主意的是,虽然我们并没有直接使用到mysql-connector-java,但是如果在lib目录下没有该文件,就会报错没有mysql的driver。

配置上两条之后,就可以进行sql连接了。

首先要定义一个database specification,这是一个map,几个必须配置的key包括了:classname, subprotocol, subname, user, password。

( def  db {:classname "com.mysql.jdbc.Driver"
              :subprotocol "mysql"
              :subname "//127.0.0.1:3306/test"
              :user "root"
              :password "pass" })

这个db-spec在后面几乎所有的sql操作都是需要的。

接下来我们主要描述几个常用API的格式,具体的内容可以参考手册。

1,新建表

sql/create-table :table-name [:key :type “”] [:key :type “”])

(defn create - users []
     (sql / create - table
      :user
      [: id  :integer "PRIMARY KEY"  "AUTO_INCREMENT" ]
      [:fname "varchar(25)" ]))

2, 插入数据

两个api,一个是insert-rows,一个是insert-values。insert-rows需要形成一个完整的行数据插入到表中,insert-values可以按照key来插入值。 

(defn insert - user [fname]
     (sql / insert - values :users [:fname] [fname]))

使用insert-values可以利用primary-key的auto_increment的属性

(defn insert - rows
    []
    (sql / insert - rows :user [ 1  "Tim" ] [ 2  "Tom" ]))

3,丢弃表

(defn drop - user
   []
   ( try
     (sql / drop - table :fruit)
     (catch Exception _)))

4, with-query-results 选择查询的数据

with-query-results 类似于 let 语句,会将查询结果绑定到rs上,rs是一个map构成的sequence。

(sql / with - query - results rs [ "select * from user" ]
    (dorun ( map  #(println %) rs)))

5, 更新表

update-values 用来更新表的内容,使用该函数需要指定查询条件,如下图所示

(defn update - user [ id  attribute - map ]
     (sql / update - values :user [ "id=?"  id ] attribute - map ))

6, 删除行

(sql / delete - rows :user [ "id=?"  id ])

7,SQL准备

clojure支持由用户输入构造sql语句,利用的是sql prepared语句,略


8. 示例

创建表 fruit,并插入两条记录,然后条件查询和全部查询 

1) 在project.clj 中,添加sql依赖:

[python]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. (defproject myClojure "0.1.0-SNAPSHOT"  
  2.   :description "FIXME: write description"  
  3.   :url "http://example.com/FIXME"  
  4.   :license {:name "Eclipse Public License"  
  5.             :url "http://www.eclipse.org/legal/epl-v10.html"}  
  6.   :dependencies [  
  7.                  [org.clojure/clojure "1.5.1"]  
  8.                  [org.clojure/java.jdbc "0.0.6"]  
  9.                  [org.clojure/clojure-contrib "1.2.0"]  
  10.                  [mysql/mysql-connector-java "5.1.26"]  
  11.                  ])  

2) mysql.cli 代码

[python]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. ; clojure connect to mysql  
  2. ; ithomer.net  
  3. 2013.12.10  
  4.   
  5. (ns myClojure.mysql2  
  6.   (:require [clojure.java.jdbc :as sql]))  
  7.   
  8. ; 配置参数  
  9. (def mysql-db{  
  10.                :classname "com.mysql.jdbc.Driver"  
  11.                :subprotocol "mysql"  
  12.                :subname "//172.27.9.104:3306/tmptest"  
  13.                :user "root"  
  14.                :password "server2011"})  
  15.   
  16. ; 创建表  
  17. (defn create-fruit  
  18.   "Create a table"   
  19.   []  
  20.    (sql/create-table  
  21.      :fruit  
  22.      [:name "varchar(32)" "PRIMARY KEY"]  
  23.      [:appearance "varchar(32)"]  
  24.      [:cost :int]  
  25.      [:grade :real]))  
  26.   
  27. ; 删除表  
  28. (defn drop-fruit  
  29.   "Drop a table"   
  30.   []  
  31.   (try  
  32.     (sql/drop-table :fruit)  
  33.     (catch Exception _)))  
  34.   
  35. ; 连接数据库  
  36. (sql/with-connection  
  37.   mysql-db  
  38.   (drop-fruit)  
  39.   (create-fruit))  
  40.   
  41. ; 插入数据  
  42. (sql/with-connection mysql-db  
  43.   (sql/insert-records :fruit  
  44.                       {:name "Apple" :appearance "rosy" :cost 24 :grade 1.2}  
  45.                       {:name "Orange" :appearance "round" :cost 49}))  
  46.   
  47. ; 条件查询  
  48. (println (sql/with-connection mysql-db  
  49.            (sql/with-query-results rows  
  50.              ["SELECT * FROM fruit WHERE appearance = ?" "rosy"]  
  51.              (:cost (first rows)))))  
  52.   
  53. ; 全量查询  
  54. (println (sql/with-connection mysql-db  
  55.            (sql/with-query-results rows  
  56.              ["SELECT * FROM fruit"]  
  57.              (dorun (map #(println %) rows)))))  

运行结果:

24
{:name Apple, :appearance rosy, :cost 24, :grade 1.2}
{:name Orange, :appearance round, :cost 49, :grade nil}
nil

创建的数据库表内容:


注:所有的sql操作都需要在with-connection宏下包裹着

 


参考推荐:

Clojure SQL 基础

Clojure 连接mysql

Connecting Clojure and MySQL