clojure.java.jdbc

repository·master·Indexed 20 days ago

https://github.com/clojure/java.jdbc

A low-level Clojure wrapper for JDBC-based database access. It provides functions for database operations such as query, insert-multi!, and reducible-query, and supports connection configuration via db-spec. Currently in maintenance mode and superseded by next.jdbc, the latest stable release is 0.7.12.

Tokens
2.8K
Snippets
10
Records
19
Agent score
23%

What's inside clojure.java.jdbc

  1. Important notice: clojure.java.jdbc is Inactive

    master

    The clojure.java.jdbc project is currently considered Inactive. It is a mature and stable library that will only receive critical bug fixes (e.g., security).

    For new projects, the maintainer recommends using seancorfield/next.jdbc, which is a faster, more modern JDBC wrapper described as the "next generation" of this library.

  2. Configure database connections with db-spec

    master

    The preferred way to define database connection settings is using a db-spec map. You can use the :dbtype key to specify the database type, which simplifies configuration.

    Supported aliases include:

    • postgres / pgsql
    • mssql / sqlserver
    • jtds / jtds:sqlserver
    • oracle / oracle:thin
    • hsql / hsqldb
    • redshift (uses com.amazon.redshift.jdbc.Driver)

    You can also provide a classname alongside dbtype or dbname to specify a JDBC driver class name for unknown database types. For Oracle, you can use :dbtype "oracle:thin" or :dbtype "oracle:oci" (the latter uses @ instead of // before the host).

  3. Define a database specification (db-spec)

    master

    A db-spec is used to tell the library how to connect to your database. There are three common ways to define one:

    1. Using :dbtype and connection options: Provide :dbtype along with :dbname, :user, :password, :host, and :port.
    2. Using :classname: If the :dbtype is unknown or you need to override the default driver, provide the :classname of the JDBC driver.
    3. Using :connection-uri: Provide a full JDBC connection string.

    Note: You must include the appropriate JDBC driver dependency in your project for these to work.

    (require '[clojure.java.jdbc :as j])
    
    ;; 1. Using :dbtype and options
    (def mysql-db {:dbtype "mysql"
                   :dbname "clojure_test"
                   :user "clojure_test"
                   :password "clojure_test"})
    
    (def pg-db {:dbtype "postgresql"
                :dbname "mypgdatabase"
                :host "mydb.server.com"
                :user "myuser"
                :password "secret"
                :ssl true
                :sslfactory "org.postgresql.ssl.NonValidatingFactory"})
    
    ;; 2. Using :classname for custom/unknown types
    (def redshift42 {:dbtype "redshift"
                     :dbname "myredstore"
                     :classname "com.amazon.redshift.jdbc42.Driver"})
    
    ;; 3. Using a full connection URI
    (def pg-uri
      {:connection-uri (str "postgresql://myuser:secret@mydb.server.com:5432/mypgdatabase"
                            "?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory")})
  4. Install clojure.java.jdbc

    master

    To use clojure.java.jdbc, add the following dependency to your project. Note that the latest stable release (0.7.12) requires Clojure 1.7 or later. You must also include the JDBC driver for your specific database (e.g., PostgreSQL, MySQL, H2).

    ### deps.edn
    ```clojure
    org.clojure/java.jdbc {:mvn/version "0.7.12"}

    Leiningen

    [org.clojure/java.jdbc "0.7.12"]

    Maven

    <dependency>
      <groupId>org.clojure</groupId>
      <artifactId>java.jdbc</artifactId>
      <version>0.7.12</version>
    </dependency>
  5. Optimize insert-multi! performance

    master
    When using insert-multi!, providing a sequence of row value vectors is substantially faster than providing a sequence of row maps. A sequence of maps performs an individual insert for each row, whereas a sequence of vectors allows for a single bulk insert of all data together.
  6. Configure db-spec with simplified syntax

    master

    Starting from version 0.3.4, you can use a simpler db-spec using :dbtype and :dbname, along with optional :host and :port keys.

    ;; Simplified db-spec
    {:dbtype :postgresql :dbname "my_db" :host "localhost" :port 5432}
  7. Perform database operations with clojure.java.jdbc

    master

    Once you have a db-spec, you can use functions from clojure.java.jdbc to interact with your data. Common operations include insert-multi! for batch inserts and query for retrieving data.

    When using query, you can pass an options map to transform the result set, such as using :row-fn to specify how rows are processed.

    (require '[clojure.java.jdbc :as j])
    
    (def mysql-db {:dbtype "mysql" :dbname "clojure_test" :user "clojure_test" :password "clojure_test"})
    
    ;; Batch insert multiple rows
    (j/insert-multi! mysql-db :fruit
      [{:name "Apple" :appearance "rosy" :cost 24}
       {:name "Orange" :appearance "round" :cost 49}])
    
    ;; Query data with a parameter and a row function
    (j/query mysql-db
      ["select * from fruit where appearance = ?" "rosy"]
      {:row-fn :cost})
    ;; => (24)
  8. Use find-by-keys and get-by-id for convenience

    master

    find-by-keys and get-by-id are convenience functions for retrieving data.

    find-by-keys supports an :order-by option which expects a sequence of orderings. An ordering can be:

    • A column name (keyword).
    • A map from a column name (keyword) to a direction (:asc or :desc).
  9. Configure connection properties like auto-commit and read-only

    master
    The get-connection function accepts an opts map containing :auto-commit? and :read-only?. These options are valid in any function call that invokes get-connection under the hood (such as query, insert!, etc.). Setting :read-only? true can help enable streaming results for most databases.
  10. Work with SQL metadata using metadata-query

    master
    Version 0.4.2 added the metadata-query macro to simplify working with metadata queries and their results. Additionally, version 0.3.0-rc1 introduced with-db-metadata and metadata-result for similar purposes.
  11. Use insert-multi! for multi-row insertion

    master

    As of version 0.5.6, the insert! function supports only single-row insertion. For multi-row insertion, use the insert-multi! function. Additionally, the :options delimiter is no longer required for the options map in these calls.

    ;; Single row insertion
    (insert! db table [:col] ["val"] {})
    
    ;; Multi-row insertion
    (insert-multi! db table [:col] [["val1"] ["val2"]])
  12. Use with-db-transaction for transactions

    master

    Version 0.3.0-rc1 deprecated db-transaction in favor of with-db-transaction. This macro allows you to specify an optional :isolation level.

    (with-db-transaction db-spec {:isolation :serializable}
      ;; database operations here
      )