转自:http://www.cnblogs.com/yangcaogui/archive/2012/06/09/2537086.html

目录:

  1. 简单的介绍下ADO.NET
  2. SqlConnection(连接对象)
  3. SqlCommand(命令对象)
  4. SqlParameter(Sql参数)
  5. SqlDataReader(数据流读取器)
  6. SqlTransaction(事务)
  7. SqlDataAdapter(数据适配器)
  8. DataSet,DataTable,DataRow,DataColumn
  9. 封装数据库操作类(这才是精华)

一丶简单的介绍下ADO.NET

  了解System.Data命名空间下我们常用的一些类:

 1 ①System.Data  → DataTable,DataSet,DataRow,DataColumn,DataRelation,Constraint,DataColumnMapping,DataTableMapping
2 ②System.Data.Coummon → 各种数据访问类的基类和接口
3 ③System.Data.SqlClient → 对Sql Server进行操作的数据访问类
4 主要有: a) SqlConnection → 数据库连接器
5 b) SqlCommand → 数据库命名对象
6 c) SqlCommandBuilder → 生存SQL命令
7 d) SqlDataReader → 数据读取器
8 e) SqlDataAdapter → 数据适配器,填充DataSet
9 f) SqlParameter → 为存储过程定义参数
10 g) SqlTransaction → 数据库事物

二丶SqlConnection(连接对象)

  1.连接字符串

    基本语法:数据源(Data Source)+数据库名称(Initial Catalog)+用户名(User ID)+密码(Password)(这种方式比较安全)!

    推荐文章 :SQL Server 连接字符串和身份验证你必须知道的ADO.NET(三) 连接字符串,你小觑了吗?SQL Server 2008连接字符串写法大全,连接字符串有很多的写法,最保险的写法可以借助“SqlConnectionStringBuilder”类,它提供了全面的连接字符串的属性,以至于减少出错率(相关属性查MSDN),还有大多数连接字符串都写在配置文件里面了!

  2.创建连接对象

  3.打开和关闭连接对象(使用Using来关闭连接)

    关于连接池的文章:你必须知道的ADO.NET(五) 细说数据库连接池(写的还真不赖啊),顶...

 三丶SqlCommand(命令对象)

  1.实例化的时候默认初始化的四个属性

  2.创建命令对象

    使用连接对象的“CreateCommand()”方法创建命令对象,也可以使用new来实例化对象!

1 SqlCommand command = connection.CreateCommand(); //这种方式比较好,也可以自己实例化一个对象!

  3.几个重要属性

    ①CommandText:获取或设置要对数据源执行的 Transact-SQL 语句、表名或存储过程!

    ②CommandType:设置你执行的SQL语句是存储过程还是T-SQL(是一个枚举)!

    

    ③Parameters:设置你T-SQL中你需要用到的参数(后面会讲到),是一个“SqlParametersCollection”类型,这个属性很重要,是你通过代码给SQL语句传递参数的途径,所以记住语法,记住一些使用规则讲对编码有很大的帮助!

  4.几个重要的方法(相信大家熟悉的不能再熟悉了)

    ①ExecuteNonQuery:返回是影响的行数(int),主要执行更新,添加,删除等操作!

    ②ExecuteReader:执行SQL或存储过程,返回的是SqlDataReader类型,主要用来查询!

      ★  这边注意这个方法的重载 CommandBehaviour 枚举,成员如下:

    

1 command.ExecuteReader(CommandBehavior.CloseConnection); //在执行读取之后会自动关闭连接对象

    ③ExecuteScalar:返回执行结果集中的第一行第一列,如果没有数据,则返回NULL!

     Note:因为可能会返回“Null”值,所以需要对结果进行判断,如下:

    ④CreateParameter:创建SqlParameter实例

1 SqlParameter para = cmd.CreateParameter() //此方法适合SQL语句中只有一个参数的情况!

    推荐文章:你必须知道的ADO.NET(六) 谈谈Command对象与数据检索

          你必须知道的ADO.NET(七) Wow!Command对象高级应用

