Android Studio使用webservice远程访问数据库SQL Server 2008 R2

首先说一下背景,由于目前个人自学Android Studio,参考度娘实现连接DB的方式,总结出目前主流的两种方式:
1)使用jtds直接访问DB数据库(参考:https://blog.csdn.net/feidie436/article/details/77532194/)方式
2)另外一种就是比较主流的以webservice方式进行远程访问数据库,使用ksoap2进行数据读取及GSON进行数据解析
但是jtds目前有点弊端,建议局域网,少数人使用。所以这次主要以Android Studio+webservice+ksoap2+GSON的方式读取数据进行总结归纳
开发环境
1、windows 10专业版本X64(**版,需要安装IIS,度娘上面有很多安装IIS的教程)
2、Visual Studio 2013旗舰版(又是盗版,穷逼一个,需要进行部署webservice)
3、Android Studio(这个是正版,需要ksoap2-android-assembly-3.6.4-jar-with-dependencies.jar(这个需要自己下载,可以进行ksoap2的官网下载,CSDN的资源下载太贵,伤不起,然后放在android项目libs目录下导入Android Studio到)和导入Android Studio自带的com.google.code.gson:gson2.8.5和GsonFormat,度娘上面有很多如何从Android Studio自动添加gson和GsonFormat的方法,这边就不细说了,另外gson的版本可能不一样,但是我现在Android Studio3.3.2的自带是gson2.8.5,这些都不重要,用法都是一样的,另外还需用到AsyncTask异步多线程,Android 不能在主线程直接访问数据库,必须用到异步才能进行)
4、SQL Server 2008 R2版本的(网上找的**版,挺好用的)
实现逻辑
第一步:安装SQL Server 2008 R2,Visual Studio 2013,Android Studio
因为是盗版的windows系统,在安装系统环境的时候遇到各种问题,比如windows没有IIS组件,比如在运行Visual Studio 2013的时候报错:内存被占用,最坑的一次是,什么都安装完了,还免费**400年…结果第3天,系统变未**,系统还原初始状态,系统Patch参数全部清空,SQL Server 2008 R2及多个软件不能启动…不过还好,最后终于找到一个系统版本,免费**180天的,一直用到了现在,所以想吐槽一下,那些GHOST系统版本的,能不能不要精简了。
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
第二步:Visual Studio 2013创建个空网站,新建webserver服务,访问及操作数据库
1)Visual Studio 2013新建一个空白网站
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
2)新建项目->Web服务(ASMX)
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
3)配置Web.config
add name=“conn_data” connectionString=“server=.;database=testDB;user id=sa;password=618531;Max Pool Size=50000;Min Pool Size=2;Pooling=true;Connect Timeout=60000;” providerName=“System.Data.SqlClient”
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
4)编写SQLHelper.cs文件用来进行数据库操作

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace DBUtility
{
///
/// 数据库访问类,
///
public class SQLHelper
{
#region 全局变量定义
private static SQLHelper sqldb;
///
/// 定义数据库链接字符串
///
private string sqlConnStr = “”;
private SqlConnection con;
#endregion

    #region <!------------------SQlhelper对象重载------------------->
    /// <summary>
    /// 根据默认连接字符串实例化
    /// </summary>
    public SQLHelper()
    {
        sqlConnStr = System.Configuration.ConfigurationManager.ConnectionStrings["conn_data"].ToString();
    }
    /// <summary>
    /// 根据指定数据库链接字符串实例化
    /// </summary>
    /// <param name="connectionName">指定数据库链接字符串值</param>
    public SQLHelper(string connectionName)
    {
        sqlConnStr = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName].ToString();
    }
    #endregion

    #region <!------------------返回一个SlqHelper类的实例------------------->
    /// <summary>
    /// 创建SqlHelper的对象(默认数据库链接connName=conn_data)
    /// </summary>
    /// <returns>sqlhelper实例</returns>
    public static SQLHelper CreateSQLHelper()
    {
        
        if (sqldb == null)
        {
            sqldb = new SQLHelper();
            return sqldb;
        }
        else
        {
            return sqldb;
        }
    }
    /// <summary>
    /// 创建SqlHelper的对象(指定数据库链接connName=自定义的非'conn_data')
    /// </summary>
    /// <param name="connectionName">数据库链接字符串在config中的键值名称</param>
    /// <returns>sqlhelper实例</returns>
    public static SQLHelper CreateSQLHelper(string connectionName)
    {
        //如需要用到,可能会修改对象名,否则无法真正重载此函数(sqldb不为空)
        if (sqldb == null)
        {
            sqldb = new SQLHelper(connectionName);
            return sqldb;
        }
        else
        {
            return sqldb;
        }
    }
    #endregion

    #region  <!------------------连接数据库 获得一个sqlconnection的连接 及数据库链接操作------------------->
    /// <summary>
    /// 连接数据库对象及数据库链接操作
    /// </summary>
    public SqlConnection CreateConnecton()
    {
        string connstr = sqlConnStr;// System.Configuration.ConfigurationManager.ConnectionStrings["conn_data"].ToString();
        try
        {
            con = new SqlConnection(connstr);
        }
        catch (SqlException ex)
        {
            throw ex;
        }
        return con;
    }
    /// <summary>
    /// 打开数据库链接
    /// </summary>
    private void ConnOpen()
    {
        if (con.State != ConnectionState.Open)
        {
            con.Open();
        }
    }
    /// <summary>
    /// 关闭数据库链接 同时释放sqlconnection资源
    /// </summary>
    private void ConnClose()
    {
        if (con.State == ConnectionState.Open)
        {
            con.Close();
            con.Dispose();
        }
        else
        {
            con.Dispose();
        }
    }
    #endregion

    #region <!------------------数据库的增、删、改更新操作------------------->
    #region <!------------------sql语句执行------------------->
    /// <summary>
    /// 执行不带参数的sql语句,更新数据库返回受影响的行数
    /// </summary>
    /// <param name="cmdText">T-SQL语句</param>
    /// <returns></returns>
    public int TSQLExecuteNonQuery(string cmdText)
    {
        return TSQLExecuteNonQuery(cmdText, null);
    }   

    /// <summary>
    /// 执行带参数的sql语句,更新数据库返回受影响的行数
    /// </summary>
    /// <param name="cmdText">T-SQL语句</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns></returns>
    public int TSQLExecuteNonQuery(string cmdText, params SqlParameter[] commandParameters)
    {
        int val = 0;
        try
        {
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn=CreateConnecton())
            {
                //conn = CreateConnecton();
                PrepareCommand(cmd, null, CommandType.Text, cmdText, commandParameters,conn);
                val = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();
                return val;
            }
        }
        catch(SqlException ex)
        {
            //ConnClose();
            throw ex;
        }
        return val;
    }
    #endregion

    #region <!------------------存储过程执行------------------->
    /// <summary>
    /// 执行不带参数的存储过程,更新数据库并返回受影响的行数
    /// </summary>
    /// <param name="cmdText">存储过程名称</param>
    /// <returns>返回受影响的行数</returns>
    public int PROCExecuteNonQuery(string procName)
    {
        return PROCExecuteNonQuery(procName,null,null);
    }
    /// <summary>
    /// 执行带参数的存储过程,更新数据库并返回受影响的行数
    /// </summary>
    /// <param name="cmdText">存储过程名称</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>返回受影响的行数</returns>
    public int PROCExecuteNonQuery(string procName, params SqlParameter[] commandParameters)
    {
        return PROCExecuteNonQuery(procName, 0, commandParameters);
    }
    /// <summary>
    /// 执行带参数的存储过程,更新数据库并返回受影响的行数
    /// </summary>
    /// <param name="cmdText">存储过程名称</param>
    /// <param name="times">设置执行存储过程的时间 单位(秒)</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>返回受影响的行数</returns>
    public int PROCExecuteNonQuery(string procName,int times, params SqlParameter[] commandParameters)
    {
        int val = 0;
        try
        {
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn = CreateConnecton())
            {
                
                PrepareCommand(cmd, null, CommandType.StoredProcedure, procName, commandParameters,times,conn);
                val = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();
                return val;
            }
        }
        catch (SqlException ex)
        {
            //ConnClose();
            throw ex;
        }
        return val;
    }
    #endregion
    #endregion

    #region <!------------------数据库查询结果集操作------------------->
    #region <!------------------1、sql语句执行------------------->
    /// <summary>
    /// 执行不带参数的SQL语句,返回结果为DataTable
    /// </summary>
    /// <param name="commandText">T-SQL 命令</param>
    /// <returns>一个包含返回结果集的DataTable</returns>
    public DataTable TSQLExecuteDataTable(string cmdText)
    {
        return TSQLExecuteDataTable(cmdText, null);
    }
    /// <summary>
    /// 执行带参数的SQL语句,返回结果为DataTable
    /// </summary>
    /// <param name="commandText">T-SQL 命令</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>一个包含返回结果集的DataTable</returns>
    public DataTable TSQLExecuteDataTable(string cmdText, params SqlParameter[] commandParameters)
    {
        DataTable dtbl = new DataTable();
        try
        {
            //conn = CreateConnecton();
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn=CreateConnecton())
            {
                PrepareCommand(cmd, null, CommandType.Text, cmdText, commandParameters,conn);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dtbl);
                da.Dispose();
                //ConnClose();
            }
        }
        catch (SqlException ex)
        {
            //ConnClose();
            throw ex;
        }
        return dtbl;
    }
    /// <summary>
    /// 执行不带参数的SQL语句,返回结果为DataSet
    /// </summary>
    /// <param name="commandText">T-SQL 命令</param>
    /// <returns>一个包含返回结果集的DataSet</returns>
    public DataSet TSQLExecuteDataSet(string cmdText)
    {
        return TSQLExecuteDataSet(cmdText, null);
    }
    /// <summary>
    /// 执行带参数的SQL语句,返回结果为DataSet
    /// </summary>
    /// <param name="commandText">T-SQL 命令</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>一个包含返回结果集的DataSet</returns>
    public DataSet TSQLExecuteDataSet(string cmdText, params SqlParameter[] commandParameters)
    {
        DataSet ds = new DataSet();
        DataTable dt = new DataTable("0");
        try
        {
            //conn = CreateConnecton();
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn=CreateConnecton())
            {
                PrepareCommand(cmd, null, CommandType.Text, cmdText, commandParameters,conn);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dt);
                da.Dispose();
                //ConnClose();
                
            }
        }
        catch (SqlException ex)
        {
            //ConnClose();
            throw ex;
        }
        ds.Tables.Add(dt);
        return ds;
    }
    /// <summary>
    /// 执行不带参数的SQL语句,返回结果为DataReader
    /// </summary>
    /// <param name="cmdText">T-SQL语句</param>
    /// <returns>返回类型为datareader的结果集</returns>
    public SqlDataReader TSQLExecuteReader(string cmdText)
    {
        SqlDataReader sdr = TSQLExecuteReader(cmdText, null);
        return sdr;
    }
    /// <summary>
    /// 执行带参数的SQL语句,返回结果为DataReader
    /// </summary>
    /// <param name="cmdText">T-SQL语句</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>返回类型为datareader的结果集</returns>
    public SqlDataReader TSQLExecuteReader(string cmdText, params SqlParameter[] commandParameters)
    {
        try
        {
            SqlCommand cmd = new SqlCommand();
            SqlConnection conn = CreateConnecton();
            //{
                //conn = CreateConnecton();
                PrepareCommand(cmd, null, CommandType.Text, cmdText, commandParameters,conn);
                SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                cmd.Parameters.Clear();
                //rdr.Dispose();
                //ConnClose();
                return rdr;
            //}
        }
        catch (Exception ex)
        {
            //ConnClose();
            throw ex;
        }
    }
    /// <summary>
    /// 执行不带参数的sql语句,返回首行首列值,忽略其他行
    /// </summary>
    /// <param name="cmdText">T-SQL命令</param>
    /// <returns></returns>
    public object TSQLExecuteScalar(string cmdText)
    {
        return TSQLExecuteScalar(cmdText, null);
    }
    /// <summary>
    /// 执行带参数的sql语句,返回首行首列值,忽略其他行
    /// </summary>
    /// <param name="cmdText">T-SQL命令</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns></returns>
    public object TSQLExecuteScalar(string cmdText, params SqlParameter[] commandParameters)
    {
        object obj = null;
        SqlCommand cmd = new SqlCommand();
        using (SqlConnection conn=CreateConnecton())
        {
            try
            {
                //conn = CreateConnecton();
                PrepareCommand(cmd, null, CommandType.Text, cmdText, commandParameters,conn);
                obj = cmd.ExecuteScalar();
                cmd.Parameters.Clear();
                //ConnClose();
            }
            catch (SqlException ex)
            {
                throw ex;
            }
        }
        return obj;
    }
    #endregion

    #region <!------------------2、存储过程执行------------------->
    /// <summary>
    /// 执行不带参数的存储过程,返回结果为DataTable
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <returns>一个包含返回结果集的DataTable</returns>
    public DataTable PROCExecuteDataTable(string procName)
    {
        return TSQLExecuteDataTable(procName, null,null);
    }
    /// <summary>
    /// 执行带参数的存储过程,返回结果为DataTable
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>一个包含返回结果集的DataTable</returns>
    public DataTable PROCExecuteDataTable(string procName, params SqlParameter[] commandParameters)
    {
        return PROCExecuteDataTable(procName, 0, commandParameters);
    }
    /// <summary>
    /// 执行带参数的存储过程,返回结果为DataTable
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <param name="times">设置执行存储过程的时间 单位(秒)</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>一个包含返回结果集的DataTable</returns>
    public DataTable PROCExecuteDataTable(string procName,int times, params SqlParameter[] commandParameters)
    {
        DataTable dtbl = new DataTable();
        try
        {
            //conn = CreateConnecton();
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn=CreateConnecton())
            {
                PrepareCommand(cmd, null, CommandType.StoredProcedure, procName, commandParameters,times,conn);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dtbl);
                da.Dispose();
                //ConnClose();
            }
        }
        catch (SqlException ex)
        {
            //ConnClose();
            throw ex;
        }
        return dtbl;
    }

    /// <summary>
    /// 执行带有返回值的存储过程
    /// </summary>
    /// <param name="procName">存储过程名</param>
    /// <param name="param">输入参数</param>
    /// <param name="outparam">存储过程Output参数名称</param>
    /// <returns></returns>
    public string RunProcReturn(string procName, SqlParameter[] param,string outparam)
    {
        string retstr = "";
        try
        {
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn = CreateConnecton())
            {
                cmd.Connection = conn;
                conn.Open();
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = procName;
                if (param != null)
                {
                    foreach (SqlParameter sp in param)
                    {
                        cmd.Parameters.Add(sp);
                    }
                }
                SqlParameter sp1 = cmd.Parameters.Add(outparam,SqlDbType.VarChar,500);
                sp1.Direction = ParameterDirection.Output;
                cmd.ExecuteNonQuery();
                retstr = Convert.ToString(sp1.Value);
            }
        }
        catch (Exception ex)
        {

            throw ex;
        }
        return retstr;
    }
    

    /// <summary>
    /// 执行不带参数的存储过程,返回结果为DataSet
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <returns>一个包含返回结果集的DataSet</returns>
    public DataSet PROCExecuteDataSet(string procName)
    {
        return PROCExecuteDataSet(procName, 0,null);
    }
    /// <summary>
    /// 执行带参数的存储过程,返回结果为DataSet
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>一个包含返回结果集的DataSet</returns>
    public DataSet PROCExecuteDataSet(string procName, params SqlParameter[] commandParameters)
    {
        return PROCExecuteDataSet(procName, 0, commandParameters);
    }
    /// <summary>
    /// 执行带参数的存储过程,返回结果为DataSet
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <param name="times">设置执行存储过程的时间 单位(秒)</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns>一个包含返回结果集的DataSet</returns>
    public DataSet PROCExecuteDataSet(string procName,int times, params SqlParameter[] commandParameters)
    {
        DataSet ds = new DataSet();
        DataTable dt = new DataTable("0");
        try
        {
            //conn = CreateConnecton();
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn=CreateConnecton())
            {
                PrepareCommand(cmd, null, CommandType.Text, procName, commandParameters,times,conn);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dt);
                da.Dispose();
                //ConnClose();
                
            }
        }
        catch (SqlException ex)
        {
            //ConnClose();
            throw ex;
        }
        ds.Tables.Add(dt);
        return ds;
    }
    /// <summary>
    /// 执行不带参数的存储过程,返回结果为DataReader
    /// </summary>
    /// <param name="procName"></param>
    /// <returns></returns>
    public SqlDataReader PROCExecuteReader(string procName)
    {
        return PROCExecuteReader(procName, 0 ,null);
    }
    /// <summary>
    /// 执行带参数的存储过程,返回结果为DataReader
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns></returns>
    public SqlDataReader PROCExecuteReader(string procName, params SqlParameter[] commandParameters)
    {
        return PROCExecuteReader(procName, 0, commandParameters);
    }
    /// <summary>
    /// 执行带参数的存储过程,返回结果为DataReader
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <param name="times">设置存储过程执行的时间 单位(秒)</param>
    /// <param name="commandParameters">一组用于执行命令的参数</param>
    /// <returns></returns>
    public SqlDataReader PROCExecuteReader(string procName,int times, params SqlParameter[] commandParameters)
    {
        try
        {
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn=CreateConnecton())
            {
                
                PrepareCommand(cmd, null, CommandType.StoredProcedure, procName, commandParameters,times,conn);
                SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                cmd.Parameters.Clear();
                rdr.Dispose();
                //ConnClose();
                return rdr;
            }
        }
        catch (SqlException ex)
        {
            //ConnClose();
            throw ex;
        }
    }
    /// <summary>
    /// 执行不带参数的存储过程,返回结果为object
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <returns></returns>
    public object PROCExecuteScalar(string procName)
    {
        return PROCExecuteScalar(procName, 0,null);
    }
    /// <summary>
    /// 执行带参数的存储过程,返回结果为object
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <param name="commandParameters">一组用于执行sql命令的参数</param>
    /// <returns></returns>
    public object PROCExecuteScalar(string procName, params SqlParameter[] commandParameters)
    {
        return PROCExecuteScalar(procName, 0,commandParameters);
    }
    /// <summary>
    /// 执行带参数的存储过程,返回结果为object
    /// </summary>
    /// <param name="procName">存储过程名称</param>
    /// <param name="times">设置存储过程执行的时间 单位(秒)</param>
    /// <param name="commandParameters">一组用于执行sql命令的参数</param>
    /// <returns></returns>
    public object PROCExecuteScalar(string procName,int times, params SqlParameter[] commandParameters)
    {
        object obj = null;
        SqlCommand cmd = new SqlCommand();
        using (SqlConnection conn=CreateConnecton())
        {
            try
            {
                PrepareCommand(cmd, null, CommandType.StoredProcedure, procName, commandParameters,conn);
                obj = cmd.ExecuteScalar();
                cmd.Parameters.Clear();
                //ConnClose();
            }
            catch (SqlException ex)
            {
                //ConnClose();
                throw ex;
            }
        }
        return obj;
    }
    #endregion
    #endregion

    #region <!------------------其他常用的特殊数据库相关操作------------------->
    #region <!------------------1、获取指定列的最大值------------------->
    //public int ExcuteSQL(string cmdText, SqlCommand cmd)
    //{
    //    int val = 0;
    //    //conn = CreateConnecton();
    //    //PrepareCommand(cmd, null, CommandType.Text, cmdText, null);
    //    cmd.CommandText = cmdText;
    //    val = cmd.ExecuteNonQuery();
    //    cmd.Parameters.Clear();
    //    return val;
    //}
    //public DataTable MyTest(string cmdText, SqlCommand cmd)
    //{
    //    DataTable dt = new DataTable();
    //    //PrepareCommand(cmd, null, CommandType.Text, cmdText, null);
    //    cmd.CommandText = cmdText;
    //    SqlDataAdapter da = new SqlDataAdapter(cmd);
    //    da.Fill(dt);
    //    da.Dispose();
    //    //ConnClose();
    //    return dt;
    //}
    #endregion

    #region <!------------------2、执行多条sql语句的事物处理------------------->
    /// <summary>
    /// 执行多条sql语句的事物处理
    /// </summary>
    /// <param name="sqlList">sql语句列表</param>
    /// <returns></returns>
    public int ExecuteTranSqlList(List<String> sqlList)
    {
        SqlConnection conn = CreateConnecton();
        ConnOpen();
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        SqlTransaction tran = conn.BeginTransaction();
        cmd.Transaction = tran;
        try
        {
            int count = 0;
            for (int i = 0; i < sqlList.Count; i++)
            {
                string strsql = sqlList[i];
                if (strsql.Trim().Length > 1)
                {
                    cmd.CommandText = strsql;
                    count += cmd.ExecuteNonQuery();
                }
            }
            tran.Commit();
            return count;
        }
        catch (SqlException ex)
        {
            tran.Rollback();
            ConnClose();
            return 0;
        }

    }

    /// <summary>
    /// 执行多条sql语句的事物处理,params参数为第一条sql语句使用
    /// </summary>
    /// <param name="sqlList"></param>
    /// <param name="commandParameters"></param>
    /// <returns></returns>
    public int ExecuteTranSqlList(List<string> sqlList, string strLast, params SqlParameter[] commandParameters)
    {
        SqlConnection conn = CreateConnecton();
        ConnOpen();
        SqlTransaction tran = conn.BeginTransaction();
        try
        {
            SqlCommand cmd = new SqlCommand("", conn, tran);
            cmd.CommandType = CommandType.Text;
            int count = 0;
            for (int i = 0; i < sqlList.Count; i++)
            {
                string strSql = sqlList[i];
                if (strSql.Trim().Length > 1)
                {
                    if (i == 0)
                    {
                        cmd.CommandText = strSql;
                        if (commandParameters != null)
                        {
                            foreach (SqlParameter parm in commandParameters)
                                cmd.Parameters.Add(parm);
                        }
                        count = int.Parse(cmd.ExecuteScalar().ToString());
                        cmd.Parameters.Clear();
                    }
                    else
                    {
                        if (strLast == "")
                        {
                            cmd.CommandText = strSql;
                            cmd.ExecuteNonQuery();
                        }
                        else
                        {
                            cmd.CommandText = strSql + count + strLast;
                            cmd.ExecuteNonQuery();
                        }
                    }
                }
            }
            tran.Commit();
            return count;
        }
        catch (SqlException ex)
        {
            tran.Rollback();
            ConnClose();
            return 0;
        }
    }

    #endregion

    #region <!------------------3、判断是否存在表中的某个字段、表------------------->
    /// <summary>
    /// 判断表中是否存在某个字段
    /// </summary>
    /// <param name="colunmName">字段名</param>
    /// <param name="tableName">表名</param>
    /// <returns>true则表示存在,false表示不存在</returns>
    public bool DiscoverValidOFColumn(string columnName, string tableName)
    {
        object res = null;
        string sql = "select count(1) from syscolumns where [id]=object_id('" + tableName + "') and [name] ='" + columnName + "'";
        try
        {
            res = TSQLExecuteScalar(sql);
        }
        catch (SqlException ex)
        {
            throw ex;
        }
        if (res == null)
        {
            return false;
        }
        return Convert.ToInt32(res) > 0;
    }
    /// <summary>
    /// 检查数据表是否存在
    /// </summary>
    /// <param name="TableName">表名</param>
    /// <returns></returns>
    public bool TableIsExist(string tableName)
    {
        bool blRet = false;
        DataTable dtRet = TSQLExecuteDataTable("Select * From sysobjects Where name='" + tableName + "'");
        if (dtRet != null && dtRet.Rows.Count >= 1) { blRet = true; }
        return blRet;
    }
    #endregion

    #region <!------------------4、返回表中指定列的第一行值 object------------------->
    /// <summary>
    /// 有数据返回true
    /// </summary>
    /// <param name="cmdText">sql</param>
    /// <returns>大于0返回true</returns>
    public bool Exists(string cmdText)
    {
        return Exists(cmdText, null);
    }
    /// <summary>
    /// 获取指表的第一行中指定列的值
    /// </summary>
    /// <param name="columnName">指定列名</param>
    /// <param name="tableName">指定表名</param>
    /// <param name="conditionsValue">sql条件语句(不包含‘where’关键字)例如‘1=1’</param>
    /// <returns></returns>
    public object GetFirstRowAndColumn(string columnName, string tableName, string conditionsValue)
    {
        string cmdText = "select " + columnName + " from " + tableName + " where " + conditionsValue;
        object obj = null;
        DataTable dt = new DataTable();
        try
        {
            //conn = CreateConnecton();
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn=CreateConnecton())
            {
                PrepareCommand(cmd, null, CommandType.Text, cmdText, null,conn);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dt);
                da.Dispose();
                obj = dt.Rows[0][0];
                ConnClose();
            }
        }
        catch (SqlException ex)
        {
            ConnClose();
            throw ex;
        }
        return obj;
    }
    #endregion

    /// <summary>
    /// 有数据返回true
    /// </summary>
    /// <param name="cmdText">sql</param>
    /// <param name="commandParameters">参数</param>
    /// <returns>大于0返回true</returns>
    public bool Exists(string cmdText, params SqlParameter[] commandParameters)
    {
        SqlConnection conn = CreateConnecton();
        ConnOpen();
        bool val;
        try
        {
            int colvalue = int.Parse(TSQLExecuteScalar(cmdText, commandParameters).ToString());
            if (colvalue > 0)
                val = true;
            else
                val = false;
        }
        catch
        {
            val = false;
        }
        finally
        {
            ConnClose();
        }
            
        return val;
    }
    #endregion

    #region 封装 参数
    /// <summary>
    /// Prepare a command for execution
    /// </summary>
    /// <param name="cmd">SqlCommand object</param>
    /// <param name="conn">SqlConnection object</param>
    /// <param name="trans">SqlTransaction object</param>
    /// <param name="cmdType">Cmd type e.g. stored procedure or text</param>
    /// <param name="cmdText">Command text, e.g. Select * from Products</param>
    /// <param name="cmdParms">SqlParameters to use in the command</param>
    private void PrepareCommand(SqlCommand cmd, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms,SqlConnection conn)
    {

        //ConnOpen();
        if (conn.State != ConnectionState.Open)
            conn.Open();

        cmd.Connection = conn;
        cmd.CommandText = cmdText;
        if (trans != null)
            cmd.Transaction = trans;
         
        cmd.CommandType = cmdType;

        if (cmdParms != null)
        {
            foreach (SqlParameter parm in cmdParms)
                cmd.Parameters.Add(parm);
        }
    }
    /// <summary>
    /// 新增超时判断的重载
    /// </summary>
    /// <param name="cmd">SqlCommand object</param>
    /// <param name="conn">SqlConnection object</param>
    /// <param name="trans">SqlTransaction object</param>
    /// <param name="cmdType">Cmd type e.g. stored procedure or text</param>
    /// <param name="cmdText">Command text, e.g. Select * from Products</param>
    /// <param name="cmdParms">SqlParameters to use in the command</param>
    /// <param name="times">设置连接执行的响应时间  单位为秒</param>
    private void PrepareCommand(SqlCommand cmd, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms,int times,SqlConnection conn)
    {

        //ConnOpen();
        if (conn.State != ConnectionState.Open)
            conn.Open();

        cmd.Connection = conn;
        cmd.CommandText = cmdText;
        if (trans != null)
            cmd.Transaction = trans;
        if (times != 0)
            cmd.CommandTimeout = times;
        cmd.CommandType = cmdType;

        if (cmdParms != null)
        {
            foreach (SqlParameter parm in cmdParms)
                cmd.Parameters.Add(parm);
        }
    }
    #endregion
}

}

