C# 写的数据库访问类

本方案可实现仅修改app.config即可连接不同数据库,但是设计数据库时需要注意各种数据库的数据类型是不一样的。

各种不同数据库的Connection、Command、DataAdapter、Transaction和Parameter都继承自IDbConnection、IDbCommand、IDbDataAdapter、IDbTransaction和IDbDataParameter,用一个工厂来实现接口的实例即可实现连接不同数据库。

首先,需要新建一个类库,命名为DbManager,此类库需要5个文件, 

1、创建一个枚举类型:DataProvider.cs

[csharp]  view plain copy
  1. namespace DbManager  
  2.    
  3. {   
  4.   
  5.     public enum DataProvider  
  6.      {  
  7.          Oracle,  
  8.          SqlServer,  
  9.          OleDb,  
  10.          Odbc,  
  11.          MySql  
  12.      }  
  13.  }  

 

2、创建一个工厂类,用来产生以上不同数据库的实例:DBManagerFactory.cs

[csharp]  view plain copy
  1. using System.Data;  
  2.  using System.Data.Odbc;  
  3.  using System.Data.SqlClient;  
  4.  using System.Data.OleDb;  
  5.  using System.Data.OracleClient; //需要添加引用  
  6.  using MySql.Data.MySqlClient;   //请自行安装MySQLConnector/Net后添加引用  
  7.    
  8. namespace DbManager  
  9.  {  
  10.      public sealed class DBManagerFactory  
  11.      {  
  12.          private DBManagerFactory()  
  13.          {  
  14.          }  
  15.    
  16.         public static IDbConnection GetConnection(DataProvider providerType)  
  17.          {  
  18.              IDbConnection iDbConnection;  
  19.              switch (providerType)  
  20.              {  
  21.                  case DataProvider.SqlServer:  
  22.                      iDbConnection = new SqlConnection();  
  23.                      break;  
  24.                  case DataProvider.OleDb:  
  25.                      iDbConnection = new OleDbConnection();  
  26.                      break;  
  27.                  case DataProvider.Odbc:  
  28.                      iDbConnection = new OdbcConnection();  
  29.                      break;  
  30.                  case DataProvider.Oracle:  
  31.                      iDbConnection = new OracleConnection();  
  32.                      break;  
  33.                  case DataProvider.MySql:  
  34.                      iDbConnection = new MySqlConnection();  
  35.                      break;  
  36.                  default:  
  37.                      return null;  
  38.              }  
  39.              return iDbConnection;  
  40.          }  
  41.    
  42.         public static IDbCommand GetCommand(DataProvider providerType)  
  43.          {  
  44.              switch (providerType)  
  45.              {  
  46.                  case DataProvider.SqlServer:  
  47.                      return new SqlCommand();  
  48.                  case DataProvider.OleDb:  
  49.                      return new OleDbCommand();  
  50.                  case DataProvider.Odbc:  
  51.                      return new OdbcCommand();  
  52.                  case DataProvider.Oracle:  
  53.                      return new OracleCommand();  
  54.                  case DataProvider.MySql:  
  55.                      return new MySqlCommand();  
  56.                  default:  
  57.                      return null;  
  58.              }  
  59.          }  
  60.    
  61.         public static IDbDataAdapter GetDataAdapter(DataProvider providerType)  
  62.          {  
  63.              switch (providerType)  
  64.              {  
  65.                  case DataProvider.SqlServer:  
  66.                      return new SqlDataAdapter();  
  67.                  case DataProvider.OleDb:  
  68.                      return new OleDbDataAdapter();  
  69.                  case DataProvider.Odbc:  
  70.                      return new OdbcDataAdapter();  
  71.                  case DataProvider.Oracle:  
  72.                      return new OracleDataAdapter();  
  73.                  case DataProvider.MySql:  
  74.                      return new MySqlDataAdapter();  
  75.                  default:  
  76.                      return null;  
  77.              }  
  78.          }  
  79.    
  80.         public static IDbTransaction GetTransaction(DataProvider providerType)  
  81.          {  
  82.              IDbConnection iDbConnection = GetConnection(providerType);  
  83.              IDbTransaction iDbTransaction = iDbConnection.BeginTransaction();  
  84.              return iDbTransaction;  
  85.          }  
  86.    
  87.         public static IDbDataParameter[] GetParameters(DataProvider providerType, int paramsCount)  
  88.          {  
  89.              IDbDataParameter[] idbParams = new IDbDataParameter[paramsCount];  
  90.              switch (providerType)  
  91.              {  
  92.                  case DataProvider.SqlServer:  
  93.                      for (int i = 0; i < paramsCount; i++)  
  94.                      {  
  95.                          idbParams[i] = new SqlParameter();  
  96.                      }  
  97.                      break;  
  98.                  case DataProvider.OleDb:  
  99.                      for (int i = 0; i < paramsCount; i++)  
  100.                      {  
  101.                          idbParams[i] = new OleDbParameter();  
  102.                      }  
  103.                      break;  
  104.                  case DataProvider.Odbc:  
  105.                      for (int i = 0; i < paramsCount; i++)  
  106.                      {  
  107.                          idbParams[i] = new OdbcParameter();  
  108.                      }  
  109.                      break;  
  110.                  case DataProvider.Oracle:  
  111.                      for (int i = 0; i < paramsCount; i++)  
  112.                      {  
  113.                          idbParams[i] = new OracleParameter();  
  114.                      }  
  115.                      break;  
  116.                  case DataProvider.MySql:  
  117.                      for (int i = 0; i < paramsCount; i++)  
  118.                      {  
  119.                          idbParams[i] = new MySqlParameter();  
  120.                      }  
  121.                      break;  
  122.                  default:  
  123.                      idbParams = null;  
  124.                      break;  
  125.              }  
  126.              return idbParams;  
  127.          }  
  128.      }  
  129.  }  

 