四丶SqlParameter(Sql参数)

  1.几个重要的属性    

  ParameterName:   设置参数名

  Value:              给参数设置值

    Size:                 设置参数字节最大大小(以字节为但为)

    SqlDbType:     参数在SQL中的类型  

  2.命令对象添加参数集合的几种方法

    ①AddWithValue

    ②Add

    ③AddRange

    推荐文章:SqlParameter的作用与用法,代码如下:

 1  using (SqlConnection connection = new SqlConnection(""))
2 {
3 SqlCommand command = connection.CreateCommand();
4 command.CommandText = "";
5
6 //可以使用这种方式添加多个参数,不过方式不够好
7 command.Parameters.Add("@name", SqlDbType.NVarChar).Value = "yang"; //第一种方式
8 command.Parameters.Add("@age", SqlDbType.Int).Value = 888;
9 command.Parameters.Add("@address", SqlDbType.NVarChar, 100).Value = "Jiang Su";
10
11 //这种方式直接给定参数名和参数就可以了,可操作性比较差
12 command.Parameters.AddWithValue("@name", "yang");
13 command.Parameters.AddWithValue("@age", 888).SqlDbType = SqlDbType.Int;
14 command.Parameters.AddWithValue("@address", "Jiang su").SqlDbType = SqlDbType.NVarChar;
15
16 //直接使用参数集合添加你需要的参数,推荐这种写法
17 SqlParameter[] parameters = new SqlParameter[]
18 {
19 new SqlParameter("@name",SqlDbType.NVarChar,100){Value = "yang"},
20 new SqlParameter("@age",SqlDbType.Int,2){Value = 888},
21 new SqlParameter("@address",SqlDbType.NVarChar,20){Value = "Jiang Su"},
22 };
23 command.Parameters.AddRange(parameters); //参数也可以是一个Array数组,如果采用数组参数代码的可读性和扩展性就不是那么好了
24
25 //当我们把参数都添加好之后,会生成一个“SqlParameterCollection”集合类型,相当于参数的集合
26 //那么我们就可以对这些参数进行修改和移除了
27 //说穿了“SqlParameterCollection”内部其实是一个List<SqlParameter>的集合,只是它里面的复杂度比较高,考虑的很全面
28 command.Parameters[0].Value = "hot girl";
29 command.Parameters[0].Size = 200;
30 }

  3.说说“SqlParameterCollection”,参数集合

    上面添加的“SqlParameter”参数都被添加到了“SqlParameterCollection”集合中去了,所以我们才能够对它进行读取和修改!

  4.定义适当的参数属性获取存储过程的返回值(return) → Direction = ParameterDirection.Output

    代码如下:

五丶SqlDataReader(数据流读取器)

  说实话,如果单单知道怎么使用读取器,那是非常好学的,如果深入了解,它里面的知识将会非常的吸引人,那么就以我小菜的经验来说说把,各位不要见怪啊!

  1.基本用法

  2.常用方法

    ①GetOrdinal:获取指定列名的列序号(索引号),使用这个方法可以把经常变动的列进行固定

1 int name = dr.GetOrdinal("name"); //通过列名来获取当前列的索引号,这样如果下次你列名顺序发生变化也没有关系

    ②GetName:  获取列名,参数为指定列名的序列号,返回string

1 string columnName = dr.GetName(name); //通过列名所处的索引号来获取列名名称 

    ③IsDBNull:判断当前读取的数据是否为Null,返回类型为Bool     

1   dr.IsDBNull(coContactID) ? "NULL" : dr.GetInt32(coContactID).ToString() //相信大家都会使用的

    ④NextResult:当查询为批处理查询时,使用这个方法去读取下一个结果集,返回值为Bool,如果存在多个结果集,则为 true;否则为 false

1 //select * from Employee;select * from County,这样的话就可以采用这种方式
2 dr.NextResult(); //记住这个要放在while(dr.Read())之后,因为读取一个数据集之后才能读取下一个数据集 

    ⑤Read:读取数据

      读取数据最重要的方法,不说了!

  3.常用属性

    ①HasRow:判断是否包含一行或多行,也就是判断有没有数据,返回类型为Bool

    ②FieldCount:获取读取的列数,返回类型为Int

    ③IsClosed:判断读取的数据流是否关闭

      所以灵活运用上面的属性讲增强代码的可读性和健壮性,综合示例:

 

    Note:当 SqlDataReader 关闭后,只能调用 IsClosed 和 RecordsAffected 属性,如果调用其它方法或属性将会报错!

  4.性能深入剖析

    读取数据的时候会有很多种写法,如 dr[0].ToString(),dr["Name"].ToString(),dr.GetString(0),dr.GetSqlString(0) 等等的读取方式的写法,如果大家去网上查资料就会很容易发现这几种写法存在着一些差异!

    下面是读取数据性能的总结:

