webapi + dapper+mysql +autofac架构搭建

写在前面: 

最近没啥事,研究了一下web api的框架, 选型用的是dapper+autofac+mysql, 简单的三层架构,总体框架如下,刚开始没有设计的太复杂:

分层介绍:

1.APIDapperTool介绍:

APIDapperTool里面是封装的dapper的一些dapper的操作,以及对多数据库的支持,dapper是一个轻量级的orm工具,与其说是一个orm,还不如称呼为dbhelper。它是一个对数据库操作的封装,不需要装什么其他的组件,只需要在nuget里面安装dapper,一个单文件就能实现操作,对其他数据库的支持也非常好,数据库间的切换也非常方便:

DbConnectionFactory这个里面是对dapper连接的的封装,以及多数据库的支持,切换,代码如下:

   public class DbConnectionFactory
    {
        /// 接收数据库类型,如:Oracle,MySQL,SqlServer。目前只支持者三种类型数据库的切换
        private static string _dbType = string.Empty;

        /// 数据库连接名
        private static string _connection = string.Empty;

        /// 获取连接名        
        private static string Connection
        {
            get { return _connection; }
            //set { _connection = value; }
        }

        /// 返回连接实例        
        private static IDbConnection dbConnection = null;
        #region 这种方式初始化属性值时,出现延迟的情况,导致静态方法被调用时,属性值为空,异常报错,因此弃用该方式,采用单例模式
        //{
        //    get
        //    {
        //        string dbConnection = ConfigurationManager.AppSettings["DbConnection"].ToString();
        //        if (!string.IsNullOrEmpty(dbConnection) && dbConnection.Contains('_'))
        //        {
        //            //获取:数据库类型_连接名:SqlServer_SqlConnection
        //            string[] strArray = dbConnection.Split('_');
        //            //接收:数据库类型
        //            _dbType = strArray[0].ToUpper();
        //            //接收:数据库连接名
        //            _connection = ConfigurationManager.ConnectionStrings[strArray[1]].ConnectionString;
        //        }
        //        return _connection;
        //    }
        //} 
        #endregion

        /// 静态变量保存类的实例        
        private static DbConnectionFactory uniqueInstance;

        /// 定义一个标识确保线程同步        
        private static readonly object locker = new object();

        /// <summary>
        /// 私有的构造方法,使外界不能创建该类的实例
        /// </summary>
        private DbConnectionFactory()
        {
            string dbConnection = ConfigurationManager.AppSettings["DbConnection"].ToString();
            if (!string.IsNullOrEmpty(dbConnection) && dbConnection.Contains('_'))
            {
                //获取:数据库类型_连接名:SqlServer_SqlConnection
                string[] strArray = dbConnection.Split('_');
                //接收:数据库类型
                _dbType = strArray[0].ToUpper();
                //接收:数据库连接名
                _connection = ConfigurationManager.ConnectionStrings[strArray[1]].ConnectionString;
            }
        }

        /// <summary>
        /// 全局访问点
        /// </summary>
        /// <returns>返回单一实例</returns>
        public static DbConnectionFactory GetInstance()
        {
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new DbConnectionFactory();
                    }
                }
            }
            return uniqueInstance;
        }

        /// <summary>
        ///  根据 Appsetting配置中的数据库类型和连接名,打开当前配置的数据库连接。
        /// </summary>
        /// <returns></returns>
        public static IDbConnection OpenCurrentDbConnection()
        {
            switch (_dbType)
            {
                case "SQLSERVER":
                    if (dbConnection == null)
                    {
                        dbConnection = new SqlConnection(Connection);
                    }
                    break;
                case "MYSQL":
                    if (dbConnection == null)
                    {
                        dbConnection = new MySqlConnection(Connection);
                    }
                    break;
                default:
                    break;
            }
            //判断连接状态
            if (dbConnection.State == ConnectionState.Closed)
            {
                dbConnection.Open();
            }
            return dbConnection;
        }

        /// <summary>
        /// 打开自定义配置的数据库类型和连接名
        /// </summary>
        /// <param name="dbConnectionString">连接内容</param>
        /// <param name="dbType">数据库类型</param>
        /// <returns></returns>
        public static IDbConnection OpenCurrentDbConnection(string dbConnectionString, DbType dbType = DbType.SqlServer)
        {
            switch (dbType.ToString().ToUpper())
            {
                case "SQLSERVER":
                    if (dbConnection == null)
                    {
                        dbConnection = new SqlConnection(dbConnectionString);
                    }
                    break;
                case "MYSQL":
                    if (dbConnection == null)
                    {
                        dbConnection = new MySqlConnection(dbConnectionString);
                    }
                    break;
                default:
                    break;
            }
            //判断连接状态
            if (dbConnection.State == ConnectionState.Closed)
            {
                dbConnection.Open();
            }
            return dbConnection;
        }
    }


    /// <summary>
    /// 数据库类型
    /// </summary>
    public enum DbType
    {
        SqlServer = 1,
        Oracle = 2,
        MySQL = 3
    }