3、创建一个接口:IDBManager.cs

[csharp]  view plain copy
  1. using System.Data;  
  2.    
  3. namespace DbManager  
  4.  {  
  5.      public interface IDBManager  
  6.      {  
  7.          DataProvider ProviderType  
  8.          {  
  9.              get;  
  10.              set;  
  11.          }  
  12.    
  13.         IDbConnection Connection  
  14.          {  
  15.              get;  
  16.              set;  
  17.          }  
  18.    
  19.         IDataReader DataReader  
  20.          {  
  21.              get;  
  22.              set;  
  23.          }  
  24.    
  25.         IDbCommand Command  
  26.          {  
  27.              get;  
  28.              set;  
  29.          }  
  30.    
  31.         IDbTransaction Transaction  
  32.          {  
  33.              get;  
  34.              set;  
  35.          }  
  36.    
  37.         IDbDataParameter[] Parameters  
  38.          {  
  39.              get;  
  40.              set;  
  41.          }  
  42.    
  43.         string ConnectionString  
  44.          {  
  45.              get;  
  46.              set;  
  47.          }  
  48.    
  49.         void Open();  
  50.          void Close();  
  51.          void Dispose();  
  52.          void CreateParameters(int paramsCount);  
  53.          void AddParameters(int index, string paramName, object objValue);  
  54.          void BeginTransaction();  
  55.          void CommitTransaction();  
  56.          void CloseReader();  
  57.          IDataReader ExecuteReader(CommandType commandType, string commandText);  
  58.          int ExecuteNonQuery(CommandType commandType, string commandText);  
  59.          object ExecuteScalar(CommandType commandType, string commandText);  
  60.          DataSet ExecuteDataSet(CommandType commandType, string commandText);  
  61.      }  
  62.  }  

 

4、创建一个类来实现IDBManager接口:DBManager.cs

