我是一名学习 Haskell 的 Java 程序员。
我在一个使用 Happstack 并通过 HDBC 与数据库对话的小型网络应用程序上工作。
我已经编写了select和exec函数,我像这样使用它们:
module Main where
import Control.Exception (throw)
import Database.HDBC
import Database.HDBC.Sqlite3 -- just for this example, I use MySQL in production
main = do
exec "CREATE TABLE IF NOT EXISTS users (name VARCHAR(80) NOT NULL)" []
exec "INSERT INTO users VALUES ('John')" []
exec "INSERT INTO users VALUES ('Rick')" []
rows <- select "SELECT name FROM users" []
let toS x = (fromSql x)::String
let names = map (toS . head) rows
print names
如您所见,非常简单。有查询、参数和结果。
连接创建和提交/回滚内容隐藏在 select 和 exec 中。
这很好,我不想在我的“逻辑”代码中关心它。
exec :: String -> [SqlValue] -> IO Integer
exec query params = withDb $ \c -> run c query params
select :: String -> [SqlValue] -> IO [[SqlValue]]
select query params = withDb $ \c -> quickQuery' c query params
withDb :: (Connection -> IO a) -> IO a
withDb f = do
conn <- handleSqlError $ connectSqlite3 "users.db"
catchSql
(do r <- f conn
commit conn
disconnect conn
return r)
(\e@(SqlError _ _ m) -> do
rollback conn
disconnect conn
throw e)
坏点:
- 每次调用都会创建一个新连接——这会降低负载时的性能
- DB url“users.db”是硬编码的 - 我不能在其他项目中重用这些功能而无需编辑
问题 1:如何引入一个具有一些已定义(最小、最大)并发连接数的连接池,以便在 select/exec 调用之间重用连接?
问题 2:如何使“users.db”字符串可配置?(如何将其移至客户端代码?)
它应该是一个透明的特性:用户代码不应该需要明确的连接处理/释放。