從零開始搭建前後端分離的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的項目框架之十資料庫基礎方法的封裝

来源:https://www.cnblogs.com/levywang/archive/2019/11/12/coreframe_10.html
-Advertisement-
Play Games

每一個擁有資料庫的項目,都會涉及到資料庫數據的操作,而很多時候都會用到相同的方法,但是只是涉及到的表不一樣,如果不對這些類似方法進行封裝,開發上就會造成時間上的浪費。 那麼如何對這些方法進行封裝呢? 要會封裝方法,最基本的得先瞭解 泛型 是什麼,什麼是泛型,博客園上有很多對這個的講解,我也相信,科班 ...


  每一個擁有資料庫的項目,都會涉及到資料庫數據的操作,而很多時候都會用到相同的方法,但是只是涉及到的表不一樣,如果不對這些類似方法進行封裝,開發上就會造成時間上的浪費。

  那麼如何對這些方法進行封裝呢?

  要會封裝方法,最基本的得先瞭解  泛型 是什麼,什麼是泛型,博客園上有很多對這個的講解,我也相信,科班的人對這個應該都有大概的瞭解,

  其次得瞭解 反射,當然,很多人會說反射會影響性能,但是在如今設備都是很好的情況下,反射影響的性能微乎其微吧~

  言歸正傳,說的再多不如實操,那麼我們先新建資料庫表的基類,並讓資料庫表類繼承它,這樣來約束泛型的類型只能是數據表對象,不能是其它類型,以此來避免不必要的錯誤!

    /// <summary>
    /// 資料庫基類
    /// </summary>
    public abstract class EntityBase : IEntityBase
    {
    }

這裡的  IEntityBase  是前面第二篇中用到的一個空的介面基類,在這個抽象基類中,可以添加欄位,這樣繼承該基類的資料庫表都會加上這些欄位,比如 創建時間、創建人等欄位

  因為這裡會涉及到分頁模型的因素,先新建泛型的分頁模型類 PageResponse 

    /// <summary>
    /// 分頁模型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class PageResponse<T>
    {
        private long _recordTotal;

        /// <summary>
        /// 當前頁碼
        /// </summary>
        public int PageIndex { get; set; }

        /// <summary>
        /// 總頁數
        /// </summary>
        public int PageTotal { get; set; } = 1;

        /// <summary>
        /// 每頁大小
        /// </summary>
        public int PageSize { get; set; }

        /// <summary>
        /// 總記錄數
        /// </summary>
        public long RecordTotal
        {
            get => _recordTotal;
            set
            {
                _recordTotal = value;
                if (PageSize <= 0) return;
                PageTotal = (int)Math.Ceiling(RecordTotal / (double)PageSize);
            }
        }

        public List<T> Data { get; set; }

        public PageResponse()
        {
            Data = new List<T>();
        }

        public PageResponse(List<T> data, int pageIndex, int pageTotal)
        {
            Data = data;
            PageIndex = pageIndex;
            PageTotal = pageTotal;
        }
    }

  接下來我們新建一個資料庫工廠類 來 進行 生產資料庫上下文,代碼如下

 /// <summary>
    /// 資料庫工廠
    /// </summary>
    public class DbContextFactory
    {
        /// <summary>
        /// 資料庫上下文
        /// </summary>
        /// <returns></returns>
        public static DemoDbContext GetCurrentDbContext()
        {
            if (DemoWeb.HttpContext.Items["DbContext"] is DemoDbContext dbContext) return dbContext;
            dbContext = DemoWeb.IocManager.Resolve<DemoDbContext>();//從容器中得到資料庫上下文 放置在 Items 中, 訪問結束自動銷毀
            //dbContext = DemoWeb.HttpContext.RequestServices.GetService(typeof(DemoDbContext)) as DemoDbContext;
            DemoWeb.HttpContext.Items["DbContext"] = dbContext;
            return dbContext;
        }
    }

  因為這裡使用的是autofac模式,所以這樣獲取。至於為什麼放到items中,也有簡單的原因講到。

   再然後新建  IBaseDao  介面文件,代碼如下:

    public interface IBaseDao<T>
    {
        T Add(T entity);

        List<T> Add(List<T> entity);

        void Delete(params object[] keyValues);
        void Delete(object objectId);
        void Delete(Expression<Func<T, bool>> whereFun);
        void Update(T entity);
        void Update(Expression<Func<T, bool>> where, Dictionary<string, object> dic);
        bool Exist(Expression<Func<T, bool>> anyLambda);

        T Find(params object[] keyValues);
        IQueryable<T> Where(Expression<Func<T, bool>> whereLambda);
        T FirstOrDefault(Expression<Func<T, bool>> whereLambda);
        int Count(Expression<Func<T, bool>> countLambda);

        T First(Expression<Func<T, bool>> firstLambda);

        IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda = null);

        List<T> LoadPageEntities<TKey>(int pageIndex, int pageSize,
            out int totalCount, out int pageCount,
            Expression<Func<T, bool>> whereLambda, bool isAsc, Expression<Func<T, TKey>> orderBy);

        PageResponse<T> LoadPageEntities<TKey>(int pageIndex, int pageSize,
            Expression<Func<T, bool>> whereLambda, bool isAsc, Expression<Func<T, TKey>> orderBy);

        IQueryable<TQ> LoadPageEntities<TQ, TKey>(IQueryable<TQ> query, int pageIndex, int pageSize,
            out int totalCount, out int pageCount, bool isAsc, Expression<Func<TQ, TKey>> orderBy) where TQ : class, new();

        PageResponse<TQ> LoadPageEntities<TQ, TKey>(IQueryable<TQ> query, int pageIndex, int pageSize,
            bool isAsc, Expression<Func<TQ, TKey>> orderBy) where TQ : class, new();

        int SaveChanges();
    }

