本文涉及的内容,一样适用于3.0版本,不用修改。html
一、@LearningCoding 小伙伴关于用Sqlsugar在mysql数据库上的研究成果:前端
sqlsugarcore支持mysql等数据库,在DbContext里面只须要设置dbtype为mysql便可,可是mysql8.0以上是个坑,会出现caching_sha2_password的错误,是由于root的密码类型问题,改起来挺麻烦的,因此建议使用mysql的时候安装5.6版本的便可,其余代码不须要改动。mysql
书接上文:前几次文章中,咱们花了三天的时间简单了解了下接口文档Swagger框架,已经彻底解放了咱们的之前的Word说明文档,而且能够在线进行调试,并且当项目开始之中,咱们能够定义一些空的接口,或者能够返回假数据,这样真正达到了先后端不等待的缺陷,仍是很不错的,固然,这离我说的先后端分离仍是相差甚远,今天呢,咱们就简单搭建下咱们的项目架构。git
本项目是我本身的一个真实项目,数据都是真实的,以前搭建过一个MVC + EF Code First的项目,本项目就是基于这个了,前一段时间我已经搭建起来了,是这样的,本系列教程会从新开始。github
先简单解释下各层之间的调用关系:sql
除了项目对外暴露的是 Api 展现层,和核心的实体 Model 层外,数据库
仓储模块(做为一个数据库管理员,直接操做数据库,实体模型):json
BaseRepository(基类仓储) 继承实现了 接口IBaseRepository,这里放公共的方法,
AdvertisementRepostitory 继承 BaseRepository<Advertisement>, IAdvertisementRepository后端
Service模块(处理业务逻辑,能够直接使用ViewModel视图模型):api
BaseService 调用 BaseRepository,同时继承 IBaseService
AdvertisementServices 继承 BaseServices<Advertisement>, IAdvertisementServices
不少人都有一个这样的想法,仓储就是Dal层?我这里简单说一下二者的区别(我Blog.Core项目可能不是体现的出来,DDD可能更好理解):
一、仓储是一种模式,能够单建一层,也能够放到基础设施层,
而Dal是三层架构种的某一层,是一个架构
二、仓储官方的定义,他是一个管理者,去管理实体对象和ORM映射对象的一个集合,是ORM操做db,
而Dal就是完彻底全的操做db数据库了,
请注意,不要把 Sqlsugar 当成三层中的 sqlhelper,不同!
三、仓储更多的是一个聚合,在下一个系列DDD中,咱们说到了一个概念,一个聚合的划分其实就是一个仓储。
四、而后咱们进一步细化,一个仓储 = 一个聚合 = 有一个聚合根 = 一个微服务!
多个微服务之间交互,就是经过聚合根来的。
其中,Models文件夹中,存放的是整个项目的数据库表实体类,这里是手动建立的,固然也能够自动建立,在之后的文章中我会提到,用到的是SqlSugar的T4建立,这里先埋一个伏笔。
提示:这个伏笔已经完成,地址《 三十二║ 四种方法快速实现项目的半自动化搭建》
而后,VeiwModels文件夹,是存放的DTO实体类,在开发中,通常接口须要接收数据,返回数据,我以前都是这么红果果的使用的,后来发现弊端很大,不只把重要信息暴露出去(好比手机号等),还对数据形成冗余(好比我须要接收用户的生日,还须要具体的年、月、日这就是三个字段,固然您也能够手动拆开,这只是一个栗子,因此不能直接用数据库实体类接收),就用到了DTO类的转换,可是频繁的转换又会麻烦,别慌,之后的文章中,咱们会引用AutoMapper来自动转换,这里再买一个伏笔。
提示:这个伏笔已经完成,地址《十三 || DTOs 对象映射使用》
最后的是MessageModel和TableModel,你们也基本一看就能明白,由于在前端接口中,须要固定的格式,以及操做,不能把数据直接发出去,会报错,在之后的Vue开发中,会提到这个,这里又买了一个伏笔。 以下:
/// <summary> /// 通用返回信息类 /// </summary> public class MessageModel<T> { /// <summary> /// 操做是否成功 /// </summary> public bool Success { get; set; } /// <summary> /// 返回信息 /// </summary> public string Msg { get; set; } /// <summary> /// 返回数据集合 /// </summary> public List<T> Data { get; set; } }
整个项目运行,没错,继续建立下一层。
建立Blog.Core.IRepository和 Blog.Core.Repository 仓储层:
这里简单说下仓储层:repository就是一个管理数据持久层的,它负责数据的CRUD(Create, Read, Update, Delete) service layer是业务逻辑层,它经常须要访问repository层。有网友这么说:Repository(仓储):协调领域和数据映射层,利用相似与集合的接口来访问领域对象。Repository 是一个独立的层,介于领域层与数据映射层(数据访问层)之间。它的存在让领域层感受不到数据访问层的存在,它提供一个相似集合的接口提供给领域层进行领域对象的访问。Repository 是仓库管理员,领域层须要什么东西只需告诉仓库管理员,由仓库管理员把东西拿给它,并不须要知道东西实际放在哪。
咱们定义了IRepository层,提供了全部的操做接口,今天搭建框架,我简单地写一个实例,明天咱们将把全部的方法嵌套进去。
在 IAdvertisementRepository.cs 中,添加一个求和接口
public interface IAdvertisementRepository { int Sum(int i, int j); }
而后再在 AdvertisementRepository.cs 中去实现该接口,记得要添加引用,这个应该都会,就不细说了。
public class AdvertisementRepository : IAdvertisementRepository { public int Sum(int i, int j) { return i + j; } }
运行项目,一块儿正常,继续往下。
建立 Blog.Core.IServices 和 Blog.Core.Services 业务逻辑层,就是和咱们平时使用的三层架构中的BLL层很类似:
Service层只负责将Repository仓储层的数据进行调用,至于如何是与数据库交互的,它不去管,这样就能够达到必定程度上的解耦,假如之后数据库要换,好比MySql,那Service层就彻底不须要修改便可,至于真正意义的解耦,仍是得靠依赖注入,这下一节咱们会讲到。
这里在 IAdvertisementServices 中添加接口
namespace Blog.Core.IServices { public interface IAdvertisementServices { int Sum(int i, int j); } }
而后再在 AdvertisementServices 中去实现该接口
public class AdvertisementServices : IAdvertisementServices { IAdvertisementRepository dal = new AdvertisementRepository();
public int Sum(int i, int j) { return dal.Sum(i, j); } }
注意!这里是引入了三个命名空间
using Blog.Core.IRepository;
using Blog.Core.IServices;using Blog.Core.Repository;
将系统默认的ValueController删除,手动添加一个BlogController控制器,能够选择一个空的,也能够选择一个带有默认读写实例的。以下:
[Produces("application/json")] [Route("api/Blog")] [Authorize(Policy ="Admin")] public class BlogController : Controller { // GET: api/Blog [HttpGet] public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET: api/Blog/5 [HttpGet("{id}", Name = "Get")] public string Get(int id) { return "value"; } // POST: api/Blog [HttpPost] public void Post([FromBody]string value) { } // PUT: api/Blog/5 [HttpPut("{id}")] public void Put(int id, [FromBody]string value) { } // DELETE: api/ApiWithActions/5 [HttpDelete("{id}")] public void Delete(int id) { } }
接下来,在应用层添加服务层的引用
using Blog.Core.IServices;
using Blog.Core.Services;
而后,改写Get方法
·······// GET: api/Blog /// <summary> /// Sum接口 /// </summary> /// <param name="i">参数i</param> /// <param name="j">参数j</param> /// <returns></returns> [HttpGet] public int Get(int i,int j) { IAdvertisementServices advertisementServices = new AdvertisementServices(); return advertisementServices.Sum(i,j); }
F5 运行项目,调试以下:
天呀!出错辣!别慌,还记得昨天我们加的权限么,嗯!就是那里,手动模拟登录,获取Token,注入,不会的能够看上一篇,而后再执行,结果:
好啦,今天的工做暂时到这里了,你能够看到总体项目的搭建,结构,如何引用,如何测试等,固然,这里仍是有不少小问题,好比:
·若是每一个仓储都须要这么写,至少是四遍,会不会太麻烦;
·每次Controller接口调用,须要引入不少命名空间
·等等等等
这些问题,下一节咱们都会带你们一块儿去慢慢解决!