原文地址:自己整理的一个访问SQLite3数据库的C++类作者:vigra
近日,对SQLite3的使用进行了研究。真不愧是优秀的嵌入数据库,API接口也极其简捷。基本上只要使用以下几个接口就能完成数据库的操作:
 
sqlite3_open()
sqlite3_prepare()
sqlite3_step()
sqlite3_column()
sqlite3_finalize()
sqlite3_close()
但是,API方式不太符合数据库开发的习惯。我们是C++程序员,封装一下吧。
 
多网上找到了一份Rob Groves在2004写的“C++ wrapper around the SQLite3 embedded database library.”基本可用,但太复杂了,不利于学习。
 
所以,我对其进行了简化,只保留了3个类:
 
TSQLite3Exception 用于异常处理
 
TSQLite3Query 用于处理带返回数据的SQL语句
 
TSQLite3DB 用于对数据库本身的操作
 
经过这样的简化,在保证基本数据库操作的前提下,代码行数变成的原来的1/3,简捷、易用,推荐给大家。
 
还附上一些应用示例代码,方便大家上手。我测试用的SQLite3版本是3.7.3
 
//---------------------------------------------------------------------------
int __fastcall TDataModule1::UpdateFounds(String sCode, String sName, String sDate, String sValue)
{
char SqlStr[500];
TSQLite3DB *db;
// open the database file
db = new TSQLite3DB();
 
try
{
try
{
db->open("data.s3db");
//更新记录
sprintf(SqlStr, "UPDATE FOUNDS SET FOUND_NAME='%s', DATE='%s', VALUE='%s' WHERE CODE='%s'",
AnsiString(sName).c_str(), AnsiString(sDate).c_str(), AnsiString(sValue).c_str(), AnsiString(sCode).c_str());
db->execDML(SqlStr);
}
catch(const TSQLite3Exception &e)
{
ShowMessage(String("更新记录失败!") + e.errorMessage());
}
catch(...)
{
return -1;
}
 
return 0;
}
 
__finally
{
delete db;
}
}
//---------------------------------------------------------------------------
int __fastcall TDataModule1::FillListViewFirst(TListView *ListView)
{
TListItem *pItem = NULL;
TSQLite3DB *db;
// open the database file
db = new TSQLite3DB();
 
try
{
try
{
db->open("data.s3db");
TSQLite3Query Results = db->execQuery("SELECT * FROM FOUNDS ORDER BY CODE");
ListView->Items->Clear();
 
for( ; !Results.eof(); Results.nextRow())
{
//如果不需要显示,则跳过
if(strncmp("是", Results.getStringField(4, ""), 2) == 0)
{
pItem = ListView->Items->Add();
//第1列
pItem->Caption = String(Results.getStringField(0, ""));
//第2列
pItem->SubItems->Add(Results.getStringField(1, ""));
//第3列
pItem->SubItems->Add(Results.getStringField(2, ""));
//第4列
pItem->SubItems->Add(Results.getStringField(3, ""));
}
}
}
catch(const TSQLite3Exception &e)
{
ShowMessage(String("查询记录失败!") + e.errorMessage());
}
catch(...)
{
return -1;
}
 
return 0;
}
 
__finally
{
delete db;
}
}
 
 
 
 
//---------------------------------------------------------------------------
 
#include <string.h>
#include <time.h>
#pragma hdrstop
 
#include "SQLite3_unit.h"
#pragma package(smart_init)
 
// Named constant for passing to TSQLite3Exception when passing it a string
// that cannot be deleted.
static const bool DONT_DELETE_MSG = false;
// Timeout values on busy or lock conditions
static const int SQLTM_TIMEOUT = 6000; // 6 seconds
 
////////////////////////////////////////////////////////////////////////////////
 