實現介面的類,代碼如下:   代碼有點長~~所以就摺疊了~~

    /// <summary>
    /// 資料庫基類
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BaseDao<T> : IBaseDao<T> where T : EntityBase, new()
    {
        
        public DemoDbContext DbContext => DbContextFactory.GetCurrentDbContext();

        public BaseDao()
        {
            //DbContext = DbContextFactory.GetCurrentDbContext();
        }

        #region 增刪改的公共方法

        public T Add(T entity)
        {
            DbContext.Set<T>().Add(entity);
            //DbContext.Entry(entity).State = EntityState.Added;
            return entity;
        }
        public List<T> Add(List<T> entitys)
        {
            DbContext.Set<T>().AddRange(entitys); //註釋掉下麵的快許多 且不影響保存
            //foreach (var model in entitys)
            //{
            //    DbContext.Entry(model).State = EntityState.Added;
            //}
            return entitys;
        }

        public void Delete(Expression<Func<T, bool>> whereFun)
        {
            IEnumerable<T> queryable = DbContext.Set<T>().Where(whereFun);
            //DbContext.Set<T>().RemoveRange(queryable);
            foreach (var model in queryable)
            {
                DbContext.Entry(model).State = EntityState.Deleted;
            }
        }

        public void Update(T entity)
        {
            DbContext.Entry(entity).State = EntityState.Modified;
        }

        public void Update(Expression<Func<T, bool>> @where, Dictionary<string, object> dic)
        {
            IEnumerable<T> queryable = DbContext.Set<T>().Where(@where).ToList();
            Type type = typeof(T);
            List<PropertyInfo> propertyList =
                type.GetProperties(BindingFlags.Public |
                                   BindingFlags.Instance).ToList();

            //遍歷結果集
            foreach (T entity in queryable)
            {
                foreach (var propertyInfo in propertyList)
                {
                    string propertyName = propertyInfo.Name;
                    if (dic.ContainsKey(propertyName))
                    {
                        //設置值
                        propertyInfo.SetValue(entity, dic[propertyName], null);
                    }
                }

                Update(entity);
            }
        }

        public void Delete(params object[] keyValues)
        {
            var entity = DbContext.Set<T>().Find(keyValues);
            DbContext.Entry(entity).State = EntityState.Deleted;
        }
        public void Delete(object objectId)
        {
            var entity = DbContext.Set<T>().Find(objectId);
            DbContext.Entry(entity).State = EntityState.Deleted;
        }
        #endregion

        #region 查詢方法

        /// <summary>
        /// 查看是否存在
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="anyLambda"></param>
        /// <returns></returns>
        public bool Exist(Expression<Func<T, bool>> anyLambda)
        {
            return DbContext.Set<T>().Any(anyLambda);
        }

        /// <summary>
        /// 根據主鍵得到數據
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public T Find(params object[] keyValues)
        {
            return DbContext.Set<T>().Find(keyValues);
        }

        /// <summary>
        /// 根據where條件查找
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IQueryable<T> Where(Expression<Func<T, bool>> whereLambda)
        {
            return DbContext.Set<T>().Where(whereLambda);
        }
        /// <summary>
        /// 獲取第一個或預設為空
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public T FirstOrDefault(Expression<Func<T, bool>> whereLambda)
        {
            return DbContext.Set<T>().FirstOrDefault(whereLambda);
        }
        /// <summary>
        /// 得到條數
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="countLambda"></param>
        /// <returns></returns>
        public int Count(Expression<Func<T, bool>> countLambda)
        {
            return DbContext.Set<T>().AsNoTracking().Count(countLambda);
        }

        /// <summary>
        /// 獲取第一個或預設的
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="firstLambda"></param>
        /// <returns></returns>
        public T First(Expression<Func<T, bool>> firstLambda)
        {
            return DbContext.Set<T>().FirstOrDefault(firstLambda);
        }

        /// <summary>
        /// 得到IQueryable數據
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda = null)
        {
            if (whereLambda == null)
            {
                return DbContext.Set<T>().AsQueryable();
            }
            return DbContext.Set<T>().Where(whereLambda).AsQueryable();
        }

        /// <summary>
        /// 從某個表中獲取分頁數據
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <param name="pageCount"></param>
        /// <param name="whereLambda"></param>
        /// <param name="isAsc"></param>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        public List<T> LoadPageEntities<TKey>(int pageIndex, int pageSize, out int totalCount, out int pageCount, Expression<Func<T, bool>> whereLambda,
            bool isAsc, Expression<Func<T, TKey>> orderBy)
        {
            var temp = DbContext.Set<T>().AsNoTracking().Where(whereLambda); //去掉.AsQueryable().AsNoTracking(),將下麵改為

            totalCount = temp.Count();
            pageCount = (int)Math.Ceiling((double)totalCount / pageSize);
            if (isAsc)
            {
                return temp.OrderBy(orderBy)
                    .Skip(pageSize * (pageIndex - 1))
                    .Take(pageSize).ToList(); //去掉.AsQueryable(),添加.select(t=>new Dto()).ToList()
            }

            return temp.OrderByDescending(orderBy)
                .Skip(pageSize * (pageIndex - 1))
                .Take(pageSize).ToList(); //.select(t=>new Dto()).ToList()

        }

        /// <summary>
        /// 返回分頁模型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="whereLambda"></param>
        /// <param name="isAsc"></param>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        public PageResponse<T> LoadPageEntities<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, bool isAsc, Expression<Func<T, TKey>> orderBy)
        {
            var temp = DbContext.Set<T>().AsNoTracking().Where(whereLambda); 

            var rest = new PageResponse<T>();
            rest.PageIndex = pageIndex;
            rest.PageSize = pageSize;
            rest.RecordTotal = temp.Count();//記錄總條數時,自動設置了總頁數
            if (isAsc)
            {
                rest.Data = temp.OrderBy(orderBy)
                     .Skip(pageSize * (pageIndex - 1))
                     .Take(pageSize).ToList(); 
            }

            rest.Data = temp.OrderByDescending(orderBy)
                .Skip(pageSize * (pageIndex - 1))
                .Take(pageSize).ToList(); 

            return rest;
        }

        /// <summary>
        /// 將查詢出來的數據 轉換成IQueryable,然後進行分頁   不跟蹤數據狀態
        /// </summary>
        /// <typeparam name="TQ">返回類型</typeparam>
        /// <typeparam name="TKey">根據哪個欄位排序(必須)</typeparam>
        /// <param name="query">數據集</param>
        /// <param name="pageIndex">頁數</param>
        /// <param name="pageSize">每頁條數</param>
        /// <param name="totalCount">總條數</param>
        /// <param name="pageCount">總頁數</param>
        /// <param name="isAsc">是否倒序</param>
        /// <param name="orderBy">排序欄位</param>
        /// <returns>IQueryable分頁結果</returns>
        public IQueryable<TQ> LoadPageEntities<TQ, TKey>(IQueryable<TQ> query, int pageIndex, int pageSize, out int totalCount, out int pageCount, bool isAsc, Expression<Func<TQ, TKey>> orderBy) where TQ : class, new()
        {
            IQueryable<TQ> temp = query.AsNoTracking();
            totalCount = temp.Count();
            pageCount = (int)Math.Ceiling((double)totalCount / pageSize);
            if (isAsc)
            {
                temp = temp.OrderBy(orderBy)
                           .Skip(pageSize * (pageIndex - 1))
                           .Take(pageSize).AsQueryable();
            }
            else
            {
                temp = temp.OrderByDescending(orderBy)
                          .Skip(pageSize * (pageIndex - 1))
                          .Take(pageSize).AsQueryable();
            }
            return temp;
        }

        /// <summary>
        /// 將查詢出來的數據 轉換成IQueryable,然後進行分頁   不跟蹤數據狀態
        /// </summary>
        /// <typeparam name="TQ">返回類型</typeparam>
        /// <typeparam name="TKey">根據哪個欄位排序(必須)</typeparam>
        /// <param name="query">數據集</param>
        /// <param name="pageIndex">頁數</param>
        /// <param name="pageSize">每頁條數</param>
        /// <param name="isAsc">是否倒序</param>
        /// <param name="orderBy">排序欄位</param>
        /// <returns>PageResponse分頁結果</returns>
        public PageResponse<TQ> LoadPageEntities<TQ, TKey>(IQueryable<TQ> query, int pageIndex, int pageSize, bool isAsc, Expression<Func<TQ, TKey>> orderBy) where TQ : class, new()
        {
            var rest = new PageResponse<TQ>();
            IQueryable<TQ> temp = query.AsNoTracking();
            rest.RecordTotal = temp.Count();
            if (isAsc)
            {
                rest.Data = temp.OrderBy(orderBy)
                    .Skip(pageSize * (pageIndex - 1))
                    .Take(pageSize).ToList();
            }
            else
            {
                rest.Data = temp.OrderByDescending(orderBy)
                    .Skip(pageSize * (pageIndex - 1))
                    .Take(pageSize).ToList();
            }
            return rest;
        }

        #endregion

        /// <summary>
        /// 自帶事務,調用此方法保存
        /// </summary>
        public int SaveChanges()
        {
            var res = -1;
            try
            {
                res = DbContext.SaveChanges();
                //Dispose();
            }
            catch (DbException ex)
            {
                throw new CustomSystemException($"資料庫保存失敗!{ex.Message}", 999);
            }
            catch (Exception ex)
            {
                throw new CustomSystemException($"資料庫保存失敗!{ex.Message}", 999);
            }
            return res;
        }

        public void Dispose()
        {
            this.DbContext.Dispose();
            GC.SuppressFinalize(this);
        }
    }