1     SqlDataReader读取方法:
2 1. DataReader 索引 + 基于 [序列号] → dr[0].ToString | Index-based access
3 2. DataReader 索引 + 基于 [列名] → dr["Name"].ToString | 性能最差
4 3. Get 开头的 + 基于 [序列号] → dr.GetString(0) | type-access
5 4. GetSql 开头的 + 基于 [序列号] → dr.GetSqlString(0) | Provider-specific typed accessor
6 5. GetOrdinal() 通过列名获取这个列的序列号 | 这个方法在提高性能上面有作用
7 6. 性能(4) --> (3) --> (1) --> (2)

    Note:所以在对数据进行读取时要有针对的使用一些性能高的方法,也不是说要追求性能,只是这是一种习惯,对于大多数读取数据库的方法使用索引来读取无疑是最快,记住一句话,“当性能没有成为问题的时候,不要过度的去优化它”,高效而又优美的使用这些方法,才是王道!

    推荐文章:SqlDataReader 提前终止的性能问题

    PS:我这里的总结其实是以前在园子看到一个人写的,找了半个小时都没找到,如果有人看到过,发个链接给我,我补上!

  5.SqlDataReader和DataSet的讨论

    推荐文章:谈谈Asp.net网站优化一:SqlDataReader和DataSet的选择

六丶SqlTransaction(事务)

  1.代码中的事务    

    现在代码中基本使用存储过程来控制事务的处理,通过代码进行控制事务也是我们学习ADO.NET的任务之一!

    事务是在连接对象之后创建,并把它跟命令对象进行关联,使用try.....Catch捕获异常,然后调用RollBack方法回滚事务!

    Commit:提交

    RollBack:回滚

  2.事务中的命名存储点      

    一旦你定义了命名存储点,只能回滚命名存储点之后的操作,这是要是情况而使用!

    这种情况是当你调用RollBack方法并重载一个命名存储点的参数,如下代码所示:

 1     using (SqlConnection conn = new SqlConnection(str))
2 {
3 conn.Open();
4 SqlTransaction transaction = conn.BeginTransaction();
5 SqlCommand cmd = conn.CreateCommand();
6 cmd.CommandText = "";
7 cmd.Transaction = transaction;
8 //使用命名存储点
9 transaction.Save("this is point"); //定义命名存储点,使用Save方法先保存存储点,定义回滚数据的开始位置
10
11 //这边是你要回滚的操作代码,TO DO...
12
13 //把从命名存储点到这里的操作进行回滚
14 transaction.Rollback("this is point"); //回滚命名存储点
15 }

  3.SQL语句中的事务(SQL Server中的事务其实很复杂的)

1 BEGIN TRANSACTION
2
3 --你需要执行的更新,删除,插入的语句
4
5 IF(@@ERROR > 0) //这是系统变量,存储你在执行更新,删除,插入操作时发生错误的记录编号
6 ROLLBACK
7 ELSE
8 COMMIT

    推荐文章:浅谈SQL SERVER中事务的ACID

          深入sql server中的事务

  4.说说“TransactionScope”,让事务更加的简单 

 1 using (TransactionScope transactionScope = new TransactionScope())
2 {
3 try
4 {
5 using (SqlConnection connection = new SqlConnection())
6 {
7 // TO DO
8 //提交事务,如果有异常,他会自动回滚的
9 transactionScope.Complete();
10 }
11 }
12 catch (Exception)
13 {
14 //捕获异常
15 throw;
16 }
17 }

    推荐文章:C#综合揭秘——细说事务

七丶SqlDataAdapter(数据适配器)

  1.构造函数 

1 四个重载:
2 1. 无参
3 2. SqlDataAdapter(SqlCommand) → 执行命令对象实例
4 3. SqlDataAdapter(String, SqlConnection) → ①只能指定查询语句 ②连接对象实例
5 4. SqlDataAdapter(String, ConnectionString) → 用 SelectCommand 和一个连接字符串初始化 SqlDataAdapter 类的一个新实例
6 Note:第四个重载就把连接对象和命令对象都包含进去了!

  2.填充数据(Fill)

    最简单的填充数据

