您好,欢迎访问一九零五行业门户网

Clojure 学习入门(7) 连接mysql

clojure的contrib包中实现了对现有jdbc的封装,在wiki上有连接,该页面上包含了对不同的数据库的连接方法和基本的操作,但是这个页面上没有提供足够的信息,足够一个初学者能够使用clojure来完成一个sql操作。本文中我们将利用clojure和lein工具,简介一下做
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依赖:
(defproject myclojure 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.5.1] [org.clojure/java.jdbc 0.0.6] [org.clojure/clojure-contrib 1.2.0] [mysql/mysql-connector-java 5.1.26] ])
2) mysql.cli 代码
; clojure connect to mysql; ithomer.net; 2013.12.10(ns myclojure.mysql2 (:require [clojure.java.jdbc :as sql])); 配置参数(def mysql-db{ :classname com.mysql.jdbc.driver :subprotocol mysql :subname //172.27.9.104:3306/tmptest :user root :password server2011}); 创建表(defn create-fruit create a table [] (sql/create-table :fruit [:name varchar(32) primary key] [:appearance varchar(32)] [:cost :int] [:grade :real])); 删除表(defn drop-fruit drop a table [] (try (sql/drop-table :fruit) (catch exception _))); 连接数据库(sql/with-connection mysql-db (drop-fruit) (create-fruit)); 插入数据(sql/with-connection mysql-db (sql/insert-records :fruit {:name apple :appearance rosy :cost 24 :grade 1.2} {:name orange :appearance round :cost 49})); 条件查询(println (sql/with-connection mysql-db (sql/with-query-results rows [select * from fruit where appearance = ? rosy] (:cost (first rows))))); 全量查询(println (sql/with-connection mysql-db (sql/with-query-results rows [select * from fruit] (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
其它类似信息

推荐信息