5)编写AndroidWebServer.asmx逻辑读取或操作数据

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data;
using System.Data.SqlClient;
using DBUtility;
///
/// AndroidWebServer 的摘要说明
///
[WebService(Namespace = “http://tempuri.org/”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。
// [System.Web.Script.Services.ScriptService]
public class AndroidWebServer : System.Web.Services.WebService {

public AndroidWebServer () {

    //如果使用设计的组件,请取消注释以下行 
    //InitializeComponent(); 
}

[WebMethod]
public string HelloWorld() {
    return "Hello World";
}



[WebMethod(Description = "查询测试")]
public DataSet GetSelectDS(string sql)
{
    SQLHelper db = new SQLHelper();
    DataSet ds = db.TSQLExecuteDataSet(sql);
    return ds;
}

[WebMethod(Description = "数据库的增、删、改更新操作")]
public int SetExecuteNonQuery(string sql)
{
    SQLHelper db = new SQLHelper();
    int ExecuteCounts = db.TSQLExecuteNonQuery(sql);
    return ExecuteCounts;
}    

}

6)运行调试
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
(注意:Andorid获取的数据最好是DataSet格式,不然可能导致失败,该webservers比较简单,主要用在测试,到时andorid可以直接写Select或insert,update,delete等SQL语句进行获取或操作数据,当然也可以用存储过程写在webserver里面进行逻辑操作,关于这个已经全部包含在SQLHelper.cs里面,直接调用就可以了)

第三步:进行Android Studio进行webservers访问及数据转换处理
1)在ksoap2官网下载最新的ksoap2.jar(ksoap2主要是用来链接webservers及基础的webservers XML数据处理),官网直接问度娘把,我已经忘记地址了,至于版本直接在官网下载最新的就可以了,我当时下载的版本是ksoap2-android-assembly-3.6.4-jar-with-dependencies,下载好的内容直接复制到Android Studio自己项目的Libs里面,复制完后右键点击新黏贴的jar,在弹出菜单中点击Add As Library,如何还是不会的童靴门可以参照度娘:AndroidStudio怎样导入jar包
2)在Android Studio导入自带的com.google.code.gson:gson2.8.5和GsonFormat,也可以参照度娘:在Android Studio中如何添加GSON 并使用GsonFormat快速实现实体类
3)创建测试java实体类,先创建一个空白的Java Class类,然后使用最上方code-Generate-GsonFormat或者Alt+Insert然后选择GsonFormat,把已经格式化好的json复制进来,点击OK就哦了。
我写的是{“id”: “1”, “username”: 6000820,“pwd”: “6000820测试”}
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
但是还需要在自己生成的实体类里面重写toString()函数,主要是后面用来让:java对象转换为JSON字符串,这部分要自己写
@Override
public String toString() {
return “TestDT [id=” + id + “, username=” + username + “, pwd=” + pwd + “]”; //让java对象转换为JSON字符串
}
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
4)在android studio里面新建一个空白的Activity窗体用来把数据显示在界面上面,我这边打算做一个简单的返回,点击确认按钮,把数据显示在EditText里面
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
5)界面画好后,需要创建一个空白的Java Class类,用来继承AsyncTask,AsyncTask是android studio封装好的(Thread+Handler)的线程通信方式,但是AsyncTask目前并不是那么的完美,如果在用于大量并发处理的时候需要各位小心,因为AsyncTask默认线程是SERIAL_EXECUTOR,即按照先后顺序依次调用(假设有两个网路请求,第一个是文件上传,第二个是接口调用,那么接口调用会等待文件下载完毕后执行,而不是立即执行,另外由于顺序模式存在排队的情况,Android提供了executeOnExecutor方法,允许开发者指定任务线程池),不过AsyncTask自带的THREAD_POOL_EXECUTOR也存在瓶颈,该线程池最大线程数是电脑CPU的两倍+1,最大线程SIZE=CPU_COUNT2+1,如果用户手机是双核CPU,那么最大线程数是22+1=5个,因此CPU个数越多,APP运行越流畅是有依据的,不晓得我去年双11花了4000大洋买的HTCU12+烈焰红唇版是多少核的CPU,反正用起来用种丝滑般的感觉,不过想吐槽的是,我怎么双11买了几天后,HTC的手机就下架了,怎么就绝版了呢… 好的直接贴代码,不聊了

