Haskell/数据库
Haskell 最流行的数据库模块是 HDBC。HDBC 在 Haskell 程序和 SQL 关系数据库之间提供了一个抽象层。这使您能够一次在 Haskell 中编写数据库代码,并使其能够与多个后端 SQL 数据库一起使用。
HDBC 模仿了 Perl 的 DBI 接口,但它也受到了 Python 的 DB-API v2、Java 中的 JDBC 以及 Haskell 中的 HSQL 的影响。就像 DBI 在 Perl 中需要 DBD 一样,HDBC 也需要一个驱动模块来工作。
这些 HDBC 后端驱动存在:PostgreSQL、SQLite 和 ODBC(用于 Windows 和 Unix/Linux/Mac)。MySQL 是最流行的开源数据库,并且有两个用于 MySQL 的驱动程序:HDBC-mysql(原生)和 HDBC-odbc(ODBC)。MySQL 用户可以在任何支持 MySQL 的平台上使用 ODBC 驱动程序,包括 Linux。
使用 ODBC 的一个优点是 SQL 语句的语法不受不同类型的数据库引擎的影响。如果需要从一个数据库迁移到另一个数据库,这将提高应用程序的可移植性。使用 ODBC 的相同理由适用于其他商业数据库(如 Oracle 和 DB2)。
有关更多信息,请参阅 HDBC 常见问题解答。
原生 ODBC-mysql 库需要 C MySQL 客户端库存在。
您可能需要 包装您的数据库访问 以防止运行时错误。
使 HDBC 通过 ODBC 与 MySQL 一起工作有点复杂,尤其是当您没有 root 权限时。
- 如果您的平台还没有提供 ODBC 库(大多数平台都有),请安装 Unix-ODBC。有关更多信息,请参见 这里。
- 安装 MySQL-ODBC 连接器。有关更多信息,请参见 这里。
- 安装 Database.HDBC 模块
- 安装 Database.HDBC.ODBC 模块
- 将 mysql 驱动程序添加到 odbcinst.ini 文件(位于 $ODBC_HOME/etc/)和 $HOME/.odbc.ini 中的数据源。
- 创建测试程序
由于 ODBC 驱动程序默认情况下使用共享库安装,因此您需要以下环境变量
export LD_LIBRARY_PATH=$ODBC_HOME/lib
如果您不喜欢添加额外的环境变量,则应尝试使用静态库选项启用编译 ODBC。
接下来的任务是编写一个简单的测试程序,该程序连接到数据库并打印所有表的名称,如下所示。
您可能需要 包装您的数据库访问 以防止运行时错误。
module Main where
import Database.HDBC.ODBC
import Database.HDBC
main =
do c <- connectODBC "DSN=PSPDSN"
xs <- getTables c
putStr $ "tables "++(foldr jn "." xs)++"\n"
where jn a b = a++" "++b
任何数据库操作的第一步都是连接到目标数据库。这是通过驱动程序特定的连接 API 完成的,该 API 的类型为
String -> IO Connection
给定一个连接字符串,连接 API 将返回 Connection
并将您置于 IO monad 中。
尽管大多数程序将在它们超出范围或程序结束时垃圾收集您的连接,但显式断开与数据库的连接是一个好习惯。
conn->Disconnect
运行查询通常涉及以下步骤
- 准备语句
- 使用绑定变量执行语句
- 获取结果集(如果有)
- 完成语句
HDBC 提供了两种用于绑定变量和返回结果集的方法:[ SqlValue ]
和 [ Maybe String ]
。使用 [ Maybe String ]
时,需要使用以 s 为前缀的函数,而不是 [ SqlValue ]
。[ SqlValue ]
允许您使用强类型数据,如果类型安全在您的应用程序中非常重要;否则,当处理大量数据库查询时,[ Maybe String ]
更加方便。使用 [ Maybe String ]
时,您假设数据库驱动程序将执行自动数据转换。请注意,这种便利会带来性能成本。
有时,当查询很简单时,会有一些简化的 API 将多个步骤包装在一个步骤中。例如,Run 和 sRun 是“准备和执行”的包装器。quickQuery 是“准备、执行和获取所有行”的包装器。
数据库事务由commit
和rollback
控制。但是请注意,某些数据库(例如 mysql)不支持事务。因此,每个查询都处于其原子事务中。
HDBC 提供withTransaction
,允许您自动控制一组查询的事务。