Rafy 框架 - 执行SQL或存储过程

简介:

有时候,开发者不想通过实体来操作数据库,而是希望通过 SQL 语句或存储过程来直接访问数据库。Rafy 也提供了一组 API 来方便实现这类需求。

 

IDbAccesser 接口


为了尽量屏蔽各数据库中 SQL 语句参数的不同标识,同时也为了使开发者更简单地实现参数化的查询。Rafy 中提供了 IDbAccesser 接口来方便开发者使用。接口定义如下:

/// <summary>
/// A db accesser which can use formatted sql to communicate with data base.
/// </summary>
public interface IDbAccesser : IDisposable
{
    /// <summary>
    /// The underlying db connection
    /// </summary>
    IDbConnection Connection { get; }

    /// <summary>
    /// 数据连接结构
    /// </summary>
    DbConnectionSchema ConnectionSchema { get; }

    /// <summary>
    /// Gets a raw accesser which is oriented to raw sql and <c>IDbDataParameter</c>。
    /// </summary>
    IRawDbAccesser RawAccesser { get; }

    /// <summary>
    /// Execute a sql which is not a database procudure, return rows effected.
    /// </summary>
    /// <param name="formattedSql">a formatted sql which format looks like the parameter of String.Format</param>
    /// <param name="parameters">If this sql has some parameters, these are its parameters.</param>
    /// <returns>The number of rows effected.</returns>
    int ExecuteText(string formattedSql, params object[] parameters);

    /// <summary>
    /// Execute the sql, and return the element of first row and first column, ignore the other values.
    /// </summary>
    /// <param name="formattedSql">a formatted sql which format looks like the parameter of String.Format</param>
    /// <param name="parameters">If this sql has some parameters, these are its parameters.</param>
    /// <returns>DBNull or value object.</returns>
    object QueryValue(string formattedSql, params object[] parameters);

    /// <summary>
    /// Query out some data from database.
    /// </summary>
    /// <param name="formattedSql">a formatted sql which format looks like the parameter of String.Format</param>
    /// <param name="parameters">If this sql has some parameters, these are its parameters.</param>
    /// <returns></returns>
    IDataReader QueryDataReader(string formattedSql, params object[] parameters);

    /// <summary>
    /// Query out some data from database.
    /// </summary>
    /// <param name="formattedSql">a formatted sql which format looks like the parameter of String.Format</param>
    /// <param name="closeConnection">Indicates whether to close the corresponding connection when the reader is closed?</param>
    /// <param name="parameters">If this sql has some parameters, these are its parameters.</param>
    /// <returns></returns>
    IDataReader QueryDataReader(string formattedSql, bool closeConnection, params object[] parameters);

    /// <summary>
    /// Query out a row from database.
    /// If there is not any records, return null.
    /// </summary>
    /// <param name="formattedSql">a formatted sql which format looks like the parameter of String.Format</param>
    /// <param name="parameters">If this sql has some parameters, these are its parameters.</param>
    /// <returns></returns>
    DataRow QueryDataRow(string formattedSql, params object[] parameters);

    /// <summary>
    /// Query out a DataTable object from database by the specific sql.
    /// </summary>
    /// <param name="formattedSql">a formatted sql which format looks like the parameter of String.Format</param>
    /// <param name="parameters">If this sql has some parameters, these are its parameters.</param>
    /// <returns></returns>
    DataTable QueryDataTable(string formattedSql, params object[] parameters);

    /// <summary>
    /// Query out a row from database.
    /// If there is not any records, return null.
    /// </summary>
    /// <param name="formattedSql">a formatted sql which format looks like the parameter of String.Format</param>
    /// <param name="parameters">If this sql has some parameters, these are its parameters.</param>
    /// <returns></returns>
    LiteDataRow QueryLiteDataRow(string formattedSql, params object[] parameters);

    /// <summary>
    /// Query out a DataTable object from database by the specific sql.
    /// </summary>
    /// <param name="formattedSql">a formatted sql which format looks like the parameter of String.Format</param>
    /// <param name="parameters">If this sql has some parameters, these are its parameters.</param>
    /// <returns></returns>
    LiteDataTable QueryLiteDataTable(string formattedSql, params object[] parameters);
}

 

该接口使用类似于 String.Format 中的字符串格式来表达 SQL 中的参数。并在连接不同的数据库时,生成相应数据库对应的参数格式。

具体使用方法如下:

执行查询代码示例:

var bookRepo = RF.Concrete<BookRepository>();
using (var dba = DbAccesserFactory.Create(bookRepo))
{
    DataTable table = dba.QueryDataTable("SELECT * FROM Books WHERE id > {0}", 0);
}

 

执行非查询代码示例:

var bookRepo = RF.Concrete<BookRepository>();
using (var dba = DbAccesserFactory.Create(bookRepo))
{
    int linesAffected = dba.ExecuteText("DELETE FROM Books WHERE id > {0}", 0);
}

 

另外,DbAccesserFactory 中也提供了不通过仓库对象,而直接使用‘数据库连接的配置名’进行构建的方法,例如:

using (var dba = DbAccesserFactory.Create("JXC"))
{
    int linesAffected = dba.ExecuteText("DELETE FROM Books WHERE id > {0}", 0);
}

 

参数过多时,则依次按顺序传入即可:

using (var dba = DbAccesserFactory.Create(bookRepo))
{
    for (int i = 0; i < 10; i++)
    {
        dba.ExecuteText(
        "INSERT INTO Book (Author,BookCategoryId,BookLocId,Code,Content,Name,Price,Publisher) VALUES ({0},{1},{2},{3},{4},{5},{6},{7})",
        string.Empty,
        null,
        null,
        string.Empty,
        string.Empty,
        i.ToString(),
        null,
        string.Empty
        );
    }
}

 