BaseDao

 

  到這裡,根據每個資料庫表建對應的 Dao 類,這樣一來開發效率就會明顯提升,示例代碼如下:

    public class DemoModelDao : BaseDao<DemoModel>
    {
        private static object locker = new object();
        private static DemoModelDao _demoModelDao;

        public static DemoModelDao Instance
        {
            get
            {
                if (_demoModelDao != null) return _demoModelDao;
                lock (locker)
                {
                    if (_demoModelDao == null)
                    {
                        _demoModelDao = new DemoModelDao();
                    }
                }
                return _demoModelDao;
            }
        }

        /// <summary>
        /// 得到分頁數據
        /// </summary>
        /// <param name="queryDemo"></param>
        /// <returns></returns>
        public PageResponse<DemoModel> DemoPageResponse(QueryDemoDto queryDemo)
        {
            var date = LoadPageEntities(queryDemo.Page, queryDemo.PageSize, 
                c => c.CustomerName.Contains(queryDemo.Name), false, c => c.Id);
            return date;
        }
    }

然後添加測試方法,添加 Biz 類,調用測試

    public class DemoModelBiz
    {
        private static object locker = new object();
        private static DemoModelBiz _demoModelBiz;

        public static DemoModelBiz Instance
        {
            get
            {
                if (_demoModelBiz != null) return _demoModelBiz;
                lock (locker)
                {
                    if (_demoModelBiz == null)
                    {
                        _demoModelBiz = new DemoModelBiz();
                    }
                }
                return _demoModelBiz;
            }
        }

        public string AddDemoModel(DemoModel demoModel)
        {
            DemoModelDao.Instance.Add(demoModel);
            var count = DemoModelDao.Instance.SaveChanges();
            return count > 0 ? "success" : "save error";
        }
        public string AddDemoModel(List<DemoModel> demoModels)
        {
            DemoModelDao.Instance.Add(demoModels);
            DemoModelDao.Instance.Delete(c=>c.Id == 1);
            DemoModelDao.Instance.Delete(c=>c.CustomerName.StartsWith("2"));
            TestModelDao.Instance.Add(new TestModel()
            {
                BlogName = "NET CORE",
                BlogPhone = 123,
                BlogUseDay = 90
            });
            var count = DemoModelDao.Instance.SaveChanges();
            return count > 0 ? "success" : "save error";
        }
        /// <summary>
        /// 得到分頁數據
        /// </summary>
        /// <param name="queryDemo"></param>
        /// <returns></returns>
        public PageResponse<DemoModel> DemoModelList(QueryDemoDto queryDemo)
        {
           return DemoModelDao.Instance.DemoPageResponse(queryDemo);
        }
    }