[csharp]  view plain copy
  1. using System;  
  2.  using System.Data;  
  3.    
  4. namespace DbManager  
  5.  {  
  6.      public sealed class DBManager : IDBManager, IDisposable  
  7.      {  
  8.          #region 字段  
  9.    
  10.         private DataProvider _providerType;  
  11.          private IDbConnection _idbConnection;  
  12.          private IDataReader _iDataReader;  
  13.          private IDbCommand _idbCommand;  
  14.          private IDbTransaction _idbTransaction;  
  15.          private IDbDataParameter[] _idbParameters;  
  16.          private string _connectionString;  
  17.   
  18.         #endregion  
  19.   
  20.         #region 构造方法  
  21.    
  22.         public DBManager()  
  23.          {  
  24.          }  
  25.    
  26.         public DBManager(DataProvider providerType)  
  27.          {  
  28.              ProviderType = providerType;  
  29.          }  
  30.    
  31.         public DBManager(DataProvider providerType, string connectionString)  
  32.          {  
  33.              ProviderType = providerType;  
  34.              ConnectionString = connectionString;  
  35.          }  
  36.   
  37.         #endregion  
  38.   
  39.         #region 属性  
  40.    
  41.         public DataProvider ProviderType  
  42.          {  
  43.              get { return _providerType; }  
  44.              set { _providerType = value; }  
  45.          }  
  46.    
  47.         public IDbConnection Connection  
  48.          {  
  49.              get { return _idbConnection; }  
  50.              set { _idbConnection = value; }  
  51.          }  
  52.    
  53.         public IDataReader DataReader  
  54.          {  
  55.              get { return _iDataReader; }  
  56.              set { _iDataReader = value; }  
  57.          }  
  58.    
  59.         public IDbCommand Command  
  60.          {  
  61.              get { return _idbCommand; }  
  62.              set { _idbCommand = value; }  
  63.          }  
  64.    
  65.         public IDbTransaction Transaction  
  66.          {  
  67.              get { return _idbTransaction; }  
  68.              set { _idbTransaction = value; }  
  69.          }  
  70.    
  71.         public IDbDataParameter[] Parameters  
  72.          {  
  73.              get { return _idbParameters; }  
  74.              set { _idbParameters = value; }  
  75.          }  
  76.    
  77.         public string ConnectionString  
  78.          {  
  79.              get { return _connectionString; }  
  80.              set { _connectionString = value; }  
  81.          }  
  82.   
  83.         #endregion  
  84.   
  85.         #region 公有方法  
  86.    
  87.         public void Open()  
  88.          {  
  89.              Connection = DBManagerFactory.GetConnection(ProviderType);  
  90.              Connection.ConnectionString = ConnectionString;  
  91.              if (Connection.State != ConnectionState.Open)  
  92.              {  
  93.                  Connection.Open();  
  94.              }  
  95.              Command = DBManagerFactory.GetCommand(ProviderType);  
  96.          }  
  97.    
  98.         public void Close()  
  99.          {  
  100.              if (Connection.State != ConnectionState.Closed)  
  101.              {  
  102.                  Connection.Close();  
  103.              }  
  104.          }  
  105.    
  106.         public void Dispose()  
  107.          {  
  108.              GC.SuppressFinalize(this);  
  109.              Close();  
  110.              Command = null;  
  111.              Transaction = null;  
  112.              Connection = null;  
  113.          }  
  114.    
  115.         public void CreateParameters(int paramsCount)  
  116.          {  
  117.              Parameters = new IDbDataParameter[paramsCount];  
  118.              Parameters = DBManagerFactory.GetParameters(ProviderType, paramsCount);  
  119.          }  
  120.    
  121.         public void AddParameters(int index, string paramName, object objValue)  
  122.          {  
  123.              if (index < Parameters.Length)  
  124.              {  
  125.                  Parameters[index].ParameterName = paramName;  
  126.                  Parameters[index].Value = objValue;  
  127.              }  
  128.          }  
  129.    
  130.         public void BeginTransaction()  
  131.          {  
  132.              if (Transaction == null)  
  133.              {  
  134.                  Transaction = DBManagerFactory.GetTransaction(ProviderType);  
  135.              }  
  136.              Command.Transaction = Transaction;  
  137.          }  
  138.    
  139.         public void CommitTransaction()  
  140.          {  
  141.              if (Transaction != null)  
  142.              {  
  143.                  Transaction.Commit();  
  144.              }  
  145.              Transaction = null;  
  146.          }  
  147.    
  148.         public void CloseReader()  
  149.          {  
  150.              if (DataReader != null)  
  151.              {  
  152.                  DataReader.Close();  
  153.              }  
  154.          }  
  155.    
  156.         public IDataReader ExecuteReader(CommandType commandType, string commandText)  
  157.          {  
  158.              Command = DBManagerFactory.GetCommand(ProviderType);  
  159.              Command.Connection = Connection;  
  160.              PrepareCommand(Command, Connection, Transaction, commandType, commandText, Parameters);  
  161.              DataReader = Command.ExecuteReader();  
  162.              Command.Parameters.Clear();  
  163.              return DataReader;  
  164.          }  
  165.    
  166.         public int ExecuteNonQuery(CommandType commandType, string commandText)  
  167.          {  
  168.              Command = DBManagerFactory.GetCommand(ProviderType);  
  169.              PrepareCommand(Command, Connection, Transaction, commandType, commandText, Parameters);  
  170.              int returnValue = Command.ExecuteNonQuery();  
  171.              Command.Parameters.Clear();  
  172.              return returnValue;  
  173.          }  
  174.    
  175.         public object ExecuteScalar(CommandType commandType, string commandText)  
  176.          {  
  177.              Command = DBManagerFactory.GetCommand(ProviderType);  
  178.              PrepareCommand(Command, Connection, Transaction, commandType, commandText, Parameters);  
  179.              object returnValue = Command.ExecuteScalar();  
  180.              Command.Parameters.Clear();  
  181.              return returnValue;  
  182.          }  
  183.    
  184.         public DataSet ExecuteDataSet(CommandType commandType, string commandText)  
  185.          {  
  186.              Command = DBManagerFactory.GetCommand(ProviderType);  
  187.              PrepareCommand(Command, Connection, Transaction, commandType, commandText, Parameters);  
  188.              IDbDataAdapter dataAdapter = DBManagerFactory.GetDataAdapter(ProviderType);  
  189.              dataAdapter.SelectCommand = Command;  
  190.              DataSet dataSet = new DataSet();  
  191.              dataAdapter.Fill(dataSet);  
  192.              Command.Parameters.Clear();  
  193.              return dataSet;  
  194.          }  
  195.   
  196.         #endregion  
  197.   
  198.         #region 私有方法  
  199.    
  200.         private void AttachParameters(IDbCommand command, IDbDataParameter[] commandParameters)  
  201.          {  
  202.              foreach (IDbDataParameter idbParameter in commandParameters)  
  203.              {  
  204.                  if (idbParameter.Direction == ParameterDirection.InputOutput && idbParameter.Value == null)  
  205.                  {  
  206.                      idbParameter.Value = DBNull.Value;  
  207.                  }  
  208.                  command.Parameters.Add(idbParameter);  
  209.              }  
  210.          }  
  211.    
  212.         private void PrepareCommand(IDbCommand command, IDbConnection connection, IDbTransaction transaction,  
  213.                                      CommandType commandType, string commandText, IDbDataParameter[] commandParameters)  
  214.          {  
  215.              command.Connection = connection;  
  216.              command.CommandText = commandText;  
  217.              command.CommandType = commandType;  
  218.              if (transaction != null)  
  219.              {  
  220.                  command.Transaction = transaction;  
  221.              }  
  222.              if (commandParameters != null)  
  223.              {  
  224.                  AttachParameters(command, commandParameters);  
  225.              }  
  226.          }  
  227.   
  228.         #endregion  
  229.      }  
  230.  }  

 