采用的是单例模式,双锁检查,获取连接。

DbContexts: 这个里面是对一些数据库操作的封装,增删改查,集合查询等等,代码如下:

   public static class DbContexts
    {

        /// 获取开启数据库的连接        
        private static IDbConnection Db
        {
            get
            {
                //创建单一实例
                DbConnectionFactory.GetInstance();
                return DbConnectionFactory.OpenCurrentDbConnection();
            }
        }

        /// <summary>
        /// 查出一条记录
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static dynamic SelectFirst(string sql)
        {
            return Db.QueryFirst(sql);
        }

        /// <summary>
        /// 查出多条记录
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static IEnumerable<dynamic> Select(string sql)
        {
            return Db.Query(sql);
        }


        /// <summary>
        /// 查出一条记录的实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static T SelectFirst<T>(string sql) where T : class, new()
        {
            return Db.QueryFirst<T>(sql);
        }


        /// <summary>
        /// 查出多条记录的实体泛型集合
        /// </summary>
        /// <typeparam name="T">泛型T</typeparam>
        /// <returns></returns>
        public static async Task<IEnumerable<T>> Select<T>(string sql) where T : class, new()
        {
            return await Db.QueryAsync<T>(sql);
        }

        public static async Task<IEnumerable<T>> Select<T>(string sql, object obj) where T : class, new()
        {
            return await Db.QueryAsync<T>(sql, obj);
        }


        /// <summary>
        /// 同时查询多张表数据(高级查询)
        /// "select *from K_City;select *from K_Area";
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static SqlMapper.GridReader SelectMultiple(string sql)
        {
            return Db.QueryMultiple(sql);
        }

        /// <summary>
        /// 单,多表 更新(事务),执行原生sql
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static async Task<int> Update(string sql)
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    rows = await Db.ExecuteAsync(sql, null, DbTransaction);
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }

        /// <summary>
        /// 单表批量更新(事务),泛型T集合作为参数
        /// </summary>
        /// <typeparam name="T">泛型T</typeparam>
        /// <param name="sql">sql语句(sql="update Person set password='ddd' where id=@id",</param>
        /// <param name="obj">参数类(obj=new{id=1})</param>
        /// <returns></returns>
        public static async Task<int> Update<T>(string sql, object obj) where T : class, new()
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    rows = await Db.ExecuteAsync(sql, obj, DbTransaction);
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }

        /// <summary>
        /// 多表 批量插入(事物),可以是泛型T集合数据
        /// </summary>
        /// <param name="param">二元组集合参数</param>
        /// <returns></returns>
        public static int Update(List<Tuple<string, object>> param)
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    foreach (var item in param)
                    {
                        rows += Db.Execute(item.Item1, item.Item2, DbTransaction);
                    }
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }


        /// <summary>
        /// 单,多表删除(事物),原生sql
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static int Delete(string sql)
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    rows = Db.Execute(sql, null, DbTransaction);
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }

        /// <summary>
        /// 单表批量删除(事物),泛型T集合作为参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static int Delete<T>(string sql, object obj) where T : class, new()
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    rows = Db.Execute(sql, obj, DbTransaction);
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }

        /// <summary>
        /// 多表批量删除(事物),可以是泛型T集合数据
        /// </summary>
        /// <param name="param">二元组参数</param>
        /// <returns></returns>
        public static int Delete(List<Tuple<string, object>> param)
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    foreach (var item in param)
                    {
                        rows += Db.Execute(item.Item1, item.Item2, DbTransaction);
                    }
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }


        /// <summary>
        /// 单,多表插入(事物),原生sql
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static int Insert(string sql)
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    rows = Db.Execute(sql, null, DbTransaction);
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }

        /// <summary>
        /// 单表批量插入(事物),泛型T集合作为参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static int Insert<T>(string sql, object obj) where T : class, new()
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    rows = Db.Execute(sql, obj, DbTransaction);
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }

        /// <summary>
        /// 多表批量插入(事物),可以是泛型T集合数据
        /// </summary>
        /// <param name="param">二元组参数</param>
        /// <returns></returns>
        public static int Insert(List<Tuple<string, object>> param)
        {
            int rows = 0;
            using (IDbTransaction DbTransaction = Db.BeginTransaction())
            {
                try
                {
                    foreach (var item in param)
                    {
                        rows += Db.Execute(item.Item1, item.Item2, DbTransaction);
                    }
                }
                catch (DataException ex)
                {
                    DbTransaction.Rollback();
                }
                DbTransaction.Commit();
            }
            return rows;
        }

    }