1 DataSet dataSet = new DataSet();
2 using (SqlConnection conn = new SqlConnection(""))
3 {
4 conn.Open();
5 SqlCommand command = conn.CreateCommand();
6 command.CommandText = "select name,age,address from MyInformation";
7 SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
8 dataAdapter.Fill(dataSet); //填充数据
9 }

  3.使用“SqlCommandBuilder”对数据进行增删改查

    ①添加数据

 1  using (SqlConnection conn = new SqlConnection(ConnectionString()))
2 {
3 conn.Open();
4 //构建查询语句,也可以指定SqlCommand,其中变换的方法有很多
5 SqlDataAdapter da = new SqlDataAdapter("select LastName,FirstName from dbo.Employees", conn);
6 DataSet ds = new DataSet();
7 da.Fill(ds);
8 //这句话很重要,它会把你在DataSet增加的数据转化为SQL语句用来更新数据库
9 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);
10 //添加行,实例化一个行对象,注意是用NewRow来创建行
11 DataRow row = ds.Tables[0].NewRow();
12 row[0] = "Yang";
13 row[1] = "鬼头";
14 ds.Tables[0].Rows.Add(row); //添加到表中
15 da.Update(ds); //把DataSet中表和数据库进行对比,更新
16 }

    ②修改数据

 1 using (SqlConnection conn = new SqlConnection(""))
2 {
3 SqlDataAdapter da = new SqlDataAdapter("SQL语句或你自己定义的命令对象", conn);
4 DataSet ds = new DataSet();
5 da.Fill(ds);
6 //很重要的一句话
7 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);
8 ds.Tables[0].Rows[12][1] = ""; //修改数据
9 da.Update(ds);
10 //调用Update方法其中隐式的调用了AcceptChanges方法,更新数据集中的数据
11 //如果你继续使用这个数据集而没有调用这个方法,在后面的使用会出现异常
12 ds.AcceptChanges(); //这句话可以不写的
13 }

    ③删除数据

 1  using (SqlConnection conn = new SqlConnection(""))
2 {
3 SqlDataAdapter da = new SqlDataAdapter("SQL语句或你自己定义的命令对象", conn);
4 DataSet ds = new DataSet();
5 da.Fill(ds);
6 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);
7 //删除数据
8 ds.Tables[0].Rows[12].Delete();
9 da.Update(ds); //这边会隐式调用DataTable的AcceptChanges方法
10 }

    Note(很重要的注意点): 值得注意的是Update方法已经隐式帮我调用了AcceptChanges,不比担心状态为改变删除数据会报错,微软已经帮我们都做好了,其实背后就是 做的Table.AcceptChanges()这件事,如果在一般的DataTable中会怎么样,提交自上次调用 AcceptChanges 以来对该行进行的所有更改,在调用这个方法之后,表中所有更改将会提交,所有行状态(RowState)状态都将变为Unchanged,在DataSet中我将会说到这些内容!

  4.关于“SqlDataAdapter”中Fill方法的一些讨论

    简单的写一下,MSDN上都有的,查一下就知道了!

1 ★指定填充数据的数量,如:
2 //从第五行到第十行数据填充DataSet
3 //上面的定义错了
4 //应该是从第六行开始,后面的十条记录
5 da.Fill(ds,5,10,”MyTable”)

八丶DataSet,DataTable,DataRow,DataColumn

  表示数据存放在缓存中,DataSet里面可以包含多个DataTable,DataTable中有多个DataColumn和多个 DataRow,包括对各种对DataTable的操作,以及对列和行的操作,在进行DataSet,DataTable进行操作的时候,应该先判断它们 是否为Null,这是最基本的!

  1.DataTable,DataRow,DataColumn

    ①创建自己的DataTable

    ②使用对象集合初始化器简化代码,以及使用“DataColumnCollection”和“DataRowCollection”来操作已添加的行和列

    构造函数的访问修饰符为Internal,通过这两个集合可以对Column和Row进行“增,删,改,查”,详细见MSDN,如Remove,Add,RemoveAt etc!

 1 dt.Columns.Add(new DataColumn("Age", typeof(Int32)));
