IBatisNet的問題總結

來源:互聯網
上載者:User
1.一個未解決的 iBatisNet 並發訪問問題

iBatisNet 是通過 SqlMap 執行個體執行 SQL Statement 的, 一個 SqlMap 執行個體裡封裝了資料庫連接和事務, 讓人難受的是, Cache 竟然也封裝在 SqlMap 裡。

大家知道, 我們可以通過以下方式獲得 SqlMap 執行個體:

a. SqlMap map = Mapper.Instance(); // 單件模式, 返回唯一執行個體

b. DomSqlMapBuilder builder = new DomSqlMapBuilder();
SqlMap map = builder.Configure(); // 返回新的 SqlMap 執行個體

在單線程的環境下, a 沒有問題, cache 也工作得很正常, 在多線程環境下, 因為 SqlMap 封裝了 Connection, 如果並發調用同一個 SqlMap 執行個體訪問資料庫的時候, 會拋出以下異常:
IBatisNet.DataMapper.Exceptions.DataMapperException: SqlMap could not invoke OpenConnection(). A connection is already started. Call CloseConnection first.

在多線程環境下, b 就派上用場了, 可以在每個線程的開始用 b 建立一個 SqlMap 執行個體, 然後用這個 SqlMap 對資料庫進行訪問。但問題也就來了, 因為 cache 是封裝在 SqlMap 裡的, 每個 SqlMap 都會建立一份自己的 cache, 也就是說, iBatisNet 內建的 cache 機制沒有用了。

真讓人失望, 我現在只好自己用 Hashtable 實現簡單的 cache 功能。 

]關於返回DataTable的一點問題

對於IBatisnet執行查詢返回DataTable,網上有很多代碼,下面簡單列出一下:

 

private IDbCommand GetDbCommand(string statementName, object paramObject)
        {
            IStatement statement = sqlMap.GetMappedStatement(statementName).Statement;

            IMappedStatement mapStatement = sqlMap.GetMappedStatement(statementName);

            IDalSession session = new SqlMapSession(sqlMap);

            if (sqlMap.LocalSession != null)
            {
                session = sqlMap.LocalSession;
            }
            else
            {
                session = sqlMap.OpenConnection();
            }

            RequestScope request = statement.Sql.GetRequestScope(mapStatement, paramObject, session);

            mapStatement.PreparedCommand.Create(request, session, statement, paramObject);

            return request.IDbCommand;

        }


        /**//// <summary>
        /// 通用的以DataTable的方式得到Select的結果(xml檔案中參數要使用$標記的佔位參數)
        /// </summary>
        /// <param name="statementName">語句ID</param>
        /// <param name="paramObject">語句所需要的參數</param>
        /// <returns>得到的DataTable</returns>
        protected DataTable ExecuteQueryForDataTable(string statementName, object paramObject)
        {
            DataSet ds = new DataSet();
            bool isSessionLocal = false;
            IDalSession session = sqlMap.LocalSession;
            if (session == null)
            {
                session = new SqlMapSession(sqlMap);
                session.OpenConnection();
                isSessionLocal = true;
            }

            IDbCommand cmd = GetDbCommand(statementName, paramObject);

            try
            {
                cmd.Connection = session.Connection;
                IDbDataAdapter adapter = session.CreateDataAdapter(cmd);
                adapter.Fill(ds);
            }
            finally
            {
                if (isSessionLocal)
                {
                    session.CloseConnection();
                }
            }

            return ds.Tables[0];

        }

理論上來說是沒任何問題的,但前幾天我做了有Output參數的預存程序來返回DataTable,如果用上面的ExecuteQueryForDataTable方法就會獲得不到Output的參數,因為它在傳回值的時候沒有用到IBatisNet內部的方法了,所以上面的方法嚴謹的寫法應該改成下面這樣:

/**//// <summary>
        /// 通用的以DataTable的方式得到Select的結果(xml檔案中參數要使用$標記的佔位參數)
        /// </summary>
        /// <param name="statementName">語句ID</param>
        /// <param name="paramObject">語句所需要的參數</param>
    /// <param name="htOutPutParameter)">Output參數值雜湊表</param>
        /// <returns>得到的DataTable</returns>
        protected DataTable ExecuteQueryForDataTable(string statementName, object paramObject, out Hashtable htOutPutParameter)
        {
            DataSet ds = new DataSet();
            bool isSessionLocal = false;
            IDalSession session = sqlMap.LocalSession;
            if (session == null)
            {
                session = new SqlMapSession(sqlMap);
                session.OpenConnection();
                isSessionLocal = true;
            }

            IDbCommand cmd = GetDbCommand(statementName, paramObject);

            try
            {
                cmd.Connection = session.Connection;
                IDbDataAdapter adapter = session.CreateDataAdapter(cmd);
                adapter.Fill(ds);
            }
            finally
            {
                if (isSessionLocal)
                {
                    session.CloseConnection();
                }
            }

            foreach (IDataParameter parameter in cmd.Parameters)
            {
                if (parameter.Direction == ParameterDirection.Output)
                {
                    htOutPutParameter[parameter.ParameterName] = parameter.Value;
                }
            }

            return ds.Tables[0];

        }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.