TSQLite3Exception::TSQLite3Exception(const int nErrCode,
char *szErrMess,
bool bDeleteMsg) :
mnErrCode(nErrCode)
{
mpszErrMess = sqlite3_mprintf("%s[%d]: %s",
errorCodeAsString(nErrCode),
nErrCode,
szErrMess ? szErrMess : "");
 
if(bDeleteMsg && szErrMess)
{
sqlite3_free(szErrMess);
}
}
//---------------------------------------------------------------------------
 
 
TSQLite3Exception::TSQLite3Exception(const TSQLite3Exception &e) :
mnErrCode(e.mnErrCode)
{
mpszErrMess = 0;
 
if(e.mpszErrMess)
{
mpszErrMess = sqlite3_mprintf("%s", e.mpszErrMess);
}
}
//---------------------------------------------------------------------------
 
 
const char *TSQLite3Exception::errorCodeAsString(int nErrCode)
{
switch(nErrCode)
{
case SQLITE_OK :
return "Successful result";
case SQLITE_ERROR :
return "SQL error or missing database";
case SQLITE_INTERNAL :
return "Internal logic error in SQLite ";
case SQLITE_PERM :
return "Access permission denied";
case SQLITE_ABORT :
return "Callback routine requested an abort";
case SQLITE_BUSY :
return "The database file is locked";
case SQLITE_LOCKED :
return "A table in the database is locked";
case SQLITE_NOMEM :
return "A malloc() failed";
case SQLITE_READONLY :
return "Attempt to write a readonly database";
case SQLITE_INTERRUPT :
return "Operation terminated by sqlite3_interrupt()";
case SQLITE_IOERR :
return "Some kind of disk I/O error occurred ";
case SQLITE_CORRUPT :
return "The database disk image is malformed";
case SQLITE_NOTFOUND :
return "NOT USED. Table or record not found";
case SQLITE_FULL :
return "Insertion failed because database is full";
case SQLITE_CANTOPEN :
return "Unable to open the database file";
case SQLITE_PROTOCOL :
return "Database lock protocol error";
case SQLITE_EMPTY :
return "Database is empty";
case SQLITE_SCHEMA :
return "The database schema changed";
case SQLITE_TOOBIG :
return "String or BLOB exceeds size limit";
case SQLITE_CONSTRAINT :
return "Abort due to constraint violation";
case SQLITE_MISMATCH :
return "Data type mismatch";
case SQLITE_MISUSE :
return "Library used incorrectly";
case SQLITE_NOLFS :
return "Uses OS features not supported on host";
case SQLITE_AUTH :
return "Authorization denied";
case SQLITE_FORMAT :
return "Auxiliary database format error";
case SQLITE_RANGE :
return "2nd parameter to sqlite3_bind out of range";
case SQLITE_NOTADB :
return "File opened that is not a database file";
case SQLITE_ROW :
return "sqlite3_step() has another row ready";
case SQLITE_DONE :
return "sqlite3_step() has finished executing";
case TSQLITE_ERROR :
return "TSQLITE_ERROR";
default:
return "UNKNOWN_ERROR";
}
}
//---------------------------------------------------------------------------
TSQLite3Exception::~TSQLite3Exception()
{
if(mpszErrMess)
{
sqlite3_free(mpszErrMess);
mpszErrMess = 0;
}
}
////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
TSQLite3Query::TSQLite3Query()
{
mpDB = 0;
mpVM = 0;
mbEof = true;
mnCols = 0;
mbOwnVM = false;
}
//---------------------------------------------------------------------------
TSQLite3Query::TSQLite3Query(const TSQLite3Query &rQuery)
{
mpDB = rQuery.mpDB;
mpVM = rQuery.mpVM;
// Only one object can own the VM
const_cast<TSQLite3Query &>(rQuery).mpVM = 0;
mbEof = rQuery.mbEof;
mnCols = rQuery.mnCols;
mbOwnVM = rQuery.mbOwnVM;
}
//---------------------------------------------------------------------------
TSQLite3Query::TSQLite3Query(sqlite3 *pDB,
sqlite3_stmt *pVM,
bool bEof,
bool bOwnVM)
{
mpDB = pDB;
mpVM = pVM;
mbEof = bEof;
mnCols = sqlite3_column_count(mpVM);
mbOwnVM = bOwnVM;
}
//---------------------------------------------------------------------------
TSQLite3Query::~TSQLite3Query()
{
try
{
finalize();
}
catch(...)
{
}
}
//---------------------------------------------------------------------------
TSQLite3Query &TSQLite3Query::operator=(const TSQLite3Query &rQuery)
{
try
{
finalize();
}
catch(...)
{
}
 
mpDB = rQuery.mpDB;
mpVM = rQuery.mpVM;
// Only one object can own the VM
const_cast<TSQLite3Query &>(rQuery).mpVM = 0;
mbEof = rQuery.mbEof;
mnCols = rQuery.mnCols;
mbOwnVM = rQuery.mbOwnVM;
return *this;
}
//---------------------------------------------------------------------------
int TSQLite3Query::numFields()
{
checkVM();
return mnCols;
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::fieldValue(int nField)
{
checkVM();
 
if(nField < 0 || nField > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
return (const char *)sqlite3_column_text(mpVM, nField);
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::fieldValue(const char *szField)
{
int nField = fieldIndex(szField);
return (const char *)sqlite3_column_text(mpVM, nField);
}
//---------------------------------------------------------------------------
int TSQLite3Query::getIntField(int nField, int nNullValue)
{
if(fieldDataType(nField) == SQLITE_NULL)
{
return nNullValue;
}
else
{
return sqlite3_column_int(mpVM, nField);
}
}
//---------------------------------------------------------------------------
int TSQLite3Query::getIntField(const char *szField, int nNullValue)
{
int nField = fieldIndex(szField);
return getIntField(nField, nNullValue);
}
//---------------------------------------------------------------------------
double TSQLite3Query::getFloatField(int nField, double fNullValue)
{
if(fieldDataType(nField) == SQLITE_NULL)
{
return fNullValue;
}
else
{
return sqlite3_column_double(mpVM, nField);
}
}
//---------------------------------------------------------------------------
double TSQLite3Query::getFloatField(const char *szField, double fNullValue)
{
int nField = fieldIndex(szField);
return getFloatField(nField, fNullValue);
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::getStringField(int nField, const char *szNullValue)
{
if(fieldDataType(nField) == SQLITE_NULL)
{
return szNullValue;
}
else
{
return (const char *)sqlite3_column_text(mpVM, nField);
}
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::getStringField(const char *szField, const char *szNullValue)
{
int nField = fieldIndex(szField);
return getStringField(nField, szNullValue);
}
//---------------------------------------------------------------------------
const unsigned char *TSQLite3Query::getBlobField(int nField, int &nLen)
{
checkVM();
 
if(nField < 0 || nField > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
nLen = sqlite3_column_bytes(mpVM, nField);
return (const unsigned char *)sqlite3_column_blob(mpVM, nField);
}
//---------------------------------------------------------------------------
const unsigned char *TSQLite3Query::getBlobField(const char *szField, int &nLen)
{
int nField = fieldIndex(szField);
return getBlobField(nField, nLen);
}
//---------------------------------------------------------------------------
bool TSQLite3Query::fieldIsNull(int nField)
{
return (fieldDataType(nField) == SQLITE_NULL);
}
//---------------------------------------------------------------------------
bool TSQLite3Query::fieldIsNull(const char *szField)
{
int nField = fieldIndex(szField);
return (fieldDataType(nField) == SQLITE_NULL);
}
//---------------------------------------------------------------------------
int TSQLite3Query::fieldIndex(const char *szField)
{
checkVM();
 
if(szField)
{
for(int nField = 0; nField < mnCols; nField++)
{
const char *szTemp = sqlite3_column_name(mpVM, nField);
 
if(strcmp(szField, szTemp) == 0)
{
return nField;
}
}
}
 
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field name requested",
DONT_DELETE_MSG);
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::fieldName(int nCol)
{
checkVM();
 
if(nCol < 0 || nCol > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
return sqlite3_column_name(mpVM, nCol);
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::fieldDeclType(int nCol)
{
checkVM();
 
if(nCol < 0 || nCol > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
return sqlite3_column_decltype(mpVM, nCol);
}
//---------------------------------------------------------------------------
int TSQLite3Query::fieldDataType(int nCol)
{
checkVM();
 
if(nCol < 0 || nCol > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
return sqlite3_column_type(mpVM, nCol);
}
//---------------------------------------------------------------------------
bool TSQLite3Query::eof()
{
checkVM();
return mbEof;
}
//---------------------------------------------------------------------------
void TSQLite3Query::nextRow()
{
checkVM();
int nRet = sqlite3_step(mpVM);
 
if(nRet == SQLITE_DONE)
{
// no rows
mbEof = true;
}
else if(nRet == SQLITE_ROW)
{
// more rows, nothing to do
}
else
{
nRet = sqlite3_reset(mpVM);
mpVM = 0;
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet,
(char *)szError,
DONT_DELETE_MSG);
}
}
//---------------------------------------------------------------------------
void TSQLite3Query::finalize()
{
if(mpVM && mbOwnVM)
{
int nRet = sqlite3_finalize(mpVM);
mpVM = 0;
 
if(nRet != SQLITE_OK)
{
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet, (char *)szError, DONT_DELETE_MSG);
}
}
else if(mpVM && !mbOwnVM)
{
sqlite3_reset(mpVM);
}
}
//---------------------------------------------------------------------------
void TSQLite3Query::checkVM()
{
if(mpVM == 0)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Null Virtual Machine pointer",
DONT_DELETE_MSG);
}
}
////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
TSQLite3DB::TSQLite3DB()
{
mpDB = 0;
mnBusyTimeoutMs = SQLTM_TIMEOUT;
}
//---------------------------------------------------------------------------
TSQLite3DB::TSQLite3DB(const TSQLite3DB &db)
{
mpDB = db.mpDB;
mnBusyTimeoutMs = SQLTM_TIMEOUT;
}
//---------------------------------------------------------------------------
TSQLite3DB::~TSQLite3DB()
{
close();
}
//---------------------------------------------------------------------------
TSQLite3DB &TSQLite3DB::operator=(const TSQLite3DB &db)
{
mpDB = db.mpDB;
mnBusyTimeoutMs = SQLTM_TIMEOUT;
return *this;
}
//---------------------------------------------------------------------------
void TSQLite3DB::open(const char *szFile)
{
int nRet = sqlite3_open(szFile, &mpDB);
 
if(nRet != SQLITE_OK)
{
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet, (char *)szError, DONT_DELETE_MSG);
}
 
setBusyTimeout(mnBusyTimeoutMs);
}
//---------------------------------------------------------------------------
void TSQLite3DB::close()
{
if(mpDB)
{
int Result = sqlite3_close(mpDB);
 
if(Result != SQLITE_OK)
{
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(Result, (char *)szError, DONT_DELETE_MSG);
}
 
mpDB = 0;
}
}
//---------------------------------------------------------------------------
int TSQLite3DB::execDML(const char *szSQL)
{
checkDB();
char *szError = 0;
int nRet = sqlite3_exec(mpDB, szSQL, 0, 0, &szError);
 
if(nRet == SQLITE_OK)
{
return sqlite3_changes(mpDB);
}
else
{
throw TSQLite3Exception(nRet, szError);
}
}
//---------------------------------------------------------------------------
TSQLite3Query TSQLite3DB::execQuery(const char *szSQL)
{
checkDB();
sqlite3_stmt *pVM = compile(szSQL);
int nRet = sqlite3_step(pVM);
 
if(nRet == SQLITE_DONE)
{
// no rows
return TSQLite3Query(mpDB, pVM, true);
}
else if(nRet == SQLITE_ROW)
{
// at least 1 row
return TSQLite3Query(mpDB, pVM, false);
}
else
{
nRet = sqlite3_finalize(pVM);
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet, (char *)szError, DONT_DELETE_MSG);
}
}
//---------------------------------------------------------------------------
sqlite_int64 TSQLite3DB::lastRowId()
{
return sqlite3_last_insert_rowid(mpDB);
}
//---------------------------------------------------------------------------
void TSQLite3DB::setBusyTimeout(int nMillisecs)
{
mnBusyTimeoutMs = nMillisecs;
sqlite3_busy_timeout(mpDB, mnBusyTimeoutMs);
}
//---------------------------------------------------------------------------
void TSQLite3DB::checkDB()
{
if(!mpDB)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Database not open",
DONT_DELETE_MSG);
}
}
//---------------------------------------------------------------------------
sqlite3_stmt *TSQLite3DB::compile(const char *szSQL)
{
checkDB();
const char *szTail = 0;
sqlite3_stmt *pVM;
int nRet;
nRet = sqlite3_prepare_v2(mpDB, szSQL, -1, &pVM, &szTail);
 
if(nRet != SQLITE_OK)
{
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet,
(char *)szError,
DONT_DELETE_MSG);
}
 
return pVM;
}
//---------------------------------------------------------------------------
 
 
//---------------------------------------------------------------------------
 
#ifndef SQLite3_unitH
#define SQLite3_unitH
 
#include "sqlite3.h"
 
#define TSQLITE_ERROR 1000
 
//---------------------------------------------------------------------------
class TSQLite3Exception
{
public:
 
TSQLite3Exception(const int nErrCode,
char *szErrMess,
bool bDeleteMsg = true);
 
TSQLite3Exception(const TSQLite3Exception &e);
 
virtual ~TSQLite3Exception();
 
int errorCode() const
{
return mnErrCode;
}
 
char *errorMessage() const
{
return mpszErrMess;
}
 
static const char *errorCodeAsString(int nErrCode);
 
private:
 
int mnErrCode;
char *mpszErrMess;
};
//---------------------------------------------------------------------------
class TSQLite3Query
{
public:
 
TSQLite3Query();
 
TSQLite3Query(const TSQLite3Query &rQuery);
 
TSQLite3Query(sqlite3 *pDB,
sqlite3_stmt *pVM,
bool bEof,
bool bOwnVM = true);
 
TSQLite3Query &operator=(const TSQLite3Query &rQuery);
 
virtual ~TSQLite3Query();
 
int numFields();
 
int fieldIndex(const char *szField);
const char *fieldName(int nCol);
 
const char *fieldDeclType(int nCol);
int fieldDataType(int nCol);
 
const char *fieldValue(int nField);
const char *fieldValue(const char *szField);
 
int getIntField(int nField, int nNullValue = 0);
int getIntField(const char *szField, int nNullValue = 0);
 
double getFloatField(int nField, double fNullValue = 0.0);
double getFloatField(const char *szField, double fNullValue = 0.0);
 
const char *getStringField(int nField, const char *szNullValue = "");
const char *getStringField(const char *szField, const char *szNullValue = "");
 
const unsigned char *getBlobField(int nField, int &nLen);
const unsigned char *getBlobField(const char *szField, int &nLen);
 
bool fieldIsNull(int nField);
bool fieldIsNull(const char *szField);
 
bool eof();
void nextRow();
void finalize();
 
private:
 
void checkVM();
 
sqlite3 *mpDB;
sqlite3_stmt *mpVM;
bool mbEof;
int mnCols;
bool mbOwnVM;
};
//---------------------------------------------------------------------------
class TSQLite3DB
{
public:
TSQLite3DB();
virtual ~TSQLite3DB();
void open(const char *szFile);
void close();
int execDML(const char *szSQL);
TSQLite3Query execQuery(const char *szSQL);
void setBusyTimeout(int nMillisecs);
sqlite_int64 lastRowId();
 
void interrupt()
{
sqlite3_interrupt(mpDB);
}
 
bool isAutoCommit()
{
return sqlite3_get_autocommit(mpDB) != 0;
}
 
static const char *SQLiteVersion()
{
return SQLITE_VERSION;
}
 
sqlite3 *getDB()
{
return mpDB;
}
private:
 
TSQLite3DB(const TSQLite3DB &db);
TSQLite3DB &operator=(const TSQLite3DB &db);
 
sqlite3_stmt *compile(const char *szSQL);
 
void checkDB();
 
sqlite3 *mpDB;
int mnBusyTimeoutMs;
};
 
//---------------------------------------------------------------------------
 
#endif
 
 
 

自己整理的一个访问SQLite3数据库的C++类的更多相关文章

  1. Python访问sqlite3数据库取得dictionary的正路!

    [引子] 很多人都知道,Python里是内置了很好用的sqlite3的.但这个库有个缺陷,在执行fetchall()/fetchone()等方法后,得到的是一个tuple.以前吧,做自己的小项目,tu ...

  2. 使用MyBatis搭建一个访问mysql数据库的简单示例

    MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用 ...

  3. servlet层调用biz业务层出现浏览器 500错误,解决方法 dao数据访问层 数据库Util工具类都可能出错 通过新建一个测试类复制代码逐步测试查找出最终出错原因

    package com.swift.jztk.servlet; import java.io.IOException; import javax.servlet.ServletException; i ...

  4. [转]html5 js 访问 sqlite 数据库的操作类

    本文转自:http://blog.csdn.net/tsxw24/article/details/7613815 webkit 核心的浏览器提供了 3个 api接口,用于访问本地sqlite数据,但使 ...

  5. Java下一个简单的数据库分库帮助类

    简介    前面两篇文章主要讲了数据库读写分离和分表分库的一些问题,这篇文章主要讲一下我个人实现的一个分表分库项目.     在此之前,我有写过一个.Net的分库,最近在做Java的项目,就顺便做出一 ...

  6. 封装List集合一个批量导入数据库的工具类

    public class CommonDal { #region 数据导入相关 /// <summary> /// 批量导入数据 /// </summary> /// < ...

  7. Sql数据库帮组类

    这段时间闲下来写了一些东西,重新写了一个简单的数据库帮组类 public class MyDBHelper { public static readonly string connString = C ...

  8. iphone/iOS 访问本地数据库sqlite3

    Phone也支持访问本地数据库Sqlite 3.这里简单的介绍一下iPhone上Sqlite 3的使用方法. 首先需要在项目中引用Sqlite 3的开发包,下面是在iPhone SDK 3.0下的目录 ...

  9. 并发访问sqlite数据库出现databse is locked的错误的一个解决办法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 在并发访问sqlite数据库会出现这样一个错误:databseis locked,这是sqlite数据库对并发支持不太 ...

随机推荐

  1. QTableWidget学习

    一.这次项目需要用到,可以在tablewidget中添加item,并且可以通过鼠标的右键选项进行一些打开.删除等操作. 1.在构造函数中定制右键菜单选项 ui.tableWidget_2->se ...

  2. 原来腾迅的QQ号竟然是个int变量

    今天有个人加我好友,我一点开申请界面 我惊异了.... 我擦,号码竟然是个负数,但是人物资料里面却是个正数 有编程经验的人,一眼就看得出来原因.而且一眼就看得出来,它们是什么 1857918296 + ...

  3. 关于RSA加密和签名的区别与联系

    发现网上对于RSA加密和签名的介绍普遍偏向于使用和概念的说明,今天想说一点不一样的.对于加解密和签名的使用及概念就不再说了,不知道的请自行百度. 签名的本质其实就是加密,但是由于签名无需还原成明文,因 ...

  4. override new 的区别

    override : 方法提供从基类继承的成员的新实现. 通过 override 声明重写的方法称为重写基方法. 重写基方法必须具有与 override方法相同的签名 new : 关键字可以显式隐藏从 ...

  5. drupal7 smtp+mimemail+mailsystem 实现发送html邮件

    1.下载三个模块 smtp: https://www.drupal.org/project/smtp mimemail: https://www.drupal.org/project/mimemail ...

  6. phonegap 开发指南系列----开始之前(1)

    在基于任何平台(安卓.ios等phonegap支持的平台)上做phonegap开发之前,需要安装 cordova 的 command-line interface (CLI) .CLI详细:http: ...

  7. Eclipse注释快捷键、如何生成API以及可能遇到的问题解决

    1.Java注释方式单行注释// 快捷键:ctrl+/多行注释/* 快捷键:shift+ctrl+/*/文档注释/** 快捷键:shift+Alt+j */ 2.生成API文档 打开index.htm ...

  8. mysql清除主从复制关系

    mysql清除主从复制关系 网页转自https://www.cnblogs.com/wjoyxt/p/5343662.html mysql主从复制中,需要将主从复制关系清除,需要取消其从库角色.这可通 ...

  9. 【JZOJ6376】樱符[完全墨染的樱花]

    description analysis 无向图上任意两点最大流不超过\(2\),说明该图是仙人掌 由于最大流等于最小割,如果一条边在两个环里,断掉两个端点至少需要\(3\)的代价 对于该仙人掌,求两 ...

  10. You can tell a lot about somebody, looking him in the eye.

    You can tell a lot about somebody, looking him in the eye.注视着别人的眼睛,你能读出很多故事.