5、再加一个DBHelper.cs,来调用DBManager类,外部来直接调用DBHelper类即可。

[csharp]  view plain copy
  1. using System;  
  2.  using System.Data;  
  3.  using System.Configuration;  
  4.    
  5. namespace DbManager  
  6.  {  
  7.      public class DBHelper  
  8.      {  
  9.          private static readonly IDBManager dbManager = new DBManager(GetDataProvider(), GetConnectionString());  
  10.    
  11.         /// <summary>  
  12.          /// 从配置文件中选择数据库类型  
  13.          /// </summary>  
  14.          /// <returns>DataProvider枚举值</returns>  
  15.          private static DataProvider GetDataProvider()  
  16.          {  
  17.              string providerType = ConfigurationManager.AppSettings["DataProvider"];  
  18.              DataProvider dataProvider;  
  19.              switch (providerType)  
  20.              {  
  21.                  case "Oracle":  
  22.                      dataProvider = DataProvider.Oracle;  
  23.                      break;  
  24.                  case "SqlServer":  
  25.                      dataProvider = DataProvider.SqlServer;  
  26.                      break;  
  27.                  case "OleDb":  
  28.                      dataProvider = DataProvider.OleDb;  
  29.                      break;  
  30.                  case "Odbc":  
  31.                      dataProvider = DataProvider.Odbc;  
  32.                      break;  
  33.                  case "MySql":  
  34.                      dataProvider = DataProvider.MySql;  
  35.                      break;  
  36.                  default:  
  37.                      return DataProvider.Odbc;  
  38.              }  
  39.              return dataProvider;  
  40.          }  
  41.    
  42.         /// <summary>  
  43.          /// 从配置文件获取连接字符串  
  44.          /// </summary>  
  45.          /// <returns>连接字符串</returns>  
  46.          private static string GetConnectionString()  
  47.          {  
  48.              return ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;  
  49.          }  
  50.    
  51.         /// <summary>  
  52.          /// 关闭数据库连接的方法  
  53.          /// </summary>  
  54.          public static void Close()  
  55.          {  
  56.              dbManager.Dispose();  
  57.          }  
  58.    
  59.         /// <summary>  
  60.          /// 创建参数  
  61.          /// </summary>  
  62.          /// <param name="paramsCount">参数个数</param>  
  63.          public static void CreateParameters(int paramsCount)  
  64.          {  
  65.              dbManager.CreateParameters(paramsCount);  
  66.          }  
  67.    
  68.         /// <summary>  
  69.          /// 添加参数  
  70.          /// </summary>  
  71.          /// <param name="index">参数索引</param>  
  72.          /// <param name="paramName">参数名</param>  
  73.          /// <param name="objValue">参数值</param>  
  74.          public static void AddParameters(int index, string paramName, object objValue)  
  75.          {  
  76.              dbManager.AddParameters(index, paramName, objValue);  
  77.          }  
  78.    
  79.         /// <summary>  
  80.          /// 执行增删改  
  81.          /// </summary>  
  82.          /// <param name="sqlString">安全的sql语句string.Format()</param>  
  83.          /// <returns>操作成功返回true</returns>  
  84.          public static bool ExecuteNonQuery(string sqlString)  
  85.          {  
  86.              try  
  87.              {  
  88.                  dbManager.Open();  
  89.                  return dbManager.ExecuteNonQuery(CommandType.Text, sqlString) > 0 ? true : false;  
  90.              }  
  91.              catch (Exception e)  
  92.              {  
  93.                  throw new Exception(e.Message);  
  94.              }  
  95.              finally  
  96.              {  
  97.                  dbManager.Dispose();  
  98.              }  
  99.          }  
  100.    
  101.         /// <summary>  
  102.          /// 执行查询  
  103.          /// </summary>  
  104.          /// <param name="sqlString">安全的sql语句string.Format()</param>  
  105.          /// <returns>返回IDataReader</returns>  
  106.          public static IDataReader ExecuteReader(string sqlString)  
  107.          {  
  108.              try  
  109.              {  
  110.                  dbManager.Open();  
  111.                  return dbManager.ExecuteReader(CommandType.Text, sqlString);  
  112.              }  
  113.              catch (Exception e)  
  114.              {  
  115.                  throw new Exception(e.Message);  
  116.              }  
  117.          }  
  118.      }  
  119.  }  
  120.    


 