2 dt.Columns.Add(new DataColumn()
3 {
4 ColumnName = "Address",
5 DataType = typeof(string),
6 DefaultValue = "江苏海安"
7 });
8 //我们这边使用Add的方法的第二个重载
9 dt.Rows.Add(new object[] {"11", 44, "222", "yang cao gui"});
10 //我们也可以对添加好的行和列进行读取和修改
11 dt.Columns[0].ColumnName = "wang wei";
12 dt.Rows[0]["wang wei"] = "我把这行这列的值修改了,哈哈";

    ③使用表达树快速构建自己的列,详细的也可以查MSDN

  2.DataRowState(行状态),DataRowVersion(行版本)

    ①DataRowState(行状态)是“DataRow”中一个很重要的状态,主要有五个方面:

1     Added          → 添加
2 Deleted → 删除
3 Detached → 分离
4 Modified → 修改
5 Unchanged → 为改变

    

     Note如果实例化一个行,但没有加入到任何一个表中,那么它的状态永远是Detached,不存在Add,Modified之分,这个是要注意的!

    ②DataRowVersion(行版本),有四个版本状态,如下:

1     Current     → 最近的行,主要针对Deleted操作之前的行,行状态的Deleted
2 Default → 行的默认状态
3 Original → 行的原始值 Added,Modified,Unchanged
4 Proposed → 行的建议值

    

    PS:如果想理解它们,应该要写一些示例代码来模拟它们,这样就能很好的熟悉它们了!

    强烈推荐这篇文章:→ 深入.NET DataTable(写的很仔细,不错,一定要看的),还有这篇 → 深入.NET DataTable(补遗)

  3.DataSet,DataTable

    比较重要的方法:Select,Merge,Copy,Clone,GetChanges等等

    关于GetChanges方法:获取数据改变的地方,它所获取的是你上次调用AcceptChanges方法之后修改数据的信息,这点要注意了!

  4.下面是对DataSet和DataTable讲的比较好的文章收集  

    DataTable.Select使用小心得

    DataTable 深入解析数据源绑定原理之高级篇

    比较两个DataTable数据(结构相同)——5万条数据仅需几秒

  5.关于“DataRelation”和“DataView”的知识也很重要 

    DataView → 表示用于排序、筛选、搜索、编辑和导航的 DataTable的可绑定数据的自定义视图,看文章:DataSet,DataTable,DataView

    DataRelation → 表示两个 DataTable 对象之间的父/子关系,看文章:DataRelation(DataSet中父子表)的一个示例

九丶封装数据库操作类(这才是精华)

    只有充分理解了上面的知识,才能更好的封装,才能写出健壮的面向对象数据库操作类库,因本人知识有限,简单的封装还可以,但是不足以见人,所以收集了了一些好文章,供我们来学习:

    1.SqlHelper- -高悬的双刃剑(到底好用么~~) (提炼更加健壮的代码)

    2.我的DbHelper数据操作类(自定义操作类库)

    3.JSM SqlHelper 2.0 源码下载(封装的更细啦,有机会研究研究)

    4.微软原版SQLHelper类(代码太多,有很多我们会用不到,还有重载的也太多了吧!)

  好了就这么多了,想简单也很简单,想复杂登天还难,哈哈,还是看个人的选择把,园子里面这方面的文章也有很多,一搜一大堆,好好研究下就ok了!

结束:写了一个星期,终于搞完了,肯定还有很多地方没有涉及到的,大家多多指点...