dapper支持异步操作,非常方便了。

2.APIModel介绍:

这个层是对数据库表的映射,可以用t4模板或者其他的生成model,代码我就不贴出来了。

3.Common介绍:

这个层是一些常用方法的封装,比如说IO操作,等等。

4.Responsitory介绍:

这个层是数据库访问层,针对单个model的一些操作。代码如下:

   public class UserInfoResponsitory : IUserInfoResponsitory
    {
        public async Task<IEnumerable<UserInfo>> GetAllList()
        {

            string sql = "select Id, Name ,Age, Salary, DaptId, CreateTime,Pwd from user";

            var list = await DbContexts.Select<UserInfo>(sql);

            return list;
        }

        public async Task<bool> AddUserInfo(UserInfo userinfo)
        {

            string query = "insert into user(Name, Age,Salary,DaptId,CreateTIme,Pwd) values(@name,@age,@salary,@daptid,@createtime,@pwd)";
            int row = await DbContexts.Update<UserInfo>(query, userinfo);

            return row > 0;
        }

        public async Task<bool> updateUserInfo(UserInfo userinfo)
        {

            string query = "update user set name = @name where id = @id";

            int row = await DbContexts.Update<UserInfo>(query, userinfo);

            return row > 0;
        }

        public async Task<IEnumerable<UserInfo>> GetUserInfoById(int id)
        {
            var user = await DbContexts.Select<UserInfo>("select id,name, age, salary, daptId, createtime, pwd from user where id= @UserId", new { UserId = id });

            return user;
        }


        public async Task<IEnumerable<UserInfo>> GetUserInfoList(int PageIndex, int PageSize)
        {
            string query = "select * from user limit @limitnumber,10";

            var list = await DbContexts.Select<UserInfo>(query, new { limitnumber = (PageIndex - 1) * 10 });

            return list;
        }

    }

5.IResponsitory层介绍:

这个是数据库访问层的接口层,声明操作的方法,不实现

    public interface IUserInfoResponsitory
    {
        Task<IEnumerable<UserInfo>> GetAllList();

        #region 增加
        /// <summary>
        /// 增加用户
        /// </summary>
        /// <param name="userinfo"></param>
        /// <returns></returns>
        Task<bool> AddUserInfo(UserInfo userinfo);
        #endregion


        #region  修改
        /// <summary>
        ///修改个人信息
        /// </summary>
        /// <param name="userinfo"></param>
        /// <returns></returns>
        Task<bool> updateUserInfo(UserInfo userinfo);
        #endregion

        /// <summary>
        /// 根据Id获取用户数据
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        Task<IEnumerable<UserInfo>> GetUserInfoById(int UserId);

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="PageIndex"></param>
        /// <param name="PageSize"></param>
        /// <returns></returns>
        Task<IEnumerable<UserInfo>> GetUserInfoList(int PageIndex, int PageSize);

IOC集成:

我使用的是autofac的构造函数注入,代码如下:

            var builder = new ContainerBuilder();

            Type basetype = typeof(IDependency);

            var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();

            var Allservices = assemblys.SelectMany(s => s.GetTypes())
                .Where(p => basetype.IsAssignableFrom(p) && p != basetype);

            builder.RegisterApiControllers(assemblys.ToArray());

            builder.RegisterAssemblyTypes(assemblys.ToArray())
                .Where(t => basetype.IsAssignableFrom(t) && t.IsClass )
                .AsImplementedInterfaces().InstancePerRequest();

            builder.RegisterType<UserService>().As<IUserService>().InstancePerRequest();

            var container = builder.Build();
            var resolver = new AutofacWebApiDependencyResolver(container);
            GlobalConfiguration.Configuration.DependencyResolver = resolver;

因为我用的是web api框架,所以引用autofac包的时候,要装下面几个包

框架总结:

由于时间有限,我这个框架搭的优点简单,应该在responsitory层上面加一个服务层,不暴露具体的数据库操作,只向外提供服务层的方法。

over

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值