IBatis.net+Autofac轻量级orm、ioc框架搭建系统

进来公司需要接入一套用户权限系统(原先的后台登录系统,用户是在xml文件里面写死的,包括访问权限,用户名密码等)。由于时间有限,又不想让自己的代码跟原先的代码一样紊乱。经过综合考虑,这里就放弃了Hibernate和Spring(配置过于繁琐,hql写起来也颇为麻烦),于是乎选择了IBatis和Autofac。

优点:IBatis和Autofac都是轻量级框架,相对于Hibernate和Spring配置相对简单一些,效率上也优于后者。

IBatis程序集:IBatisNet.Common.dll,IBatisNet.DataMapper.dll
IBatis配置文件:SQLMap.config,providers.config
- SQLMap.config

<?xml version="1.0" encoding="utf-8"?>
<sqlMapConfig
  xmlns="http://ibatis.apache.org/dataMapper"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <settings>
    <!--/是否使用Satement命名空间,这里的命名空间指的是映射文件中sqlMap节点的namespace属性,默认是false-->
    <setting useStatementNamespaces="false"/>
    <!--是否启用DataMapper的缓存机制,针对全部的SqlMap,默认是true-->
    <setting cacheModelsEnabled="true"/>
    <!--是否启用SqlMapConfig.xsd schema验证映射文件,默认是false-->
    <setting validateSqlMap="false"/>
  </settings>
  <!--配置数据驱动提供类配置文件的路径和文件名-->
  <providers resource="Config/providers.config"/>
  <!--如果在providers.config文件中指定了默认的数据库驱动,那么provider节点就不需要设置了,它的作用是在换数据库驱动时不需要修改providers.config文件。datasource节点用于指定ADO.NET Connection String.-->
  <database>
    <provider name="sqlServer2.0"/>
    <dataSource name="mydb" connectionString="data source=127.0.0.1;database=UserRole;user id=sa;password=sa;"/>
  </database>

  <!--指定映射的文件的位置-->
  <sqlMaps>
    <sqlMap resource="Maps/PageActionMap.xml"/>
    <sqlMap resource="Maps/PageMap.xml"/>
    <sqlMap resource="Maps/PermissionPageActionMap.xml"/>
    <sqlMap resource="Maps/PermissionPageMap.xml"/>
    <sqlMap resource="Maps/RoleMap.xml"/>
    <sqlMap resource="Maps/UserMap.xml"/>
    <sqlMap resource="Maps/UserRoleMap.xml"/>
  </sqlMaps>

</sqlMapConfig>

上述映射文件的UserMap.xml

