如何从Clojure连接到MySQL数据库?

30

假设您的计算机已经安装了Clojure和MySQL。
如何使它们通信?

4个回答

29

假设您已经在您的电脑上安装了 Clojure 和 MySQL。

  1. checkout and build clojure-contrib:

    git clone git://github.com/richhickey/clojure-contrib.git
    cd clojure-contrib
    build
    

    Put the resulting clojure-contrib.jar on your CLASSPATH.

  2. Download MySQL Connector/J and put the mysql-connector-java-5.1.7-bin.jar on your CLASSPATH

    You might have to run your JVM with these arguments:

    -Djdbc.drivers=com.mysql.jdbc.Driver
    
  3. Determine the connection URL of your MySQL database

    For example, if you are running MySQL under MAMP then the URL that you would use in JDBC will look something like:

    conn = DriverManager.getConnection
            ("jdbc:mysql://localhost:8889/db_name?user=root&password=root")
    

    The url is broken down into these components:

    • protocol: jdbc:
    • subprotocol: mysql
    • db-host: localhost
    • db-port: 8889
    • username
    • password
  4. Make this clojure script, modify the database connection parameters to match your URL, save as test.clj, compile and run.

    (use 'clojure.contrib.sql)               ;;' satisfy prettify

      (let [db-host "localhost"
            db-port 8889
            db-name "db_name"]
        (def db {:classname "com.mysql.jdbc.Driver"
               :subprotocol "mysql"
               :subname (str "//" db-host ":" db-port "/" db-name)
               :user "root"
               :password "root"})
        (with-connection db
          (with-query-results rs ["select * from languages"]
            (dorun (map #(println (:language :iso_code %)) rs)))))

            ; rs will be a sequence of maps,
            ; one for each record in the result set.

注意:这段代码是基于Mark Volkmann编写的类似代码进行了修改,以便从Clojure中访问Postgres数据库


2
第一行的注释(;;' ignore)不是源代码的必需部分 - 它被添加以保留Clojure源代码的语法着色。 - devstopfix
步骤1现在是:git克隆 git://github.com/richhickey/clojure-contrib.git - anon
1
请注意,您可能无法直接连接到远程服务器,因此最好使用类似于“ssh -L 1234:localhost:3306 user@remoteserver”的方式将某个随机本地端口转发到服务器上。另外,建议了解GNU Screen以便更轻松地处理多个终端窗口。 - konr

15

以下是一份友好的Lein配置,大部分内容参考了Nurullah Akkaya的这篇博客

  1. 在你的project.clj文件中添加依赖项:

(defproject clojql "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.2.1"]
                 [org.clojure/clojure-contrib "1.2.0"]   ;; for clojure.contrib.sql
                 [org.clojure/java.jdbc "0.0.6"]         ;; jdbc 
                 [mysql/mysql-connector-java "5.1.6"]])  ;; mysql driver
  • 在命令行中运行lein deps来获取依赖项

  • 在地图中指定您的连接信息:

  • user=> (use 'clojure.contrib.sql)
    nil
    user=> (def db {:classname "com.mysql.jdbc.Driver" 
                    :subprotocol "mysql" 
                    :subname "//localhost:3306/nmr" 
                    :user "root"})
    
    使用with-connectionwith-query-results(及其他)
    user=> (with-connection db (with-query-results rs ["select * from sometable"] (count rs)))
    667
    

    第3步和第4步可以在REPL中执行(使用lein repl启动),也可以在普通源代码中执行


    顺便说一下,当前稳定版本包括1.4.0的clojure、0.2.3的java.jdbc和5.1.22的mysql-connector-java。不再需要使用clojure-contrib,而clojure.contrib.sql现在已成为java.jdbc的一部分。请参见https://github.com/clojure/java.jdbc了解示例。 - raylu

    9
    截至2016年: 使用Leiningen, 在project.clj中添加依赖项:
    :dependencies [[org.clojure/clojure "1.8.0"]
                   [org.clojure/java.jdbc "0.4.2"]
                   [mysql/mysql-connector-java "5.1.38"]]
    

    在命名空间定义内部需要引入数据库连接器:

    (ns name.space
      (:require [clojure.java.jdbc :as j]))
    

    定义数据库连接:
    (def db-map {:subprotocol "mysql"
                 :subname "//localhost:3306/SCHEME"
                 :user "DB_USER"
                 :password "DB_USER_PASS"})
    

    查询数据库:
    (j/query db-map ["SELECT * FROM table"])
    

    http://clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html中查找更多的示例。


    4
    如果你想要一些语法糖,可以尝试使用Korma。 文档 Github
    (use 'korma.db)
    (defdb db (postgres {:db "mydb"
                         :user "user"
                         :password "dbpass"}))
    
    (use 'korma.core)
    (defentity users)
    
    
    (select users)
    ;; executes: SELECT * FROM users
    
    
    (select users
      (where (or (= :usersname "chris")
                 (= :email "chris@chris.com"))))
    ;; executes: SELECT * FROM users WHERE (users.usersname = 'chris' OR users.email = 'chris@chris.com')
    

    1
    这并不是真正的MySQL。 - Ven
    @Ven,虽然上面片段中的defdb确实指向Postgres,但文档涵盖了除MySQL之外的其他数据库。请参见此处:http://sqlkorma.com/docs#db 也许可以更新代码片段以更好地与问题相关联。 - Ron Klein

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接