一、引言

  接着上一篇的教程,本章我们继续讲SmartSql。今天的主题是动态仓储。

  老规矩,先上一个项目结构

  从第二章开始。我们将原来的单一项目做了一个分离。方便之后的更新。

  在这个结构中。原本上一章的DataAccess没有了。取而代之的是Repository。这个就是动态仓储的项目。接下来我们从这个Repository项目开始说。这也是动态仓储的核心。

二、Repository项目

1. Nuget依赖

  SmartSql有一个独立的动态仓储库,即:SmartSql.DyRepository。如果你想使用动态仓储,引用它就行啦。

2. 第一个仓储接口

  引用完库,接下来就是创建我们的第一个仓储接口—IArticleRepository。废话不到,先上代码再一一解释。

 using SmartSql.DyRepository;
using SmartSql.DyRepository.Annotations;
using SmartSqlSampleChapterTwo.Entity;
using System.Data; namespace SmartSqlSampleChapterTwo.Repository
{
[SqlMap(Scope = "CustomScope")]
public interface IArticleRepository : IRepository<T_Article, long>
{
[Statement(CommandType = CommandType.Text, Execute = ExecuteBehavior.ExecuteScalar, Id = "Offline")]
int OfflineArticle([Param("Id", FieldType = typeof(long))] long articleId); [Statement(Sql = "Update T_Article Set Status = 1 Where Id = @Id")]
int OnlineArticle([Param("Id")] long article);
}
}

IArticleRepository

2.1 默认接口 IRepository

  看完代码是不是发现和上一章的DataAccess有很大的区别,那些CURD的方法都没有了。

  这是SmartSql内置的一些默认接口,它包括以下这些接口,这些接口基本可以满足大部分普通业务场景了。

 int Insert(TEntity entity);

 int Update(TEntity entity);

 [Statement(Id = "Update")]
int DyUpdate(object dyObj); int Delete(object reqParams); [Statement(Id = "Delete")]
int DeleteById([Param("Id")] TPrimary id); TEntity GetEntity(object reqParams); [Statement(Id = "GetEntity")]
TEntity GetById([Param("Id")] TPrimary id); [Statement(Execute = ExecuteBehavior.ExecuteScalar)]
int GetRecord(object reqParams); IList<TEntity> QueryByPage(object reqParams); IList<TEntity> Query(object reqParams); [Statement(Execute = ExecuteBehavior.ExecuteScalar)]
bool IsExist(object reqParams);

2.2 SqlMap特性

  这个特性是用于指定Scope的配置。这个对应于Map中的Scope属性。这里我定义了“CustomScope”。那对应的Map中也将与之对应。如下图:

  

2.3 Statement特性

  这个特性略微有点复杂,其中包含了6个属性,接下来我们一个个看。

2.3.1 Scope

  这个特性和SqlMap的Scope作用是一样的。区别在于Statement的级别更高。

2.3.2 Id

  指定此函数所使用的Statement。依据是Id。例:

// 接口定义
[Statement(Id = "TestId")]
int CustomStatementId();
<!-- Statement定义 -->
<Statement Id="TestId">
db script...
</Statement>

2.3.3 Execute

  Execute是一个ExecuteBehavior枚举,用于指定此函数执行Sql脚本的方式。

ExecuteBehavior
Auto ORM自动识别
Execute 返回影响行数,主要用于执行写操作。
ExecuteScalar 返回第一行第一列的数据,主要用于返回自增主键和获取结果数
Query 返回List
QuerySingle 返回第一行数据
GetDataTable 返回DataTable
GetDataSet 返回DataSet

  

2.3.4 Sql

  特殊场景下,可以直接使用此属性定义Sql脚本,而不用配置SqlMap。如IArticleRepository的OnlineArticle定义。

2.3.5 CommandType

  这个属性是ADO.NET的CommandType枚举。作用也完全相同

2.3.6 SourceChoice

  指定数据源,可以指定Write或Read。

3. Startup

  在上一章节中,我们在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,方便用户注册指定的仓储。

4. Controller的变化

  在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) > ;
} /// <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
}) > ;
} /// <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);
}
}
}

ArticleController

  可以注意到的是,除了把DataAccess变成了Repository。其他的代码几乎没有改动。最后我还添加了仓储自定义的接口的调用。

5. 结语

  今天,我们了解了动态仓储的使用。它是一个非常方便的特性,可以非常显著的提升我们写代码的效率,减少一定的代码量,避免了很多“体力活”。让我们专注于业务!

示例代码链接在这里

下期预告:SmartSql中的事务,及AOP的使用