<?xml version="1.0" encoding="utf-8" ?>
<!--namespace必须用否者就报错(读取配置文件报:未将对象引用设置到对象的实例)-->
<sqlMap namespace="User" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <alias>
    <!-- alias:取别名   
         assembly:表示类所在的文件
         type:表示该类的完整的名称
      -->
    <typeAlias alias="User" assembly="HC.JiShi.UserRole.dll" type="HC.JiShi.UserRole.Entity.UserPo" />
    <typeAlias alias="UserPermissionPage" assembly="HC.JiShi.UserRole.dll" type="HC.JiShi.UserRole.Entity.UserPermissionPagePo" />
    <typeAlias alias="UserPermissionPageAction" assembly="HC.JiShi.UserRole.dll" type="HC.JiShi.UserRole.Entity.UserPermissionPageActionPo" />
  </alias>

  <resultMaps>
    <resultMap id="UserResult"  class="User">
      <!--如果不取别名要使用类的全路径‘HC.JiShi.UserRole.Entity.UserPo’-->
      <result property="Id"    column="Id"/>
      <result property="UserName"    column="UserName"/>
      <result property="Password"    column="Password"/>
      <result property="CreateDate"    column="CreateDate"/>
      <result property="IsAdmin"    column="IsAdmin"/>
      <result property="IsValid"    column="IsValid"/>
    </resultMap>

    <resultMap id="UserPermissionPageResult"  class="UserPermissionPage">
      <result property="UserId"    column="UserId"/>
      <result property="PageId"    column="PageId"/>
      <result property="PageName"    column="PageName"/>
      <result property="Url"    column="Url"/>
      <result property="Domain"    column="Domain"/>
    </resultMap>

    <resultMap id="UserPermissionPageActionResult"  class="UserPermissionPageAction">
      <result property="UserId"    column="UserId"/>
      <result property="PageActionId"    column="PageActionId"/>
      <result property="PageId"    column="PageId"/>
      <result property="ActionName"    column="ActionName"/>
      <result property="ActionUrl"    column="ActionUrl"/>
    </resultMap>
  </resultMaps>

  <statements>
    <select id="GetUserById" parameterClass="int" resultClass="User">
      SELECT * FROM [User] WHERE Id=#Id#
    </select>

    <insert id="AddUser" parameterClass="User">
      INSERT INTO [User]  VALUES(#UserName#,#Password#,#IsAdmin#,#IsValid#,#CreateDate#)
      <selectKey resultClass="int" type="post" property="Id">
        SELECT @@IDENTITY
      </selectKey>
    </insert>

    <delete id="DeleteUser" parameterClass="int" restultClass="int">
      DELETE FROM [User] WHERE Id=#Id#
    </delete>

    <delete id="DeleteUsers" parameterClass="List">
      DELETE FROM [User]
      <iterate prepend="WHERE" open="(" close=")" conjunction="OR">
        Id = #[]#
      </iterate>
    </delete>

    <update id="UpdateUser" parameterClass="User" restltClass="int">
      UPDATE [User] SET UserName=#UserName#,Password=#Password#,IsAdmin=#IsAdmin#,IsValid=#IsValid#,CreateDate=#CreateDate# WHERE Id=#Id#
    </update>
  </statements>
</sqlMap>

IBatis操作sql说明

属性

说明

parameterMap

参数映射,需结合parameterMap节点对映射关系加以定义,对于存储过程之外的statement而言,建议使用parameterClass作为参数配置方式,一方面避免了参数映射配置工作,另一方面其性能表现更加出色

parameterClass

参数类。指定了参数类型的完整类名(包括命名空间),可以通过别名避免每次书写冗长的类名

resultMap

结果映射,需结合resultMap节点对映射关系加以定义

resultClass

结果类。指定了结果类型的完整类名(包括命名空间),可以通过别名避免每次书写冗长的类名

cacheModel

Statement对应的Cache模块

extends

重复使用SQL子句

上面的底层已经写完,当然还需要一个IBatis的操作类Mapper.cs,这是我网上找的,有兴趣的可以自己再封装完善一下。
Mapper.cs

    public class Mapper
    {
        private static volatile ISqlMapper _mapper = null;

        protected static void Configure(object obj)
        {
            _mapper = null;
        }

        protected static void InitMapper()
        {
            var handler = new ConfigureHandler(Configure);
            var builder = new DomSqlMapBuilder();
            _mapper = builder.ConfigureAndWatch(handler);
        }

        public static ISqlMapper Instance()
        {
            if (_mapper == null)
            {
                lock (typeof(SqlMapper))
                {
                    if (_mapper == null) // double-check
                    {
                        InitMapper();
                    }
                }
            }
            return _mapper;
        }

        public static ISqlMapper Get()
        {
            return Instance();
        }


        /// <summary>
        /// RealMarket Mapper
        /// </summary>
        public static ISqlMapper GetMaper
        {
            get
            {
                if (_mapper == null)
                {
                    lock (typeof(ISqlMapper))
                    {
                        if (_mapper == null)
                        {
                            var hander = new ConfigureHandler(Configure);
                            var builder = new DomSqlMapBuilder();
                            _mapper = builder.ConfigureAndWatch("config/sqlmap.config", hander);
                        }
                    }
                }
                return _mapper;
            }
        }
    }

User表的操作类UserDao.cs

    public class UserDao : IUserDao
    {
        public int AddUser(UserPo user)
        {
            Object obj = Mapper.GetMaper.Insert("AddUser", user);
            return (int)obj;
        }

        public void DeleteUser(int id)
        {
            Mapper.GetMaper.Delete("DeleteUser", id);
        }

        public void DeleteUsers(List<int> ids)
        {
            Mapper.GetMaper.Delete("DeleteUsers", ids);
        }

        public void UpdateUser(UserPo user)
        {
            Mapper.GetMaper.Update("UpdateUser", user);
        }

        public void UpdateUserName(int id, string userName)
        {
            var htPram = new Hashtable { { "Id", id }, { "UserName", userName } };
            Mapper.GetMaper.Update("UpdateUserName", htPram);
        }

        public void UpdatePassword(int id, string password)
        {
            var htPram = new Hashtable { { "Id", id }, { "Password", password } };
            Mapper.GetMaper.Update("UpdatePassword", htPram);
        }

        public UserPo GetUser(int id)
        {
            return Mapper.GetMaper.QueryForObject<UserPo>("GetUserById", id);
        }
    }

上面是IBatis的部署及使用步骤,其中UserDao用户操作类继承自IUserDao

    public interface IUserDao
    {
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        int AddUser(UserPo user);

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        void DeleteUser(int id);

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids"></param>
        void DeleteUsers(List<int> ids);

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="user"></param>
        void UpdateUser(UserPo user);

        /// <summary>
        /// 更新用户名
        /// </summary>
        /// <param name="id"></param>
        /// <param name="userName"></param>
        void UpdateUserName(int id, string userName);

        /// <summary>
        /// 更新密码
        /// </summary>
        /// <param name="id"></param>
        /// <param name="password"></param>
        void UpdatePassword(int id, string password);

        /// <summary>
        /// 获取用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        UserPo GetUser(int id);
    }

那么如何使用Autofac来调用IUserDao呢?这里我们只需要通过代码在容器里面注册用户操作类
Container.cs

    using Autofac;

    public class Container
    {
        public static IContainer CommonContainer { get; set; }

        private static readonly ContainerBuilder Builder = new ContainerBuilder();

        static Container()
        {
            RegisterUserDao();
            CommonContainer = Builder.Build();
        }

        private static void RegisterUserDao()
        {
            Builder.RegisterType<UserDao>().As<IUserDao>();
        }
    }

最后一步使用

    public class UserService : IUserService
    {       
        private readonly IUserDao _userDao = Container.CommonContainer.Resolve<IUserDao>();

        public int AddUser(User user)
        {
            var checkUser = _userDao.GetUser(user.UserName);
            //判断用户名是否存在
            if (!checkUser.IsNullOrEmpty())
            {
                throw new BussinessException(ERROR_USERNAME_EXIST);
            }
            user.Password = DEncrypt.Encrypt(user.Password, Key);
            Object obj = _userDao.AddUser(GetUserPoFromUser(user));
            return (int)obj;
        }

        public void DeleteUser(int id)
        {
            _userDao.DeleteUser(id);
        }

        public void DeleteUsers(List<int> ids)
        {
            _userDao.DeleteUsers(ids);
        }
    }

可以按照上述操作扩展业务,完善业务层和数据层。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值