再添加測試的控制器類,示例代碼如下:

    [Route("api/[controller]")]
    public class DemoModelController : BaseController
    {
        [Route("testadd"), HttpPost]
        public async Task<ActionResult> AddDemoModel()
        {
            var models = new List<DemoModel>();
            for (int i = 0; i < 100; i++)
            {
                var testModel = new DemoModel()
                {
                    CustomerName = i +"-Levy" + DateTime.Now.ToString("HH:mm:ss"),
                    IdentityCardType = 1
                };
                models.Add(testModel);
            }
            for (int i = 0; i < 100; i++)
            {
                var testModel = new DemoModel()
                {
                    CustomerName = i + "-zzzz" + DateTime.Now.ToString("HH:mm:ss"),
                    IdentityCardType = 2
                };
                models.Add(testModel);
            }

            var res = await Task.FromResult(DemoModelBiz.Instance.AddDemoModel(models));
            return Succeed(res);
        }

        [Route("demolist"), HttpPost]
        public async Task<ActionResult> DemoModelList([FromBody] QueryDemoDto queryDemo)
        {
            var res = await Task.FromResult(DemoModelBiz.Instance.DemoModelList(queryDemo));
            return Succeed(res);
        }
    }

涉及到的類

    public class QueryDemoDto
    {
        public int Page { get; set; }
        public int PageSize { get; set; }
        public string Name { get; set; }
    }