package com.example.myapplication;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Message;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;

import com.example.myapplication.DBTable.TestDT;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONObject;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

class DBHelper extends AsyncTask<String, Integer, String> {

private String result;
private EditText text;
private List<TestDT> TestDT = new ArrayList<TestDT>();//创建TestDT的实体类

DBHelper(EditText text) //构造函数非常重要,主要用于回调处理的结果内容给予主线程(另外还有一种方式用回调函数可以使用,这边的参数EditText,在主线程的EditText空间,用来显示数据,当然也可以用其他的类型,不是必须要用EditText,可以自己定义)
{
    this.text = text;
}

@Override
//该方法是执行AsyncTask的时候,实现逻辑的方法
protected String doInBackground(String[] params) {   
    try {
        result = getRemoteInfo(params[0]);

    } catch (Exception e) {
        e.printStackTrace();
    }
    //将结果返回给onPostExecute方法
    return result;
}

@Override
 //此方法可以在主线程改变UI,主要是进行返回结果到主线程
protected void onPostExecute(String msg) {
    super.onPostExecute(msg);
    if (msg != null) {
        text.setText(msg);

    } else {
        text.setText("查询不到数据~~~");
    }
}

/**
 * 测试Webserver访问数据库查询及编辑DB
 *
 * @param sSQL SQL查询语句
 */
public String getRemoteInfo(String sSQL) throws Exception {
    String WSDL_URI = "http://192.168.0.101/AndroidWebServer.asmx";//wsdl 的uri (这个是自己PC IIS发布的webserver网站地址)
    String namespace = "http://tempuri.org/";//namespace
    String methodName = "GetSelectDS";//要调用的方法名称(这个是IIS发布的webserver网站,需要调用的方法,我们前面的例子有GetSelectDS和SetExecuteNonQuery方法)
    SoapObject request = new SoapObject(namespace, methodName);
    // 设置需调用WebService接口需要传入的两个参数mobileCode、userId
    request.addProperty("sql", sSQL);
    //创建SoapSerializationEnvelope 对象,同时指定soap版本号(之前在wsdl中看到的)
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER12);
    envelope.bodyOut = request;//由于是发送请求,所以是设置bodyOut
    envelope.dotNet = true;//由于是.net开发的webservice,所以这里要设置为true
    HttpTransportSE httpTransportSE = new HttpTransportSE(WSDL_URI);
    httpTransportSE.call(null, envelope);//调用0
    Gson gson = new Gson();  //创建Gson对象
    // 获取返回的数据
    // SoapObject object = (SoapObject) envelope.bodyIn;
    // Object object = (Object) envelope.getResponse();
    SoapObject object = (SoapObject) envelope.getResponse();
    if (envelope.getResponse() != null) {
        SoapObject soapObject = (SoapObject) envelope.bodyIn;
        SoapObject soap1 = (SoapObject) soapObject.getProperty("GetSelectDSResult");//此时的获取到的信息是 (获取webserver的调用的方法名称)
        SoapObject soapChilds = (SoapObject) soap1.getProperty(1);//因为0位置对我们来说没有数据,所以我们去1位置的信息
        SoapObject soap2 = (SoapObject) soapChilds.getProperty(0);//去掉了前面的部分anyType
        if (TestDT.size() > 0) {//对实体类进行clear作业
            TestDT.clear();
        }
        for (int i = 0; i < soap2.getPropertyCount(); i++) {
            SoapObject soap3 = (SoapObject) soap2.getProperty(i);//取出每个视频信息
            TestDT film = new TestDT();
            film.setId(soap3.getProperty("id").toString());
            film.setUsername(soap3.getProperty("username").toString());
            film.setPwd(soap3.getProperty("pwd").toString());
            TestDT.add(film);//封装后存入集合中
        }
    }
    String objectStr = TestDT.toString();//让java对象转换为LIST字符串
    String gsStr = gson.toJson(TestDT);//让java对象转换为Json字符串
    result = gsStr;
    Log.d("debug", result);
    return result;
}

}
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
6)在前面空白的Activity窗体中,在后台编写调用DBHelper(AsyncTask)的逻辑,实现数据的显示
package com.example.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MyLogin extends AppCompatActivity implements View.OnClickListener {

Button bt;
Button bt2;
EditText edt;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_login);
    bt = findViewById(R.id.MyLoginBT1);
    bt.setOnClickListener(this);
    bt2 = findViewById(R.id.MyLoginBT2);
    bt2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
    EditText ET1 = (EditText) findViewById(R.id.MyLogintv1);
    if (v.getId() == R.id.MyLoginBT1) {
        ET1.setText("第一次文本框");
        sendRequestForListData();
    }
    if (v.getId() == R.id.MyLoginBT2) {
        ET1.setText("第二次文本框");
    }
}
private void sendRequestForListData()
{
    try {
        String sStr="";
        edt = (EditText) findViewById(R.id.MyLogintv1);
        //启动后台异步线程进行连接webService操作,并且根据返回结果在主线程中改变UI
         DBHelper socketConn = new DBHelper(edt);
        //启动后台任务
        socketConn.execute(" Select * From TestDT ");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
7)最后需要在Android Studio打开手机网络访问权限,在AndoridMainifest.xml配置信息中添加

Android Studio使用webservice远程访问数据库SQL Server 2008 R2
8)启动夜神模拟器,进行最后调试(我没有用Android Studio自带的模拟器,主要是自带的太卡,太不方便,启动也麻烦),夜神模拟器真的很方便,怎么使用可以参照度娘(启动夜神nox_adb.exe connect 127.0.0.1:62001的时候,可以自己写个脚本放在桌面上,把夜神模拟器的安装地址写在系统Patch环境变量中,就可以一键启动模拟器)
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
Android Studio使用webservice远程访问数据库SQL Server 2008 R2
Android Studio使用webservice远程访问数据库SQL Server 2008 R2