【问题标题】:How do I connect to a MySQL database from Clojure?如何从 Clojure 连接到 MySQL 数据库?
【发布时间】:2009-03-05 08:07:00
【问题描述】:

假设:您的机器上已经同时运行 Clojure 和 MySQL。
你如何让他们说话?

【问题讨论】:

    标签: mysql clojure


    【解决方案1】:

    假设:您的机器上已经同时运行 Clojure 和 MySQL。

    1. 结帐并构建clojure-contrib:

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

      将生成的 clojure-contrib.jar 放入您的 CLASSPATH

    2. 下载MySQL Connector/J并将mysql-connector-java-5.1.7-bin.jar放在你的CLASSPATH

      您可能必须使用以下参数运行 JVM:

      -Djdbc.drivers=com.mysql.jdbc.Driver
      
    3. 确定 MySQL 数据库的连接 URL

      例如,如果您在MAMP 下运行 MySQL,那么您将在 JDBC 中使用的 URL 将类似于:

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

      url被分解成这些组件:

      • 协议:jdbc:
      • 子协议:mysql
      • 数据库主机:localhost
      • 数据库端口:8889
      • 用户名
      • 密码
    4. 制作这个clojure脚本,修改数据库连接参数以匹配你的URL,保存为test.clj,编译运行。

        (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.
    

    NB 此代码改编自 Mark Volkmann 编写的类似代码到 access a Postgres database from Clojure

    【讨论】:

    • 第一行的注释 (;;' ignore) 不是源代码的必需部分 - 添加它是为了保留 Clojure 源代码的语法着色。
    • 第 1 步现在是: git clone git://github.com/richhickey/clojure-contrib.git
    • 请注意,您可能无法直接连接到远程服务器,因此最好使用ssh -L 1234:localhost:3306 user@remoteserver 将一些随机本地端口转发到服务器。此外,检查 GNU Screen 以更轻松地处理多个终端。
    【解决方案2】:

    这是一个对 lein 友好的答案,有很多来自 this blog by 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
      
    2. 从命令行运行lein deps获取依赖项

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

      user=> (use 'clojure.contrib.sql)
      nil
      user=> (def db {:classname "com.mysql.jdbc.Driver" 
                      :subprotocol "mysql" 
                      :subname "//localhost:3306/nmr" 
                      :user "root"})
      
    4. 使用with-connectionwith-query-results(& others)

      user=> (with-connection db (with-query-results rs ["select * from sometable"] (count rs)))
      667
      

    步骤 3 和 4 可以来自 repl(lein repl 启动它)或在普通源代码中

    【讨论】:

    • 谢谢!顺便说一句,目前最新的“稳定”版本是 clojure 的 1.4.0,java.jdbc 的 0.2.3,mysql-connector-java 的 5.1.22。不再需要 clojure-contrib 并且 clojure.contrib.sql 现在是 java.jdbc 的一部分。有关示例,请参见 github.com/clojure/java.jdbc
    【解决方案3】:

    截至 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。

      Docs

      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')
      

      【讨论】:

      • 那不是真正的 mysql。
      • @Ven,虽然上面 sn-p 中的 defdb 确实指向 Postgres,但文档涵盖了 MySql 以及其他数据库。见这里:sqlkorma.com/docs#db 也许可以更新代码 sn-p 以更好地与问题相关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-04
      • 2020-11-20
      相关资源
      最近更新 更多