Home

Awesome

clj-dbcp

Clojure wrapper for Apache DBCP2 to create JDBC connections pools.

Usage

On Clojars: https://clojars.org/clj-dbcp

Leiningen coordinates: [clj-dbcp "0.9.0"] (supports Clojure 1.5 through Clojure 1.9, Java 7 or higher)

The recommended way to create a datasource is to call the clj-dbcp.core/make-datasource function, for example:

(make-datasource {:classname "com.mysql.jdbc.Driver"
                  :jdbc-url "jdbc:mysql://localhost/empdb"
                  :username "empuser"
                  :password "s3cr3t"
                  :test-query "SELECT 1;"})

You can also parse a database URL (Heroku style) and use to create datasource:

(make-datasource (parse-url "postgres://foo:bar@heroku.com:5489/hellodb"))

or,

(make-datasource (parse-url (System/getenv "DATABASE_URL")))

Sections below describe which of the keys are applicable to various databases:

JDBC parameters

Required: :classname (string), :jdbc-url (string) Optional: :test-query (string)

Optional keys for all JDBC connections

Keyword argMeaningDefault/special
:propertiesMap of property names and values
:userDatabase username
:usernameDatabase username, same as :user
:passwordDatabase password
:test-queryValidation queryAs per :target
:init-sizeInitial size of connection pool (int)
:min-idleMinimum idle connections in pool (int)
:max-idleMaximum idle connections in pool (int)
:max-totalMaximum active connections in pool (int)-ve=no limit
:pool-pstmt?Whether to pool prepared statementstrue
:max-open-pstmtMaximum open prepared statements (int)
:remove-abandoned?Whether to remove abandoned connectionstrue
:remove-abandoned-timeout-secondsTimeout in seconds (int)300
:log-abandoned?Whether to log abandoned connectionstrue
:lifo-pool?Whether Last-In-First-Out (LIFO) or notfalse
:test-while-idle?Whether validate the idle connectionstrue
:test-on-borrow?Whether validate connections on borrowtrue
:test-on-return?Whether validate connections on returntrue
:test-query-timeoutTimeout (seconds) for validation queries
:millis-between-eviction-runsMillis to sleep between evictions-1
:min-evictable-millisMillis a connection may sit idle before eviction1800000
:tests-per-evictionNo. of connections to test in each eviction run3
:cache-state?Whether to cache statetrue

Generic JDBC connections

:adapterRequired keysDesired keys
:jdbc:classname :jdbc-url:test-query

JNDI connections

You can open a JNDI datasource (unlike the JDBC datasource) as follows:

(make-datasource :jndi {:context "java:comp/env/myDataSource"})

or,

(jndi-datasource "java:comp/env/myDataSource")

Example

A typical CRUD example using Derby database is below.

Leiningen dependencies:

[clj-dbcp "0.9.0"]
[asphalt  "0.4.0"]  ; for JDBC CRUD operations
[mysql/mysql-connector-java "6.0.2"]  ; MySQL JDBC driver 

Example code:

(ns example.app
(ns newproj.core
  (:require 
    [clj-dbcp.core     :as dbcp]
    [asphalt.core :as a]))

(def db-sql  ;; an in-memory database instance
  {:datasource
   (dbcp/make-datasource
     {:classname "com.mysql.jdbc.Driver" 
      :jdbc-url   "jdbc:mysql://localhost:3306/new_db"
      :user "root" 
      :password "root"})})

(defn crud
  []
  (a/update db-sql "CREATE TABLE IF NOT EXISTS EMP (ID int, Name varchar (25), Age int)" [])
  (a/update db-sql
    "INSERT INTO emp (id, name, age) VALUES (?, ?, ?)"
    [1, "Bashir",40])
  (a/update db-sql
    "UPDATE EMP set name=\"Shabir\", age=50 where id=1"
    [])
  (println (a/query a/fetch-rows
             db-sql
             "SELECT id, name, age FROM emp" []))
  (a/update db-sql
    "DROP TABLE EMP" []))

Development Notes

You need Java 7 and Leiningen 2 to build this code. Testing JDBC-ODBC bridge driver requires that you use a Windows machine with ODBC DSNs configured.

Starting up the swank server (if you are going to work using Emacs/Slime):

$ lein2 dev swank

Testing against the dev version:

$ ./run-tests

Testing across several versions of Clojure:

$ ./run-tests.sh all

Contributors

Getting in touch

On GMail: kumar.shantanu(at)gmail.com

On Twitter: @kumarshantanu

License

Copyright © 2012-2016 Shantanu Kumar

Distributed under the Eclipse Public License, the same as Clojure.