zoukankan      html  css  js  c++  java
  • 项目架构开发:数据访问层之Query

    接上文 项目架构开发:数据访问层之Repository

    上一章我们讲了IRepository接口,这张我们来讲IQuery

    根据字面意思就可以知道,这次主要讲数据查询,上一章我们只针对单表做了查询的操作,多表联查并没有实现

    其实对于任何一个项目来说,多表联查都是比较麻烦的地方,因为项目的“读”操作,特别是多表的“读”,至少占据所有“读”的一半以上

    然而至今,据我所知还没有哪一款ORM工具可以灵活处理多表联查;想要不写sql语句,又想性能高,还想用强类型的ling查询方法;这对于多表查询来说比较难

    鉴于此,也别做那些别扭的映射了(像NH),而如果用lingtosql我觉得还不如直接写sql来的好;

    是开发人员不可能不懂sql,那对多表查询这一块,干脆独立一个Query类出来,专门处理这种事

    好了这只是我的处理方式,我们来看看

    IQuery.cs

     1     public interface IQuery
     2     {
     3         T QuerySingle<T>(string sql, object paramPairs) where T : class;
     4         IEnumerable<T> QueryList<T>(string sql, object paramPairs) where T : class;
     5 
     6         /// <summary>必须带上row_number() over({0}) RowNumber</summary>
     7         Tuple<int, IEnumerable<T>> GetPage<T>(Page page, string sql, dynamic paramPairs = null) where T : class;
     8         
     9         Tuple<int, IEnumerable<T>> GetPage<T>(string sql, object paramPairs = null) where T : class;
    10         int Execute(string sql, dynamic paramPairs = null);
    11         long Count(string sql, dynamic paramPairs = null);
    12     }

    上方法名就可以知道,写sql,然后返回自定义的T或IEnumerable<T>

    这里避免了用泛型类,因为某个实体大多数情况下可能也只是需要,上边其中其中的1、2个而已

    这里有一个Execute方法,其实不应该放在这的,但是也懒得写另外一个类了,先放着吧

    Query的实现

    DapperQuery.cs

     1 using Dapper;
     2 using Dapper.Contrib.Extensions;
     3 using LjrFramework.Common;
     4 using LjrFramework.Interface;
     5 using System;
     6 using System.Collections.Generic;
     7 using System.Data;
     8 using System.Linq;
     9 
    10 namespace LjrFramework.Data.Dapper
    11 {
    12     public class DapperQuery : IQuery
    13     {
    14         protected IDbConnection Conn { get; private set; }
    15 
    16         public DapperQuery()
    17         {
    18             Conn = DbConnectionFactory.CreateDbConnection();
    19         }
    20 
    21         public void SetDbConnection(IDbConnection conn)
    22         {
    23             Conn = conn;
    24         }
    25 
    26         public T QuerySingle<T>(string sql, object paramPairs) where T : class
    27         {
    28             return Conn.Query<T>(sql, paramPairs).SingleOrDefault();
    29         }
    30 
    31         public IEnumerable<T> QueryList<T>(string sql, object paramPairs) where T : class
    32         {
    33             return Conn.Query<T>(sql, paramPairs);
    34         }
    35 
    36         /// <summary>自动分页,必须带上row_number() over({0}) RowNumber</summary>
    37         public Tuple<int, IEnumerable<T>> GetPage<T>(Page page, string sql, object paramPairs = null) where T : class
    38         {
    39             var multi = Conn.GetPage<T>(page.PageIndex, page.PageSize, sql, paramPairs);
    40             var count = multi.Read<int>().Single();
    41             var results = multi.Read<T>();
    42             return new Tuple<int, IEnumerable<T>>(count, results);
    43         }
    44         // 需自己实现分页语句
    45         public Tuple<int, IEnumerable<T>> GetPage<T>(string sql, object paramPairs = null) where T : class
    46         {
    47             var multi = Conn.GetGridReader<T>(sql, paramPairs);
    48             var count = multi.Read<int>().Single();
    49             var results = multi.Read<T>();
    50             return new Tuple<int, IEnumerable<T>>(count, results);
    51         }
    52 
    53 
    54         public int Execute(string sql, object paramPairs = null)
    55         {
    56             return Conn.Execute(sql, paramPairs);
    57         }
    58 
    59         public long Count(string sql, object paramPairs = null)
    60         {
    61             return Conn.Query<long>(sql, paramPairs).SingleOrDefault();
    62         }
    63     }
    64 }

    这个实现跟上一章差不多,都是直接调用Conn的扩展方法,

    我们进去看看(public Tuple<int, IEnumerable<T>> GetPage<T>(string sql, object paramPairs = null) where T : class)的实现

    可以看到dapper是已经支持sql语句的查询,并且返回多个记录(SqlMapper.GridReader)

    每次分页都要去手动刷选 页数 与 记录开始行数的话比较麻烦

    所有我做了一点小改动,武学用户写分页语句,直接查询就可以了,后台会自动生成分页语句的格式

    不过要带上row_number() over({0}) RowNumber;就是上边那个有注释的方法

    他的实现如下

    这样用户只需要准守一点约束,就会方便很多

    这些都是在dapper的Extensions里实现的,用户需要自行修改,自己想要的自定义的功能

    好了,Query有效代码写完了,我们看看运行效果

    Query测试

      1 using Autofac;
      2 using Company.Project.PO;
      3 using LjrFramework.Data.Dapper;
      4 using LjrFramework.Common;
      5 using LjrFramework.Infrastructure;
      6 using LjrFramework.Interface;
      7 using Microsoft.VisualStudio.TestTools.UnitTesting;
      8 using System;
      9 using LjrFramework.Data.UnitOfWork;
     10 
     11 namespace LjrFramework.UnitTest
     12 {
     13     [TestClass]
     14     public class QueryTest
     15     {
     16         private IQuery query;
     17 
     18         public QueryTest()
     19         {
     20             var builder = new ContainerBuilder();
     21             builder.RegisterType<DapperQuery>().As<IQuery>();
     22 
     23             var container = builder.Build();
     24             query = container.Resolve<IQuery>();
     25 
     26         }
     27 
     28         [TestMethod]
     29         public void QuerySingle()
     30         {
     31             var model = query.QuerySingle<LoginUser>("select * from LoginUser where Id = @Id", new { Id = "854B1FCA-F8D7-4B4B-AA5D-9075F1922721" });
     32 
     33             Assert.AreEqual(model.LoginName, "lanxiaoke-d318fd40-1b9d-42f8-a002-388b1228012d");
     34         }
     35 
     36         [TestMethod]
     37         public void QueryList()
     38         {
     39             var list = query.QueryList<LoginUser>("select * from LoginUser where LoginName like '%'+ @LoginName + '%'", new { LoginName = "lanxiaoke" });
     40 
     41             int index = 0;
     42             foreach (var user in list)
     43             {
     44                 index++;
     45             }
     46 
     47             Assert.AreEqual(index > 0, true);
     48         }
     49 
     50         [TestMethod]
     51         public void GetPage()
     52         {
     53             var page = new Page()
     54             {
     55                 PageIndex = 1,
     56                 PageSize = 10
     57             };
     58 
     59             var results = query.GetPage<LoginUser>(page,
     60                 @"select row_number() over(order by CreateTime) RowNumber,* from LoginUser where LoginName like '%'+ @LoginName + '%'", new { LoginName = "lanxiaoke" });
     61 
     62             var total = results.Item1;
     63             var list = results.Item2;
     64 
     65             int index = 0;
     66             foreach (var user in list)
     67             {
     68                 index++;
     69             }
     70 
     71             Assert.AreEqual(index > 0, true);
     72         }
     73 
     74         [TestMethod]
     75         public void GetPage2()
     76         {
     77             var page = new Page()
     78             {
     79                 PageIndex = 1,
     80                 PageSize = 10
     81             };
     82 
     83             var results = query.GetPage<LoginUser>(
     84                 @"select count(*) as TotalCount from LoginUser c where LoginName like '%'+ @LoginName + '%'
     85                   select row_number() over(order by CreateTime) RowNumber,* from LoginUser where LoginName like '%'+ @LoginName + '%'",
     86             new { LoginName = "lanxiaoke" });
     87 
     88             var total = results.Item1;
     89             var list = results.Item2;
     90 
     91             int index = 0;
     92             foreach (var user in list)
     93             {
     94                 index++;
     95             }
     96 
     97             Assert.AreEqual(index > 0, true);
     98         }
     99 
    100         [TestMethod]
    101         public void Count()
    102         {
    103             var row = query.Count("select count(*) from LoginUser");
    104 
    105             Assert.AreEqual(row > 1, true);
    106         }
    107 
    108     }
    109 }

    自此,多表查询就讲完了

    项目架构开发系列

  • 相关阅读:
    缓冲区溢出漏洞实验
    编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能
    预备作业01
    20155335俞昆的第2次随笔
    20155335俞昆
    团队博客
    小组项目第三周(20145101、20145102、20145124、20145203)
    小组项目第二周(20145101、20145102、20145124、20145203)
    小组项目第一周(20145101、20145102、20145124、20145203)
    项目总结
  • 原文地址:https://www.cnblogs.com/lanxiaoke/p/6503333.html
Copyright © 2011-2022 走看看