现在,将上述项目生成一个DbManager.dll类库,在具体的DAL层里面就可以直接调用了。

DBHelper类没有全部写完,只写了ExecuteNonQuery()和ExecuteReader()两个方法,对于有参和无参的增删改查操作暂时够用,返回DataSet的方法未写,Transaction相关的也未写。

6、app.config

[csharp]  view plain copy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2.  <configuration>  
  3.      <connectionStrings>  
  4.          <add name="ConnString" connectionString="server=localhost;database=yourDbName;Persist Security Info=False;uid=root;pwd=mysqladmin"/>  
  5.          <!-- 通过改变ConnectionString的值来更换数据库连接字符串  
  6.          <add name="ConnString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=DBDemo.mdb;Jet OLEDB:Database Password=1234"/>  
  7.          <add name="ConnString" connectionString="server=localhost;database=yourDbName;Persist Security Info=False;Integrated Security=SSPI"/>  
  8.          <add name="ConnString" connectionString="server=localhost;database=yourDbName;Persist Security Info=False;uid=sa;pwd=1234"/>  
  9.          <add name="ConnString" connectionString="server=localhost;database=yourDbName;Persist Security Info=False;uid=root;pwd=mysqladmin"/>  
  10.          -->  
  11.      </connectionStrings>  
  12.      <appSettings>  
  13.          <add key="DataProvider" value="MySql"/>  
  14.          <!-- 通过改变value值来更换数据库  
  15.          <add key="DataProvider" value="Oracle"/>  
  16.          <add key="DataProvider" value="SqlServer"/>  
  17.          <add key="DataProvider" value="OleDb"/>  
  18.          <add key="DataProvider" value="Odbc"/>   
  19.          <add key="DataProvider" value="MySql"/>  
  20.          -->  
  21.      </appSettings>  
  22.  </configuration>  


 

