接着上一篇的教程,本章咱们继续讲SmartSql。今天的主题是动态仓储。git
老规矩,先上一个项目结构github
从第二章开始。咱们将原来的单一项目作了一个分离。方便以后的更新。ide
在这个结构中。本来上一章的DataAccess没有了。取而代之的是Repository。这个就是动态仓储的项目。接下来咱们从这个Repository项目开始说。这也是动态仓储的核心。函数
SmartSql有一个独立的动态仓储库,即:SmartSql.DyRepository。若是你想使用动态仓储,引用它就行啦。ui
引用完库,接下来就是建立咱们的第一个仓储接口—IArticleRepository。废话不到,先上代码再一一解释。spa
1 using SmartSql.DyRepository; 2 using SmartSql.DyRepository.Annotations; 3 using SmartSqlSampleChapterTwo.Entity; 4 using System.Data; 5
6 namespace SmartSqlSampleChapterTwo.Repository 7 { 8 [SqlMap(Scope = "CustomScope")] 9 public interface IArticleRepository : IRepository<T_Article, long>
10 { 11 [Statement(CommandType = CommandType.Text, Execute = ExecuteBehavior.ExecuteScalar, Id = "Offline")] 12 int OfflineArticle([Param("Id", FieldType = typeof(long))] long articleId); 13
14 [Statement(Sql = "Update T_Article Set Status = 1 Where Id = @Id")] 15 int OnlineArticle([Param("Id")] long article); 16 } 17 }
看完代码是否是发现和上一章的DataAccess有很大的区别,那些CURD的方法都没有了。code
这是SmartSql内置的一些默认接口,它包括如下这些接口,这些接口基本能够知足大部分普通业务场景了。xml
1 int Insert(TEntity entity); 2
3 int Update(TEntity entity); 4
5 [Statement(Id = "Update")] 6 int DyUpdate(object dyObj); 7
8 int Delete(object reqParams); 9
10 [Statement(Id = "Delete")] 11 int DeleteById([Param("Id")] TPrimary id); 12
13 TEntity GetEntity(object reqParams); 14
15 [Statement(Id = "GetEntity")] 16 TEntity GetById([Param("Id")] TPrimary id); 17
18 [Statement(Execute = ExecuteBehavior.ExecuteScalar)] 19 int GetRecord(object reqParams); 20
21 IList<TEntity> QueryByPage(object reqParams); 22
23 IList<TEntity> Query(object reqParams); 24
25 [Statement(Execute = ExecuteBehavior.ExecuteScalar)] 26 bool IsExist(object reqParams);
这个特性是用于指定Scope的配置。这个对应于Map中的Scope属性。这里我定义了“CustomScope”。那对应的Map中也将与之对应。以下图:blog
这个特性略微有点复杂,其中包含了6个属性,接下来咱们一个个看。教程
这个特性和SqlMap的Scope做用是同样的。区别在于Statement的级别更高。
指定此函数所使用的Statement。依据是Id。例:
// 接口定义 [Statement(Id = "TestId")] int CustomStatementId();
<!-- Statement定义 -->
<Statement Id="TestId"> db script... </Statement>
Execute是一个ExecuteBehavior枚举,用于指定此函数执行Sql脚本的方式。
Auto | ORM自动识别 |
Execute | 返回影响行数,主要用于执行写操做。 |
ExecuteScalar | 返回第一行第一列的数据,主要用于返回自增主键和获取结果数 |
Query | 返回List |
QuerySingle | 返回第一行数据 |
GetDataTable | 返回DataTable |
GetDataSet | 返回DataSet |
特殊场景下,能够直接使用此属性定义Sql脚本,而不用配置SqlMap。如IArticleRepository的OnlineArticle定义。
这个属性是ADO.NET的CommandType枚举。做用也彻底相同
指定数据源,能够指定Write或Read。
在上一章节中,咱们在Startup中注册了SmartSql,如今咱们要继续注册动态仓储。代码也很简单,只要在AddSmart方法完成后继续调用AddRepositoryFromAssembly便可。以下:
services.AddSmartSql(builder => { builder.UseAlias("SmartSqlSampleChapterTwo"); // 定义实例别名,在多库场景下适用。 //.UseXmlConfig(ResourceType.File,"MyConfig.xml");
}).AddRepositoryFromAssembly(options => { // SmartSql实例的别名
options.SmartSqlAlias = "SmartSqlSampleChapterTwo"; // 仓储接口所在的程序集全称
options.AssemblyString = "SmartSqlSampleChapterTwo.Repository"; // 筛选器,根据接口的Type筛选须要的仓储
options.Filter = type => type.FullName.Contains("Sample"); // Scope模板,默认是"I{Scope}Repository"
options.ScopeTemplate = "I{Scope}Repository"; });
这个方法中会抛出一个AssemblyAutoRegisterOptions,方便用户注册指定的仓储。
在Sample中,咱们直接让Controller引用了Repository,实际场景中。咱们能够在任何须要仓储的地方引用仓储。代码以下:
using Microsoft.AspNetCore.Mvc; using SmartSqlSampleChapterTwo.Entity; using SmartSqlSampleChapterTwo.Repository; using System.Collections.Generic; namespace SmartSqlSampleChapterTwo.Api.Controllers { /// <summary>
///
/// </summary>
[Route("[controller]/[action]")] public class ArticleController : Controller { private readonly IArticleRepository _articleRepository; /// <summary>
/// constructor /// </summary>
/// <param name="articleRepository"></param>
public ArticleController(IArticleRepository articleRepository) { _articleRepository = articleRepository; } /// <summary>
///
/// </summary>
/// <param name="article"></param>
/// <returns></returns>
[HttpPost] public T_Article Add([FromBody] T_Article article) { article.Id = _articleRepository.Insert(article); return article; } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet] public T_Article Get([FromQuery] long id) { return _articleRepository.GetById(id); } /// <summary>
///
/// </summary>
/// <param name="article"></param>
/// <returns></returns>
[HttpPost] public bool Update([FromBody] T_Article article) { return _articleRepository.Update(article) > 0; } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="status"></param>
/// <returns></returns>
[HttpPost] public bool UpdateStatus([FromQuery] long id, [FromQuery] int status) { return _articleRepository.DyUpdate(new { Id = id, Status = status }) > 0; } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet] public bool IsExist([FromQuery] long id) { return _articleRepository.IsExist(new { Id = id }); } /// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
[HttpGet] public IEnumerable<T_Article> Query([FromQuery] string key = "") { return _articleRepository.Query(new { Title = key }); } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet] public int Offline([FromQuery] long id) { return _articleRepository.OfflineArticle(id); } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet] public int Online([FromQuery] long id) { return _articleRepository.OnlineArticle(id); } } }
能够注意到的是,除了把DataAccess变成了Repository。其余的代码几乎没有改动。最后我还添加了仓储自定义的接口的调用。
今天,咱们了解了动态仓储的使用。它是一个很是方便的特性,能够很是显著的提高咱们写代码的效率,减小必定的代码量,避免了不少“体力活”。让咱们专一于业务!
下期预告:SmartSql中的事务,及AOP的使用