ADO.NET - 全面梳理的更多相关文章

  1. ADO.NET梳理

    目录: 简单的介绍下ADO.NET SqlConnection(连接对象) SqlCommand(命令对象) SqlParameter(Sql参数) SqlDataReader(数据流读取器) Sql ...

  2. ado.net Web前端:关于JavaScript知识点的简单梳理

    学习js:1.htmml2.cssjs+html+css == html5 js的组成:1).ecamscript ES是js的标准,js 是es 的实现2)文档对象模型(Document Objec ...

  3. ADO.net操作数据库

    今天整理硬盘,发现2年前开始着手开始学习C#的学习日记.陆续整理,一是自己的知识梳理梳理,二是希望与大家多多交流,能给初学者带来一定帮助,当然是更高兴的啦. 断线对象 另一类是与数据源无关的断线对象, ...

  4. .NET平台技术体系梳理+初学者学习路径推荐+我们的愿景与目标

    文章出自:http://www.cnblogs.com/ice-river/p/3475041.html 一 .NET平台技术体系梳理 .NET平台应用领域众多(桌面开发,web开发,移动开发),不断 ...

  5. ADO.NET知识点

    今天复习到了ADO.NET,就把他们的知识梳理总结出来 ADO.NET 是一组向 .NET 程序员公开数据访问服务的类.提供了对各种关系数据.XML 和应用程序数据的访问. 所有的数据访问类位于Sys ...

  6. ADO.net 数据库连接new SqlConnection、Open、Close、Dispose

    今天踩了一个坑,用了一个static对象,存储了Connection,导致了并发量大时(35/s)出现单个连接的数据库请求堆积,以及并发Open导致的异常,最终使服务下线. 排查中发现有些概念不清的地 ...

  7. ADO.NET对象的详解

    1. Connection 类 和数据库交互,必须连接它.连接帮助指明数据库服务器.数据库名字.用户名.密码,和连接数据库所需要的其它参数.Connection对象会被Command对象使用,这样就能 ...

  8. WebForm获取GET或者POST参数到实体的转换,ADO.NET数据集自动转换实体

    最近在修改维护以前的webform项目(维护别人开发的.....)整个aspx没有用到任何的控件,这个我也比较喜欢不用控件所以在提交信息的时候需要自己手动的去Request.QueryString[] ...

  9. ADO.NET编程之美----数据访问方式(面向连接与面向无连接)

    最近,在学习ADO.NET时,其中提到了数据访问方式:面向连接与面向无连接.于是,百度了一下,发现并没有很好的资料,然而,在学校图书馆中发现一本好书(<ASP.NET MVC5 网站开发之美&g ...

随机推荐

  1. 【maven项目结构】module 生成独立的jar

    生成jar 生成jar的过程会出现以下问题: clean完了之后就会出现以下问题: install [INFO] Scanning for projects... [INFO] [INFO] ---- ...

  2. 【BZOJ 1009】 [HNOI2008]GT考试

    Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0< ...

  3. 【HDU2222】Keywords Search

    Problem DescriptionIn the modern time, Search engine came into the life of everybody like Google, Ba ...

  4. Jplayer(转)

    Jplayer必须要加载 1.样式  jplayer.blue.monday.css 2.jq jquery.1.6.2.min.js 当前最新版本为1.6.2 3.jplayer的js jquery ...

  5. ExtJs gridPanel Column 时间格式化

    var panel = new Ext.container.Viewport({ items: { xtype: 'gridpanel', id: 'gridPanel', store: store, ...

  6. BZOJ 4036 [HAOI2015] Set 解题报告

    首先我们不能一位一位的考虑,为什么呢? 你想想,你如果一位一位地考虑的话,那么最后就只有 $n$ 个数字,然而他给了你 $2^n$ 个数字,怎么看都不对劲呀.(我是因为这样子弄没过样例才明白的) 所以 ...

  7. UOJ Round #8 赴京赶考 解题报告

    算法零 $n,m \le 100, q \le 10$ 的话,直接给网格中的每一个格点都建一个点,然后该怎么最短路就怎么最短路,该怎么并查集+BFS就怎么并查集+BFS. 复杂度 $O(qnm)$,可 ...

  8. jQuery的优点——(一)

    稍微学点js然后就用起jQuery,用久了,就好像自己都成高手了,想得少了,都觉得自己就是js高手了.哗啦啦的惭愧啊=.= 面试GY的时候,因为在简历上写着大大的会用jQuery快速开发原型页面,然后 ...

  9. HZNU1015: 矩阵排序

    http://acm.hznu.edu.cn/JudgeOnline/problem.php?id=1015 题意:把矩阵每一行都排序. (以前觉得很难的题目回头看看原来如此简单 ][]; ; i&l ...

  10. Android支付接入(一):支付宝

    原地址:http://blog.csdn.net/simdanfeg/article/details/9011603 转载之前我想深深地感谢屌丝哥 相信相同过App获取利润的都会需要接入计费SDK,下 ...