7、程序中的调用

举个简单的例子,我们就创建一个控制台应用程序,然后添加DbManager.dll的引用

Program.cs文件的样子:

[csharp]  view plain copy
  1. using System;  
  2.  using System.Data;  
  3.  using DbManager;  //记得引入命名空间  
  4.    
  5. namespace DBDemo  
  6.  {  
  7.      class Program  
  8.      {  
  9.          static void Main(string[] args)  
  10.          {  
  11.              SelectWithoutParams();  
  12.              Console.WriteLine("------安全sql语句string.Format()的查询结果------");  
  13.              SelectWithSafeSql(4);  
  14.              Console.WriteLine("------参数化语句的查询结果-------");  
  15.              SelectWithParams("总统套间");  
  16.    
  17.         }  
  18.    
  19.    
  20.    
  21.         private static void SelectWithoutParams()  
  22.    
  23.         {  
  24.              const string sql = "select * from RoomType";  
  25.              IDataReader reader = DBHelper.ExecuteReader(sql);  
  26.              while (reader.Read())  
  27.              {  
  28.                  Console.WriteLine(reader["TypeName"].ToString());  
  29.              }  
  30.              DBHelper.Close();  //记得关闭reader  
  31.          }  
  32.    
  33.         private static void SelectWithSafeSql(int TypeId)  
  34.          {  
  35.              string sql = string.Format("select * from RoomType where TypeId={0}", TypeId);  
  36.              IDataReader reader = DBHelper.ExecuteReader(sql);  
  37.              while (reader.Read())  
  38.              {  
  39.                  Console.WriteLine(reader["TypeName"].ToString());  
  40.              }  
  41.              DBHelper.Close();  
  42.          }  
  43.    
  44.         private static void SelectWithParams(string typeName)  
  45.          {  
  46.    
  47.             string sql = "select * from RoomType where TypeName=@TypeName";  
  48.    
  49.    
  50.    
  51.             //先创建参数,然后才能添加参数   
  52.   
  53.             DBHelper.CreateParameters(1);  //参数个数,1个  
  54.              DBHelper.AddParameters(0, "@TypeName", typeName);  
  55.              IDataReader reader = DBHelper.ExecuteReader(sql);  
  56.              while (reader.Read())  
  57.              {  
  58.                  Console.WriteLine(reader["TypeName"].ToString());  
  59.              }  
  60.              DBHelper.Close();  
  61.          }  
  62.      }  
  63.  }  
  64.    


 

OK!全部完成!在具体的DAL层中,调用DBHelper的相关方法即可,如果是查询方法,记得最后要写关闭代码。只要表结构一样,可以在app.config中随意切换数据库。

最后注意的是:

各个数据库的插入语句不一样,假设我们有4个字段,第一个字段fieldName1为自增字段。

对于SQLServer,不需要写自增字段,

语句是:INSERT INTO table VALUES(value2, value3, value4);

对于MySQL,自增字段位置需要写null代替,

语句是:INSERT INTO table VALUES(NULL, value2, value3, value4);

而对于ACCESS数据库,则必须写完整,

语句是:INSERT INTO table(fieldName2, fieldName3,fieldName4) VALUES(value2, value3, value4);

为了实现兼容,大家还是都按完整的来写,就不会有错了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值