接下來就運行程式調試看結果吧~

 

 這裡數據保存成功之後我們進行數據的查詢,

 

 可以看到查詢出結果,這裡有兩千多條數據,是因為執行了多次且每次保存前都會刪除以2開始的數據。

 題外話,因為我們是將資料庫上下文放在  HttpContext.Items 中的,可能有些人會擔心程式運行完後會不釋放,從而導致資料庫鏈接過多而出現崩潰,

首先呢,訪問結束時 HttpContext.Items 就會銷毀,也就意味著資料庫鏈接也就銷毀了,

如果還是不放心,可以在方法執行完成時,將資料庫鏈接手動釋放,

首先在工廠類中加上

        /// <summary>
        /// 釋放DBContext對象
        /// </summary>
        public static void DisposeDbContext()
        {
            if (DemoWeb.HttpContext.Items.ContainsKey("DbContext"))
            {
                DemoWeb.HttpContext.Items.Remove("DbContext");
            }
        }

然後不管程式正常執行完成,還是遇到異常,都會走控制器的  OnActionExecuted  方法,因此可以重載這個方法,然後調用釋放方法 DbContextFactory.DisposeDbContext(); 

 

以上若有什麼不對或可以改進的地方,望各位指出或提出意見,一起探討學習~

有需要源碼的可通過此 GitHub 鏈接拉取 覺得還可以的給個 start 和點個 下方的推薦哦~~謝謝!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 由於我本地的mysql版本比較低,最近想著要升級一下mysql版本,鑒於docker容器的火熱,就想著在本地裝個docker環境,然後下載最新版的mysql鏡像,完成mysql8.0的安裝。電腦是windows 10版本。 一 啟用Hyper V 打開控制面板 程式 啟用或關閉windows功能,勾 ...
  • Spring 練習 通過學習spring的基礎知識,瞭解了Spring為了降低Java開發的複雜性,採取了以下4種關鍵策略: 基於POJO的輕量級和最小侵入性編程; 通過依賴註入和麵向介面實現松耦合; 基於切麵和慣例進行聲明式編程; 通過切麵和模板減少樣板式代碼。 下麵將做一個spring的練習de ...
  • c++ 模板類,方法返回值類型是typedef出來的,或者是auto,那麼此方法在類外面如何定義? 比如方法max1的返回值是用typedef定義出來的mint,那麼在類外如何定義這個方法呢? 嘗試1: 嘗試1的結果:編譯不過,提示不能識別mint 嘗試2: 嘗試2的結果:依然編譯不過 嘗試3: 在 ...
  • Spring之IOC容器初始化 前言 在前面我們分析了最底層的IOC容器BeanFactory,接著簡單分析了高級形態的容器ApplicationContext,在ApplicationContext 中我們知道一個核心方法 refresh,這裡面就是IOC容器的初始化流程,在前面並沒有直接去分析它 ...
  • 一.編寫shell腳本基本格式 拿最簡單的 舉例 . !/bin/bash:告訴電腦,使用bash解釋器來執行代碼 echo: 列印 二.運行shell腳本 (推薦使用) 三.註釋 四.定義變數 基本語法 shell 1.定義變數:變數名=變數值 2.撤銷變數:unset 變數名 3.聲明靜態變數 ...
  • 1.paramiko 用於幫助開發者通過代碼遠程連接伺服器,並對伺服器進行操作。 遠程執行命令【用戶名和密碼】 遠程執行命令【公鑰和私鑰】(公鑰必須提前上傳到伺服器) 遠程上傳和下載文件【用戶名和密碼】 遠程上傳和下載文件【公鑰和私鑰】 補充:通過私鑰字元串也可以連接遠程伺服器。 2.公司員工基於x ...
  • 多態是類的三大特性之一,抽象類又是多態的實現方法之一。抽象類是什麼呢,如果把虛方法比作一個盛有純凈水的杯子,那麼此時的“純凈水”就是事先定義好的方法,我們可以根據不同的需求來改變杯子中所事先盛放的是“純凈水”還是“咖啡”。但是抽象類呢,他更像是一個空的杯子,放在消毒櫃中,讓有需要的人自己去拿,去決定 ...
  • 類型的劃分 一個類型,要麼是值類型,要麼是引用類型 。區別在於拷貝方式:值類型拷貝值,引用類型拷貝引用 值類型 值類型直接包含值。相當於每一個值類型都有自己單獨的值: int a = 10; int b = a; a和b都有著自己的值,修改a並不會影響b,反過來一樣,互不影響。 即使是將實例傳給Co ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...