IRawDbAccesser 接口


由于 IDbAccesser 接口封装了 SQL 语句中参数对应不同数据库中名称的变化,同时也更方便开发者使用,所以一般情况下,都推荐使用该接口。但是,IDbAccesser 接口并不支持存储过程的调用。另外,有时开发者希望自己来构建原生的 SQL 语句和参数,这时,就需要用到 IRawDbAccesser 接口了。(接口定义过长,这里不再贴出。)

该接口的使用方法与 IDbAccesser 类似,不同的地方在于 SQL 中需要传入特定数据库的参数名,并且参数需要自行构造,例如:

using (var dba = DbAccesserFactory.Create(bookRepo))
{
    for (int i = 0; i < 10; i++)
    {
        dba.RawAccesser.ExecuteText(
            "INSERT INTO Book (Author,BookCategoryId,BookLocId,Code,Content,Name,Price,Publisher,Id) VALUES ('', NULL, NULL, '', '', :p0, NULL, '', :p1)",
            dba.RawAccesser.ParameterFactory.CreateParameter("p0", i),
            dba.RawAccesser.ParameterFactory.CreateParameter("p1", i)
            );
    }
}

 

另外,IRawDbAccesser 接口也可以使用存储过程了,例如:

using (var dba = DbAccesserFactory.Create(bookRepo))
{
    for (int i = 0; i < 10; i++)
    {
        dba.RawAccesser.ExecuteProcedure(
            "InsertBookProcedure",
            dba.RawAccesser.ParameterFactory.CreateParameter("p0", i),
            dba.RawAccesser.ParameterFactory.CreateParameter("p1", i)
            );
    }
}

 


本文转自BloodyAngel博客园博客,原文链接:http://www.cnblogs.com/zgynhqf/p/4925195.html,如需转载请自行联系原作者

相关文章
|
5月前
|
SQL XML Java
配置Spring框架以连接SQL Server数据库
最后,需要集成Spring配置到应用中,这通常在 `main`方法或者Spring Boot的应用配置类中通过加载XML配置或使用注解来实现。
483 0
|
7月前
|
存储 SQL 数据库连接
C#程序调用Sql Server存储过程异常处理:调用存储过程后不返回、不抛异常的解决方案
本文分析了C#程序操作Sql Server数据库时偶发的不返回、不抛异常问题,并提出了解决思路。首先解析了一个执行存储过程的函数`ExecuteProcedure`,其功能是调用存储过程并返回影响行数。针对代码执行被阻塞但无异常的情况,文章总结了可能原因,如死锁、无限循环或网络问题等。随后提供了多种解决方案:1) 增加日志定位问题;2) 使用异步操作提升响应性;3) 设置超时机制避免阻塞;4) 利用线程池分离主线程;5) 通过信号量同步线程;6) 监控数据库连接状态确保可用性。这些方法可有效应对数据库操作中的潜在问题,保障程序稳定性。
589 11
|
SQL 安全 Java
除了Flask框架,还有哪些框架能防止SQL注入攻击?
这些框架都在安全方面有着较好的表现,通过它们的内置机制和安全特性,可以有效地降低 SQL 注入攻击的风险。然而,无论使用哪个框架,开发者都需要具备良好的安全意识,正确配置和使用框架提供的安全功能,以确保应用的安全可靠。同时,持续关注安全更新和漏洞修复也是非常重要的。
553 162
|
SQL 监控 安全
Flask 框架防止 SQL 注入攻击的方法
通过综合运用以上多种措施,Flask 框架可以有效地降低 SQL 注入攻击的风险,保障应用的安全稳定运行。同时,持续的安全评估和改进也是确保应用长期安全的重要环节。
515 71
|
9月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
SQL 存储 人工智能
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
Vanna 是一个开源的 Python RAG(Retrieval-Augmented Generation)框架,能够基于大型语言模型(LLMs)为数据库生成精确的 SQL 查询。Vanna 支持多种 LLMs、向量数据库和 SQL 数据库,提供高准确性查询,同时确保数据库内容安全私密,不外泄。
1713 7
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
|
11月前
|
SQL 分布式计算 Java
Spark SQL向量化执行引擎框架Gluten-Velox在AArch64使能和优化
本文摘自 Arm China的工程师顾煜祺关于“在 Arm 平台上使用 Native 算子库加速 Spark”的分享,主要内容包括以下四个部分: 1.技术背景 2.算子库构成 3.算子操作优化 4.未来工作
1513 0
|
10月前
|
存储 Java 关系型数据库
java调用mysql存储过程
在 Java 中调用 MySQL 存储过程主要借助 JDBC(Java Database Connectivity)。其核心原理是通过 JDBC 与 MySQL 建立连接,调用存储过程并处理结果。具体步骤包括:加载 JDBC 驱动、建立数据库连接、创建 CallableStatement 对象、设置存储过程参数并执行调用。此过程实现了 Java 程序与 MySQL 数据库的高效交互。
|
9月前
|
存储 关系型数据库 MySQL
【YashanDB知识库】MySQL返回结果集的存储过程的改写方法
本文介绍了将MySQL存储过程改写至YashanDB的解决方案。由于MySQL存储过程可直接返回结果集,而YashanDB需通过返回SYS_REF_CURSOR的函数实现类似功能,因此需要对代码进行转换。示例中展示了如何将MySQL存储过程`proc1`改写为YashanDB函数,并调整JDBC应用代码以适配REF_CURSOR输出参数,从而正确获取查询结果。此方法确保了跨数据库场景下的兼容性与功能性。
|
存储 SQL NoSQL