你必须知道的 SmartSql !
介绍
SmartSql = MyBatis + Cache(Memory | Redis) + R/W Splitting +Dynamic Repository + Diagnostics ......
简洁、高效、高性能、扩展性、监控、渐进式开发!
她是如何工作的?
SmartSql 借鉴了 MyBatis 的思想,使用 XML 来管理 SQL ,并且提供了若干个筛选器标签来消除代码层面的各种 if/else 的判断分支。
SmartSql将管理你的 SQL ,并且通过筛选标签来维护本来你在代码层面的各种条件判断,使你的代码更加优美。
为什么选择 SmartSql ?
DotNet 体系下大都是 Linq 系的 ORM,Linq 很好,消除了开发人员对 SQL 的依赖。
但却忽视了一点,SQL 本身并不复杂,而且在复杂查询场景当中开发人员很难通过编写Linq来生成良好性能的SQL,相信使用过EF的同学一定有这样的体验:“我想好了Sql怎么写,然后再来写Linq,完了可能还要再查看一下Linq输出的Sql是什么样的“。这是非常糟糕的体验。要想对Sql做绝对的优化,那么开发者必须对Sql有绝对的控制权。另外Sql本身很简单,为何要增加一层翻译器呢?
SmartSql 从正式开源已历经俩年多的时间,在生产环境经过若干个微服务验证。
同时也有一部分企业正在使用 SmartSql (如果您也在使用 SmartSql 欢迎提交issue)Who is using SmartSql。
目前已加入 NCC。
未来(Roadmap-2019) SmartSql 也会持续加入一些新的特性来帮助开发者提升效率。欢迎提交 Issue https://github.com/dotnetcore/SmartSql/issues。
那么为什么不是 Dapper,或者 DbHelper ?
Dapper 确实很好,并且又很好的性能,但是会让给你的代码里边充斥着 SQL 和各种判断分支,这些将会使代码维护难以阅读和维护。另外 Dapper 只提供了DataReader 到 Entity 的反序列化功能。而 SmartSql 提供了大量的特性来提升开发者的效率。
特性概览
动态仓储
动态代理仓储(SmartSql.DyRepository)组件是 SmartSql 非常独特的功能,它能简化 SmartSql 的使用。对业务代码几乎没有侵入。可以说使用 ISqlMapper 是原始方法,而 DyRepository 自动帮你实现这些方法。
DyRepository 的表现是只需要定义仓储接口,通过简单配置就能自动实现这些接口并注册到 IoC 容器中,使用时注入即刻获取实现。原理是通过接口和接口方法的命名规则来获取 SmartSql 的 xml 文件中的 Scope 和 SqlId ,用接口方法的参数作为 Request ,通过 xml 中的 sql 自动判断是查询还是执行操作,最后实现对 ISqlMapper 的调用。
0. 定义仓储接口
public interface IUserRepository : IRepository<User, long>
{
}
1. 注入依赖
services.AddSmartSql()
.AddRepositoryFromAssembly(options => { options.AssemblyString = "SmartSql.Starter.Repository"; });
2. 使用
public class UserService
{
IUserRepository userRepository;
public UserService(IActivityRepository userRepository)
{
this.userRepository = userRepository;
}
}
SmartSql 最佳实践 -> SmartCode
通过 SmartCode 开发人员仅需配置好数据库连接即可生成解决方案所需的一切,包括但不限于:
- 解决方案工程
- 帮你 restore 一下
ReStore:
Type: Process
Parameters:
FileName: powershell
WorkingDirectory: '{{Project.Output.Path}}'
Args: dotnet restore
- Docker
- 构建 Docker 镜像 & 运行实例
BuildDocker:
Type: Process
Parameters:
FileName: powershell
WorkingDirectory: '{{Project.Output.Path}}'
Args: docker build -t {{Project.Parameters.DockerImage}}:v1.0.0 .
RunDocker:
Type: Process
Parameters:
FileName: powershell
WorkingDirectory: '{{Project.Output.Path}}'
Args: docker run --name {{Project.Parameters.DockerImage}} --rm -d -p 8008:80 {{Project.Parameters.DockerImage}}:v1.0.0 .
- 顺便开启个浏览器
RunChrome:
Type: Process
Parameters:
FileName: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
CreateNoWindow: false
Args: http://localhost:8008/swagger
Docker
SmartCode 生成的目录结构
读写分离
SmartSql 读写分离特别简便,仅需提供好配置即可:
<Database>
<DbProvider Name="PostgreSql"/>
<Write Name="WriteDB" ConnectionString="${Master}"/>
<Read Name="ReadDb-1" ConnectionString="${Slave-0}" Weight="100"/>
<Read Name="ReadDb-2" ConnectionString="${Slave-1}" Weight="100"/>
</Database>
缓存
- Lru 最近最少使用算法
- Fifo 先进先出算法
- RedisCacheProvider
- 其他继承自ICacheProvider缓存类型均可
<Caches>
<Cache Id="LruCache" Type="Lru">
<Property Name="CacheSize" Value="10"/>
<FlushOnExecute Statement="AllPrimitive.Insert"/>
<FlushInterval Hours="1" Minutes="0" Seconds="0"/>
</Cache>
<Cache Id="FifoCache" Type="Fifo">
<Property Name="CacheSize" Value="10"/>
</Cache>
<Cache Id="RedisCache" Type="${RedisCacheProvider}">
<Property Name="ConnectionString" Value="${Redis}" />
<FlushInterval Seconds="60"/>
</Cache>
</Caches>
<Statement Id="QueryByLruCache" Cache="LruCache">
SELECT Top 6 T.* From T_User T;
</Statement>
类型处理器
SmartSql 内部实现了 DotNet 主要类型的类型处理器,并且提供了部分类型兼容的类型转换处理器,同时还提供了比较常用的 JsonTypeHanlder 。
<TypeHandler PropertyType="SmartSql.Test.Entities.UserInfo,SmartSql.Test" Type="${JsonTypeHandler`}">
<Properties>
<Property Name="DateFormat" Value="yyyy-MM-dd mm:ss"/>
<Property Name="NamingStrategy" Value="Camel"/>
</Properties>
</TypeHandler>
CUD 代码生成
SmartSql 同时提供了 CUD 扩展函数帮助开发者生成好 CUD-SQL ,方便开发者直接使用,无需编写任何配置。
public static TEntity GetById<TEntity, TPrimaryKey>(this ISqlMapper);
public static TPrimaryKey Insert<TEntity, TPrimaryKey>(this ISqlMapper sqlMapper, TEntity entity);
public static int DyUpdate<TEntity>(this ISqlMapper sqlMapper, object entity);
public static int Update<TEntity>(this ISqlMapper sqlMapper, TEntity entity);
public static int DeleteById<TEntity, TPrimaryKey>(this ISqlMapper sqlMapper, TPrimaryKey id);
public static int DeleteMany<TEntity, TPrimaryKey>(this ISqlMapper sqlMapper, IEnumerable<TPrimaryKey> ids);
Id 生成器
SnowflakeId
<IdGenerators>
<IdGenerator Name="SnowflakeId" Type="SnowflakeId">
<Properties>
<Property Name="WorkerIdBits" Value="10"/>
<Property Name="WorkerId" Value="888"/>
<Property Name="Sequence" Value="1"/>
</Properties>
</IdGenerator>
</IdGenerators>
<Statement Id="Insert">
<IdGenerator Name="SnowflakeId" Id="Id"/>
INSERT INTO T_UseIdGenEntity
(
Id,
Name
)
VALUES
(
@Id,
@Name
);
Select @Id;
</Statement>
var id = SqlMapper.ExecuteScalar<long>(new RequestContext
{
Scope = nameof(UseIdGenEntity),
SqlId = "Insert",
Request = new UseIdGenEntity()
{
Name = "SmartSql"
}
});
DbSequence
<IdGenerators>
<IdGenerator Name="DbSequence" Type="DbSequence">
<Properties>
<Property Name="Step" Value="10"/>
<Property Name="SequenceSql" Value="Select Next Value For IdSequence;"/>
</Properties>
</IdGenerator>
</IdGenerators>
<Statement Id="InsertByDbSequence">
<IdGenerator Name="DbSequence" Id="Id"/>
INSERT INTO T_UseIdGenEntity
(
Id,
Name
)
VALUES
(
@Id,
@Name
);
Select @Id;
</Statement>
var id = SqlMapper.ExecuteScalar<long>(new RequestContext
{
Scope = nameof(UseIdGenEntity),
SqlId = "InsertByDbSequence",
Request = new UseIdGenEntity()
{
Name = "SmartSql"
}
});
AOP 事务
[Transaction]
public virtual long AddWithTran(User user)
{
return _userRepository.Insert(user);
}
事务嵌套
当出现事务嵌套时,子函数的事务特性注解将不再开启,转而使用上级调用函数的事务
[Transaction]
public virtual long AddWithTranWrap(User user)
{
return AddWithTran(user);
}
BulkInsert
using (var dbSession= SqlMapper.SessionStore.Open())
{
var data = SqlMapper.GetDataTable(new RequestContext
{
Scope = nameof(AllPrimitive),
SqlId = "Query",
Request = new { Taken = 100 }
});
data.TableName = "T_AllPrimitive";
IBulkInsert bulkInsert = new BulkInsert(dbSession);
bulkInsert.Table = data;
bulkInsert.Insert();
}
Skywalking 监控
SmartSql 目前支持 Skywalking 监控,通过安装 SkyAPM-dotnet 代理来启用。以下是部分截图。
监控执行命令
查看是否缓存,以及返回的记录数
查看执行的SQL语句
事务
异常
异常堆栈跟踪
示例项目
技术交流
点击链接加入QQ群【SmartSql 官方交流群】:604762592
了解更多,请移步官方文档
你必须知道的 SmartSql !的更多相关文章
- 程序员必须要知道的Hadoop的一些事实
程序员必须要知道的Hadoop的一些事实.现如今,Apache Hadoop已经无人不知无人不晓.当年雅虎搜索工程师Doug Cutting开发出这个用以创建分布式计算机环境的开源软...... 1: ...
- 【转载】在IT界取得成功应该知道的10件事
在IT界取得成功应该知道的10件事 2011-08-11 13:31:30 分类: 项目管理 导读:前面大多数文章都是Jack Wallen写的,这是他的新作,看来要成为NB程序员还要不停的自我总结 ...
- 理工科应该的知道的C/C++数学计算库(转)
理工科应该的知道的C/C++数学计算库(转) 作为理工科学生,想必有限元分析.数值计算.三维建模.信号处理.性能分析.仿真分析...这些或多或少与我们常用的软件息息相关,假如有一天你只需要这些大型软件 ...
- 你应该知道的10个奇特的 HTML5 单页网站
网页设计师努力寻找新的方式来展现内容.其中一个大的趋势是单页网站,现在被世界上的一些大的品牌广泛采用,使用它们来为用户提供一个快速,干净和简单的而且美丽的网站. 下面是10个令人惊叹的单页 H ...
- Git / 程序员需要知道的12个Git高级命令
众所周知,Git目前已经是分布式版本控制领域的翘楚,围绕着Git形成了完整的生态圈.学习Git,首先当然是学习Git的基本工作流.相比于SVN等传统版本控制系统来说,Git是专为分布式版本控制而生的强 ...
- 你应该知道的RPC原理
你应该知道的RPC原理 在学校期间大家都写过不少程序,比如写个hello world服务类,然后本地调用下,如下所示.这些程序的特点是服务消费方和服务提供方是本地调用关系. 而一旦踏入公司尤其是大型互 ...
- 希望早几年知道的5个Unix命令
原文: http://spin.atomicobject.com/2013/09/09/5-unix-commands/ 希望早几年知道的5个Unix命令 使用*nix系统已经有一段时间了.但是还是有 ...
- 关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造)
关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造) 摘要:在中文搜索中的标点.符号往往也是有语义的,比如我们要搜索“C++”或是“C#”,我们不希望搜索出来的全是“C”吧?那样对程 ...
- 对于JavaScript的函数.NET开发人员应该知道的11件事
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 昨天小感冒今天重感冒,也不能长篇大论.如果你是.NET开发人员,在进入前端开发领域的时候,对 ...
随机推荐
- 详解Trie
一.Trie的概念 Trie又称字典树,前缀树(事实上前缀树这个名字就很好的解释了Trie的储存方式) 来一张图理解一下Trie的储存方式:(图片来自百度百科) 由这张图我们也可以知道Trie的特点: ...
- JavaScript(三、DOM文档对象模型)
一.什么是DOM DOM 是 Document Object Model(文档对象模型)的缩写. DOM 是 W3C(万维网联盟)的标准. DOM 定义了访问 HTML 和 XML 文档的标准: &q ...
- Scrapy爬虫框架补充内容一(Linux环境)
Scrapy爬虫框架结构及工作原理详解 scrapy框架的框架结构如下: 组件分析: ENGINE:(核心):处理整个框架的数据流,各个组件在其控制下协同工作 SCHEDULER(调度器):负责接收引 ...
- React入门一
React.js算是当今主流框架之一了,好多公司项目都是React.直接上图: 所以最近整合一些论坛,今儿咱就说说React, React 是一个用于构建用户界面的 JAVASCRIPT 库. Rea ...
- Js的String对象
Js的String对象常用方法: 方法一.得到某字符在字符串中的索引位置. str.indexOf(findStr,[index])--返回的是要查找字符在字符串中的位置索引 ,index开始查找 ...
- cmd连接Oracle数据库成功后输入sql语句返回 2
解决办法 : sql语句后一定要跟分号 .
- Redis之实战篇(与Mybatis整合)
摘要: 现在市面流行的java框架,一个是ssh(spring.struts2.hibernate),另一个是ssm(spring.springmvc.mybatis),由于之前已经有整合过ssm框架 ...
- vector的内存分配问题
vector的内存增长问题,其实无非是vector中size()和capacity()问题.vector的一个缺点就是它的内存分配是按照2的倍数分配内存的.当当前容量对插入元素不够时,分配一块新的内存 ...
- window安装mysql5.7解压版(解决乱码问题)
♣安装mysql两种方法 ♣下载mysql5.7解压版 ♣配置步骤 ♣解决服务无法启动 ♣解决乱码 1.安装mysql两种方法 MySQL安装文件分为两种,一种是msi格式的,一种是zip格式的.如果 ...
- 好代码是管出来的——使用Git来管理源代码
软件开发过程中一个重要的产出就是代码,软件的编码过程一般是由一个团队共同完成,它是一个并行活动,为了保证代码在多人开发中能够顺利完成,我们需要使用代码版本控制工具来对代码进行统一存储,并追踪每一份代码 ...