SmartSql使用教程(2)——使用动态代理实现CURD的更多相关文章

  1. SmartSql使用教程(1)——初探,建立一个简单的CURD接口服务

    一.引言 最近SmartSql被正式引入到了NCC,借着这个契机写一个使用教程系列 二.SmartSql简介[摘自官方文档] 1. SmartSql是什么? SmartSql = MyBatis + ...

  2. SmartSql 动态代理仓储

    SmartSql 动态代理仓储,一个高生产力的组件.该组件看似很难懂,实际上仅做了映射Statement,转发请求的功能.但却意义重大. SmartSql提供了一个通用泛型仓储接口 SmartSql. ...

  3. Java动态代理之InvocationHandler最简单的入门教程

    网上关于Java的动态代理,Proxy和InvocationHandler这些概念有讲解得非常高深的文章.其实这些概念没有那么复杂.现在咱们通过一个最简单的例子认识什么是InvocationHandl ...

  4. 8、Spring教程之静态代理/动态代理

    为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 学习aop之前 , 我们要先了解一下代理模式! 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象 ...

  5. 【Spring Framework】Spring入门教程(五)AOP思想和动态代理

    本文主要讲解内容如下: Spring的核心之一 - AOP思想 (1) 代理模式- 动态代理 ① JDK的动态代理 (Java官方) ② CGLIB 第三方代理 AOP概述 什么是AOP(面向切面编程 ...

  6. 【译】11. Java反射——动态代理

    原文地址:http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html 博主最近比较忙,争取每周翻译四篇.等不急的请移步原文网页. ...

  7. 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)

    黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...

  8. SmartSql使用教程(3)——SmartSql中的事务,及AOP的使用

    一.引言 经过两章的铺垫,我们现在对SmartSql已经有了一定的了解,那么今天我们的主题是事务处理.事务处理是常用的一种特性,而SmartSql至少提供了两种使用事务的方法.一种是通过Reposit ...

  9. Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理

    面试问题:Java里的代理设计模式(Proxy Design Pattern)一共有几种实现方式?这个题目很像孔乙己问"茴香豆的茴字有哪几种写法?" 所谓代理模式,是指客户端(Cl ...

随机推荐

  1. Swift 学习笔记 (继承)

    一个类可以从另一个类继承方法.属性和其他的特性.当一个类从另一个类继承的时候,继承的类就是所谓的子类,而这个类继承的类被称为父类. 在 Swift 中类可以调用和访问属于它们父类的方法.属性和下标脚本 ...

  2. vi中如何替换某字符成“回车”?

    vi中如何替换某字符成“回车”? 在 vi 中::s/,/^M/g (you need to type CTRL-V <CR> to get a ^M here)VIM - Vi IMpr ...

  3. Android 虚拟机 程序安装目录

    Android应用安装涉及到如下几个目录:system/app系统自带的应用程序,无法删除.data/app用户程序安装的目录,有删除权限.安装时把apk文件复制到此目录.data/data存放应用程 ...

  4. CMake最好的学习资料

    本文为转载,阅读不友好,请先查看原文:https://blog.gmem.cc/cmake-study-note 收下为原文内容================> 基础知识 CMake简介 CM ...

  5. POJ题目算法分类总结博客地址

    http://blog.csdn.net/sunbaigui/article/details/4421705 又从这个地址找了一些:http://blog.csdn.net/koudaidai/art ...

  6. Android SDK离线安装方法详解(加速安装)

    AndroidSDK在国内下载一直很慢··有时候通宵都下不了一点点,最后只有选择离线安装,现在发出离线安装地址和方法,希望对大家有帮助 一,首先下载SDK的安装包,android-sdk_r10-wi ...

  7. Proftpd mysql认证配置文档

    Proftpd mysql认证配置文档 ver1.0, 2012/09/25 一.下载安装proftp mysql 下载 wget http://cloud.github.com/downloads/ ...

  8. CodeForces - 767A Snacktower

    题目大意 一个数可以被输出当且仅当所有比它大的数都已经输出.输入一个1~n的排列,求每次输出的输出序列. 题解 直接用堆模拟 #include <queue> #include <c ...

  9. linux下Redis以及c++操作

    使用不同的语言,redis支持不同的编程语言,但是调用了不同的redis包,例如: java对应jedis: php对应phpredis: C++对应的则是hredis. 安装Redis 上篇博客已经 ...

  10. select查询语句执行顺序

    查询中用到的关键词主要包含六个,并且他们的顺序依次为select--from--where--group by--having--order by其中select和from是必须的,其他关键词是可选的 ...