实例讲解如何使用C++ *** 作MySQL数据库类

实例讲解如何使用C++ *** 作MySQL数据库类,第1张

/ project: 通用模块 ( 用 c++ 处理 mysql 数据库类,像ADO ) description: 通过DataBase,RecordSet,Record,Field类,实现对mysql数据库的 *** 作 包括连接、修改、添加、删除、查询等等,像ADO一样 *** 作数据库,使 用方便 ( the end of this file have one sample, welcom to use ) file:zlb_mysqlh author: @ zlb time:2005-12-12 --/ #ifndef ZLB_MYSQL_H #define ZLB_MYSQL_H #include "mysqlh" #include <iostream> #include <vector> #include <string> using namespace std; namespace zlb_mysql{ / 字段 *** 作 / class Field { public : / 字段名称 / vector<string> m_name; / 字段类型 / vector<enum_field_types> m_type; public : Field(); ~Field(); / 是否是数字 / bool IsNum(int num); / 是否是数字 / bool IsNum(string num); / 是否是日期 / bool IsDate(int num); / 是否是日期 / bool IsDate(string num); / 是否是字符 / bool IsChar(int num); / 是否是字符 / bool IsChar(string num); / 是否为二进制数据 / bool IsBlob(int num); / 是否为二进制数据 / bool IsBlob(string num); / 得到指定字段的序号 / int GetField_NO(string field_name); }; / 1 单条记录 2 [int ] *** 作 [""] *** 作 / class Record { public: / 结果集 / vector<string> m_rs; / 字段信息 占用4字节的内存 当记录数很大是回产生性能问题 / Field m_field; public : Record(){}; Record(Field m_f); ~Record(); void SetData(string value); / [""] *** 作 / string operator[](string s); string operator[](int num); / null值判断 / bool IsNull(int num); bool IsNull(string s); / 用 value tab value 的形式 返回结果 / string GetTabText(); }; / 1 记录集合 2 [int ] *** 作 [""] *** 作 3 表结构 *** 作 4 数据的插入修改 / class RecordSet { private : / 记录集 / vector<Record> m_s; / 游标位置/ unsigned long pos; / 记录数 / int m_recordcount; / 字段数 / int m_field_num; / 字段信息 / Field m_field; MYSQL_RES res ; MYSQL_FIELD fd ; MYSQL_ROW row; MYSQL m_Data ; public : RecordSet(); RecordSet(MYSQL hSQL); ~RecordSet(); / 处理返回多行的查询,返回影响的行数 / int ExecuteSQL(const char SQL); / 得到记录数目 / int GetRecordCount(); / 得到字段数目 / int GetFieldNum(); / 向下移动游标 / long MoveNext(); / 移动游标 / long Move(long length); / 移动游标到开始位置 / bool MoveFirst(); / 移动游标到结束位置 / bool MoveLast(); / 获取当前游标位置 / unsigned long GetCurrentPos()const; / 获取当前游标的对应字段数据 / bool GetCurrentFieldValue(const char sFieldName,char sValue); bool GetCurrentFieldValue(const int iFieldNum,char sValue); / 获取游标的对应字段数据 / bool GetFieldValue(long index,const char sFieldName,char sValue); bool GetFieldValue(long index,int iFieldNum,char sValue); / 是否到达游标尾部 / bool IsEof(); / 返回字段 / Field GetField(); / 返回字段名 / const char GetFieldName(int iNum); / 返回字段类型 / const int GetFieldType(char sName); const int GetFieldType(int iNum); / 返回指定序号的记录 / Record operator[](int num); }; / 1 负责数据库的连接关闭 2 执行sql 语句(不返回结果) 3 处理事务 / class DataBase { public : DataBase(); ~DataBase(); private : / msyql 连接句柄 / MYSQL m_Data; public : / 返回句柄 / MYSQL GetMysql(); / 连接数据库 / int Connect(string host, string user, string passwd, string db, unsigned int port, unsigned long client_flag); / 关闭数据库连接 / void DisConnect(); / 执行非返回结果查询 / int ExecQuery(string sql); / 测试mysql服务器是否存活 / int Ping(); / 关闭mysql 服务器 / int ShutDown(); / 主要功能:重新启动mysql 服务器 / int ReBoot(); / 说明:事务支持InnoDB or BDB表类型 / / 主要功能:开始事务 / int Start_Transaction(); / 主要功能:提交事务 / int Commit(); / 主要功能:回滚事务 / int Rollback(); / 得到客户信息 / const char Get_client_info(); / 主要功能:得到客户版本信息 / const unsigned long Get_client_version(); / 主要功能:得到主机信息 / const char Get_host_info(); / 主要功能:得到服务器信息 / const char Get_server_info(); /主要功能:得到服务器版本信息/ const unsigned long Get_server_version(); /主要功能:得到 当前连接的默认字符集/ const char Get_character_set_name(); / 主要功能返回单值查询 / char ExecQueryGetSingValue(string sql); / 得到系统时间 / const char GetSysTime(); / 建立新数据库 / int Create_db(string name); / 删除制定的数据库/ int Drop_db(string name); }; }; #endif //ZLB_MYSQL_H / project: 通用模块 ( 用 c++ 处理 mysql 数据库类,像ADO ) description: 通过DataBase,RecordSet,Record,Field类,实现对mysql数据库的 *** 作 包括连接、修改、添加、删除、查询等等,像ADO一样 *** 作数据库,使 用方便 ( the end of this file have one sample, welcom to use ) file:zlb_mysqlcpp author: @ zlb time:2005-12-12 --/ #include "stdafxh" #include "zlb_mysqlh" namespace zlb_mysql{ / +++++++++++++++++++++++++++++++++++++++++++++++++++ / / 字段 *** 作 / Field::Field(){} Field::~Field(){} / 是否是数字 / bool Field::IsNum(int num) { if(IS_NUM(m_type[num])) return true; else return false; } / 是否是数字 / bool Field::IsNum(string num) { if(IS_NUM(m_type[GetField_NO(num)])) return true; else return false; } / 是否是日期 / bool Field::IsDate(int num) { if( FIELD_TYPE_DATE == m_type[num] || FIELD_TYPE_DATETIME == m_type[num] ) return true; else return false; } / 是否是日期 / bool Field::IsDate(string num) { int temp; temp=GetField_NO(num); if(FIELD_TYPE_DATE == m_type[temp] || FIELD_TYPE_DATETIME == m_type[temp] ) return true; else return false; } / 是否是字符 / bool Field::IsChar(int num) { if(m_type[num]==FIELD_TYPE_STRING || m_type[num]==FIELD_TYPE_VAR_STRING || m_type[num]==FIELD_TYPE_CHAR ) return true; else return false; } / 是否是字符 / bool Field::IsChar(string num) { int temp; temp=this->GetField_NO (num); if(m_type[temp]==FIELD_TYPE_STRING || m_type[temp]==FIELD_TYPE_VAR_STRING || m_type[temp]==FIELD_TYPE_CHAR ) return true; else return false; } / 是否为二进制数据 / bool Field::IsBlob(int num) { if(IS_BLOB(m_type[num])) return true; else return false; } / 是否为二进制数据 / bool Field::IsBlob(string num) { if(IS_BLOB(m_type[GetField_NO(num)])) return true; else return false; } / 得到指定字段的序号 / int Field::GetField_NO(string field_name) { for(unsigned int i=0;i<m_namesize ();i++) { if(!m_name[i]compare (field_name)) return i; } return -1; } /-----------------------------------------------------/ / +++++++++++++++++++++++++++++++++++++++++++++++++++ / / 1 单条记录 2 [int ] *** 作 [""] *** 作 / Record::Record(Field m_f) { m_field =m_f; } Record::~Record(){}; void Record::SetData(string value) { m_rspush_back (value); } / [""] *** 作 / string Record::operator[](string s) { return m_rs[m_field->GetField_NO(s)]; } string Record::operator[](int num) { return m_rs[num]; } / null值判断 / bool Record::IsNull(int num) { if("" == m_rs[num]c_str ()) return true; else return false; } bool Record::IsNull(string s) { if("" == m_rs[m_field->GetField_NO(s)]c_str()) return true; else return false; } / 主要-功能:用 value tab value 的形式 返回结果 / string Record::GetTabText() { string temp; for(unsigned int i=0 ;i<m_rssize();i++) { temp+=m_rs[i]; if(i<m_rssize ()-1) temp+="\t"; } return temp; } /-----------------------------------------------------/ / +++++++++++++++++++++++++++++++++++++++++++++++++++ / / 1 记录集合 2 [int ] *** 作 [""] *** 作 3 表结构 *** 作 4 数据的插入修改 / RecordSet::RecordSet() { res = NULL; row = NULL; pos = 0; } RecordSet::RecordSet(MYSQL hSQL) { res = NULL; row = NULL; m_Data = hSQL; pos = 0; } RecordSet::~RecordSet() { } / 处理返回多行的查询,返回影响的行数 成功返回行数,失败返回-1 / int RecordSet::ExecuteSQL(const char SQL) { if ( !mysql_real_query(m_Data,SQL,strlen(SQL))) { //保存查询结果 res = mysql_store_result(m_Data ); //得到记录数量 m_recordcount = (int)mysql_num_rows(res) ; //得到字段数量 m_field_num = mysql_num_fields(res) ; for (int x = 0 ; fd = mysql_fetch_field(res); x++) { m_fieldm_namepush_back(fd->name); m_fieldm_typepush_back(fd->type); } //保存所有数据 while (row = mysql_fetch_row(res)) { Record temp(&m_field); for (int k = 0 ; k < m_field_num ; k++ ) { if(row[k]==NULL||(!strlen(row[k]))) { tempSetData (""); } else { tempSetData(row[k]); } } //添加新记录 m_spush_back (temp); } mysql_free_result(res ) ; return m_ssize(); } return -1; } / 向下移动游标 返回移动后的游标位置 / long RecordSet::MoveNext() { return (++pos); } / 移动游标 / long RecordSet::Move(long length) { int l = pos + length; if(l<0) { pos = 0; return 0; }else { if(l >= m_ssize()) { pos = m_ssize()-1; return pos; }else { pos = l; return pos; } } } / 移动游标到开始位置 / bool RecordSet::MoveFirst() { pos = 0; return true; } / 移动游标到结束位置 / bool RecordSet::MoveLast() { pos = m_ssize()-1; return true; } / 获取当前游标位置 / unsigned long RecordSet::GetCurrentPos()const { return pos; } / 获取当前游标的对应字段数据 / bool RecordSet::GetCurrentFieldValue(const char sFieldName, char sValue) { strcpy(sValue,m_s[pos][sFieldName]c_str()); return true; } bool RecordSet::GetCurrentFieldValue(const int iFieldNum,char sValue) { strcpy(sValue,m_s[pos][iFieldNum]c_str()); return true; } / 获取游标的对应字段数据 / bool RecordSet::GetFieldValue(long index,const char sFieldName, char sValue) { strcpy(sValue,m_s[index][sFieldName]c_str()); return true; } bool RecordSet::GetFieldValue(long index,int iFieldNum,char sValue) { strcpy(sValue,m_s[index][iFieldNum]c_str()); return true; } / 是否到达游标尾部 / bool RecordSet::IsEof() { return (pos == m_ssize())true:false; } / 得到记录数目 / int RecordSet::GetRecordCount() { return m_recordcount; } / 得到字段数目 / int RecordSet::GetFieldNum() { return m_field_num; } / 返回字段 / Field RecordSet::GetField() { return &m_field; } / 返回字段名 / const char RecordSet::GetFieldName(int iNum) { return m_fieldm_nameat(iNum)c_str(); } / 返回字段类型 / const int RecordSet::GetFieldType(char sName) { int i = m_fieldGetField_NO(sName); return m_fieldm_typeat(i); } const int RecordSet::GetFieldType(int iNum) { return m_fieldm_typeat(iNum); } / 返回指定序号的记录 / Record RecordSet::operator[](int num) { return m_s[num]; } / -------------------------------------------------- / / +++++++++++++++++++++++++++++++++++++++++++++++++++ / / 1 负责数据库的连接关闭 2 执行sql 语句(不返回结果) 3 处理事务 / DataBase::DataBase() { m_Data = NULL; } DataBase::~DataBase() { if(NULL != m_Data) { DisConnect(); } } / 返回句柄 / MYSQL DataBase::GetMysql() { return m_Data; } / 主要功能:连接数据库 参数说明: 1 host 主机ip地址或者时主机名称 2 user 用户名 3 passwd 密码 4 db 欲连接的数据库名称 5 port 端口号 6 uinx 嵌套字 7 client_flag 客户连接参数 返回值: 0成功 -1 失败 / int DataBase::Connect(string host, string user, string passwd, string db, unsigned int port, unsigned long client_flag) { if((m_Data = mysql_init(NULL)) && mysql_real_connect( m_Data, hostc_str(), userc_str(), passwdc_str(), dbc_str(),port , NULL, client_flag)) { //选择制定的数据库失败 if ( mysql_select_db( m_Data, dbc_str () ) < 0 ) { mysql_close( m_Data) ; return -1 ; } } else { //初始化mysql结构失败 mysql_close( m_Data ); return -1 ; } //成功 return 0; } / 关闭数据库连接 / void DataBase::DisConnect( ) { mysql_close(m_Data) ; } / 主要功能: 执行非返回结果查询 参数:sql 待执行的查询语句 返回值; n为成功 表示受到影响的行数 -1 为执行失败 / int DataBase::ExecQuery(string sql) { if(!mysql_real_query(m_Data,sqlc_str (),(unsigned long)sqllength()) ) { //得到受影响的行数 return (int)mysql_affected_rows(m_Data) ; } else { //执行查询失败 return -1; } } / 主要功能:测试mysql服务器是否存活 返回值:0 表示成功 -1 失败 / int DataBase::Ping() { if(!mysql_ping(m_Data)) return 0; else return -1; } / 主要功能:关闭mysql 服务器 返回值;0成功 -1 失败 / int DataBase::ShutDown() { if(!mysql_shutdown(m_Data,SHUTDOWN_DEFAULT)) return 0; else return -1; } / 主要功能:重新启动mysql 服务器 返回值;0表示成功 -1 表示失败 / int DataBase::ReBoot() { if(!mysql_reload(m_Data)) return 0; else return -1; } / 说明:事务支持InnoDB or BDB表类型 / / 主要功能:开始事务 / int DataBase::Start_Transaction() { if(!mysql_real_query(m_Data, "START TRANSACTION" , (unsigned long)strlen("START TRANSACTION") )) { return 0; } else //执行查询失败 return -1; } / 主要功能:提交事务 返回值:0 表示成功 -1 表示失败 / int DataBase::Commit() { if(!mysql_real_query( m_Data, "COMMIT", (unsigned long)strlen("COMMIT") ) ) { return 0; } else //执行查询失败 return -1; } / 主要功能:回滚事务 返回值:0 表示成功 -1 表示失败 / int DataBase::Rollback() { if(!mysql_real_query(m_Data, "ROLLBACK", (unsigned long)strlen("ROLLBACK") ) ) return 0; else //执行查询失败 return -1; } / 得到客户信息 / const char DataBase::Get_client_info() { return mysql_get_client_info(); } /主要功能:得到客户版本信息/ const unsigned long DataBase::Get_client_version() { return mysql_get_client_version(); } / 主要功能:得到主机信息 / const char DataBase::Get_host_info() { return mysql_get_host_info(m_Data); } / 主要功能:得到服务器信息 / const char DataBase::Get_server_info() { return mysql_get_server_info( m_Data ); } / 主要功能:得到服务器版本信息 / const unsigned long DataBase::Get_server_version() { return mysql_get_server_version(m_Data); } /主要功能:得到 当前连接的默认字符集/ const char DataBase::Get_character_set_name() { return mysql_character_set_name(m_Data); } / 主要功能返回单值查询 / char DataBase::ExecQueryGetSingValue(string sql) { MYSQL_RES res; MYSQL_ROW row ; char p = NULL; if(!mysql_real_query( m_Data, sqlc_str(),(unsigned long)sqllength())) { //保存查询结果 res = mysql_store_result( m_Data ) ; row = mysql_fetch_row( res ) ; p = ((row[0]==NULL)||(!strlen(row[0])))"-1":row[0]; mysql_free_result( res ) ; } else //执行查询失败 p = "-1"; return p; } / 得到系统时间 / const char DataBase::GetSysTime() { return ExecQueryGetSingValue("select now()"); } / 主要功能:建立新数据库 参数:name 为新数据库的名称 返回:0成功 -1 失败 / int DataBase::Create_db(string name) { string temp ; temp="CREATE DATABASE "; temp+=name; if(!mysql_real_query( m_Data,tempc_str () , (unsigned long)templength ()) ) return 0; else //执行查询失败 return -1; } / 主要功能:删除制定的数据库 参数:name 为欲删除数据库的名称 返回:0成功 -1 失败 / int DataBase::Drop_db(string name) { string temp ; temp="DROP DATABASE "; temp+=name; if(!mysql_real_query( m_Data,tempc_str () , (unsigned long)templength ()) ) return 0; else //执行查询失败 return -1; } /-----------------------------------------------------/ }; / 使用例子 / #include "zlb_mysqlh" using namespace std; void main() { zlb_mysql::DataBase zlb; //连接数据库 if(-1 == zlbConnect("localhost"/本地数据库,可以是远程 ip/, "root"/用户名/,"apple"/密码/, "test"/数据库名/, 0,0/两个标志,mysql文档有说明,一般为0/)) { std::cout<<"connect failed "<<std::endl; } else { std::cout<<"connect success"<<std::endl; } //通过返回的数据库句柄,建立记录急,你可以通过返回的这个句柄建立多个记录急 zlb_mysql::RecordSet rs(zlbGetMysql()); rsExecuteSQL("select from testtable");//这个语句大家都知道是什么意思了 cout<<rsGetRecordCount()/返回的总的记录数/<<endl; cout<<rsGetFieldNum()/返回的总的字段数/<<endl; cout<<rs[0]GetTabText()/返回第一条记录,你也可以rs[1]GetTabText() 如果你有多条记录, / <<endl; /实现遍列,也可以使用后面的遍列方式/ for(int i=0;i<rsGetRecordCount();++i) { for(int j =0;j<rsGetFieldNum();++j) cout<<rs[i][j]; cout<<endl; } zlb_mysql::Field fd = rsGetField();/你可以通过这样的方式,获取字段的信息/ cout<<fd->GetField_NO("Password")/返回我表里的 Password 字段的位置,不 是记录的位置/ <<endl; cout<<rs[0]["Password"]<<endl;/输出第0行第Password列的值/ cout<<rs[0][fd->GetField_NO("Password")]<<endl;/你也可以这样/ cout<<rsGetFieldName(0)/获取字段的名字/<<endl; cout<<rsGetFieldType("UserName")/获取字段的类型,是mysql里定义的/<<endl; cout<<rsGetCurrentPos()/获取当前记录的位置/<<endl; char s[50]; rsGetCurrentFieldValue(1,s);/获取当前记录对应字段的值/ cout<<s<<endl; cout<<rsMove(1)<<endl;/移动游标,正数往前 负数往后/ cout<<rsGetCurrentPos()<<endl; rsGetCurrentFieldValue(1,s); cout<<s<<endl; rsMoveFirst();/移动游标到最前/ while(!rsIsEof()/判断是否到达游标尾,实现遍列/) { rsGetCurrentFieldValue("UserName",s); cout<<s<<"\t"; rsGetCurrentFieldValue("Password",s); cout<<s<<"\t

"; rsMoveNext(); } rsGetFieldValue(0,"UserName",s);/获取指定行 的记录值/ cout<<s<<"\t"; rsGetFieldValue(0,"Password",s); cout<<s<<"\t

"; }

代码错误。sqldatasource是SQL服务器的名字,主要负责建立与数据库的连接。sqldatasource配置不上数据库,多数是代码错误,或者是在服务器上输入的代码,输入错误导致的,是需要重新检查一遍代码即可。

在VB中使用ADO

在程序设计中,ADO不是作为可视化的控件来使用的,如果要在应用程序中使用ADO组件,需要在"工程"菜单下的"引用"项中选该组件!该组件名称为:"MircrosoftActiveXDataObject20Library"(注:可能有2526或者其他版本)

3-

使用ADO访问数据库类似于高速公路,首先,必须先修好公路,建立城市与城市间的连接,汽车才能在上面运行,ADO首先也需要建立程序与数据库间的连接,然后在这个连接上执行 *** 作

因此ADO提供了一个连接对象,该对象负责建立与数据库的连接,因此提供了一些属性以供设置,同时也提供了建立连接的方法与相应连接相关的事件!

连接建立之后,连接对像本身也提供了数据库执行 *** 作的方法,但要更强有力的执行SQL的功能要由另一个命令对象来实现

此外,一个非常重要的对象是记录集对像,因为在很多时候,需要执行数据库的查询,而查询的结果返回必须以某个容器来承载,就好比高速公路运送回来的货物需要建立一个物资仓库来进行货物的接收和储存

还需要注意的是,要求程序与数据库之间断开连接

连接对象,命令对象,和记录集对象分别对应ADO的Connection,Command,和Recordset三个对象

4-

1连接对象(Connection)的主要属性

属性名称属性说明

Provider指定要进行连接的提供程序的名称,该属性标识要进行数据连接的数据库类型

设置或者返回产生错误之前执行命令期间需等待的时间,单位为秒

设置或者返回产生错误前建立连接期间所等待的时间,单位为秒

设置建立到数据源的连接的信息,不同的信息单元以";"号分割

State说明当前连接的状态信息

主要属性说明:

AProvider

用Provider属性可以设置或返回连接提供者名称,也可以通过属性的内容或open方法的参数设置该属性

例如:ConProvider="MicrosoftJetOLEDB351"

ConProvider="sqloledb"

分别表示aess与SqlServer的连接支持!

B

例如,可以按以下方式分别设置SQLServer与Aess的连接字符串信息

Con="driver={SQLServer};server=SV1;uid=sa;pwd=;database=pubs"

Con="Provider=MicrosoftJetOLEDB40;DataSource=C:MDB"

请注意Aess数据库与SqlServer数据库不同的连接方式,Aess数据库需要指定具体的文件名,而SqlServer通过指定数据库名来访问

连接方式可以还可以是数据源,例如,可以使用建立的数据源连接:

Con="DSN=ACCPSQL;server=SV1;uid=sa;pwd=;"

CState

该属性是只读的,不能进行设置,返回值为常数表示连接已关闭,返回值adStateOpen常数表示连接是打开的

附:ProviderParameters参数

提供程序参数字符串

MicrusoftJetMicrosoftJetOLEDB351

OracleMSDAORA

MicrosoftODBCDriverMSDASQL

SQLServerSQLOLEDB

java连接数据库的代码位于MVC中的M(模型层)中,主要负责与数据库打交道。

本人把我以前写的代码加上注释给你看看希望对你有帮助。

publicclassUserInfoDAO{

//验证登陆名/密码sql语句

//private-----这个sql语句只在本类内部使用,没有必要public

//static-----sql语句仅仅一份就足够了

//final-----sql语句一般在运行时不变,final修饰的变量相当于常量

//常量名所有字母大写

privatestaticfinalStringSQL_CHECK_USERINFO=

"SELECTLOGINNAME,USERNAME,PASSWORD,AGE,ADDRESSFROMUSERINFOWHERELOGINNAME=ANDPASSWORD=";

publicUserInfoDAO(){

}

/

验证登陆名/密码方法

@paramuUserInfo

@returnboolean

/

publicbooleancheckUser(UserInfou){

booleanb=false;//验证是否成功的标识

Connectionconn=null;//数据库连接的引用

pstmt=null;//引用

ResultSetrs=null;//结果集引用

//调用的方法,得到数据库里连接实例

conn=();

try{

//通过Connection的()方法构建实例,参数为sql语句

pstmt=conn(SQL_CHECK_USERINFO);

//为sql语句中的赋值,注意序号从1开始

pstmtsetString(1,u());

pstmtsetString(2,ugetPassword());

//执行查询得到结果集

rs=pstmt();

//在结果集中循环,如果结果集中有记录意味着验证成功

b=rsnext();//标识置为true

while(rsnext()){

b=true;//标识置为true

}

}catch(ex){

Systemoutprintln(exgetMessage());

}finally{

//注意:一定在finally中释放数据库资源

cleanUP(rs,pstmt,conn);

}

returnb;

}

privatevoidcleanUP(ResultSetrs,pstmt,Connectionconn){

try{

if(rs!=null){

rsclose();

}

if(pstmt!=null){

pstmtclose();

}

if(conn!=null){

connclose();

}

}catch(ex){

Systemoutprintln(exgetMessage());

}

}

}

1、基本概念及原理

由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道,对于共享资源,有一个很著名的设计模式:资源池 (Resource Pool)。该模式正是为了解决资源的频繁分配释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接 建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定 连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量使用情况,为系统开发测试及性能调 整提供依据。

2、服务器自带的连接池

JDBC的API中没有提供连接池的方法。一些大型的WEB应用服务器如BEA的WebLogic和IBM的WebSphere等提供了连接池的机制,但是必须有其第三方的专用类方法支持连接池的用法。

连接池关键问题分析

1、并发问题

为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为Java语言自身提供了对并发管理的支 持,使用synchronized关键字即可确保线程是同步的。使用方法为直接在类方法前面加上synchronized关键字,如:

public synchronized Connection getConnection()

2、多数据库服务器和多用户

对于大型的企业级应用,常常需要同时连接不同的数据库(如连接Oracle和Sybase)。如何连接不同的数据库呢我们采用的策略是:设计 一个符合单例模式的连接池管理类,在连接池管理类的唯一实例被创建时读取一个资源文件,其中资源文件中存放着多个数据库的url地址()用户名()密 码()等信息。如 txurl=1722115123:5000/tx_it,txuser=yang,txpassword=yang321。根据资源文件提 供的信息,创建多个连接池类的实例,每一个实例都是一个特定数据库的连接池。连接池管理类实例为每个连接池实例取一个名字,通过不同的名字来管理不同的连 接池。

对于同一个数据库有多个用户使用不同的名称和密码访问的情况,也可以通过资源文件处理,即在资源文件中设置多个具有相同url地址,但具有不同用户名和密码的数据库连接信息。

3、事务处理

我们知道,事务具有原子性,此时要求对数据库的 *** 作符合“ALL-ALL-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。

在Java语言中,Connection类本身提供了对事务的支持,可以通过设置Connection的AutoCommit属性为 false,然后显式的调用commit或rollback方法来实现。但要高效的进行Connection复用,就必须提供相应的事务支持机制。可采用 每一个事务独占一个连接来实现,这种方法可以大大降低事务管理的复杂性。

4、连接池的分配与释放

连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。

对于连接的管理可使用空闲池。即把已经创建但尚未分配出去的连接按创建时间存放到一个空闲池中。每当用户请求一个连接时,系统首先检查空闲池内 有没有空闲连接。如果有就把建立时间最长(通过容器的顺序存放实现)的那个连接分配给他(实际是先做连接是否有效的判断,如果可用就分配给用户,如不可用 就把这个连接从空闲池删掉,重新检测空闲池是否还有连接);如果没有则检查当前所开连接池是否达到连接池所允许的最大连接数(maxConn),如果没有 达到,就新建一个连接,如果已经达到,就等待一定的时间(timeout)。如果在等待的时间内有连接被释放出来就可以把这个连接分配给等待的用户,如果 等待时间超过预定时间timeout,则返回空值(null)。系统对已经分配出去正在使用的连接只做计数,当使用完后再返还给空闲池。对于空闲连接的状 态,可开辟专门的线程定时检测,这样会花费一定的系统开销,但可以保证较快的响应速度。也可采取不开辟专门线程,只是在分配前检测的方法。

5、连接池的配置与维护

连接池中到底应该放置多少连接,才能使系统的性能最佳系统可采取设置最小连接数(minConn)和最大连接数(maxConn)来控制连接 池中的连接。最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很 快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连 接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过反复测试,找到最佳点。

如何确保连接池中的最小连接数呢有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。

这其实是一个比较虚的概念。广义的中间件范围很广。起沟通作用的都可以认为是中间件。甚至ODBC这样的东西你也可以认为是中间件。

现在用的比较多的中间件应该是BEA公司的tuxedo和IBM公司的weblogic(好象是这个东西),我接触过一点tuxedo。oracle、sun和ms好象也有类似产品,不过用的人很少。tuxedo是这个领域的领导者,不过IBM正在追赶并有可能超过,毕竟,IBM就是IBM。

tuxedo这东西我们用来做数据库和前台应用之间的中间件。

使用了中间件之后,以前直接连接的前台应用程序和数据库之前就多了个tuxedo,现在前台程序把请求发给tuxedo,tuxedo再把请求发给数据库,数据库处理结束之后把结果返回tuxedo,tuxedo再把结果送回给前台。这样一搞,表面看复杂了很多。不过带来一些好处,比如:

安全。tuxedo的服务是定制的,这就有点象是存贮过程,因为应用程序无法直接接到数据库而只能通过tuxedo,所以应用程序无法做tuxedo服务之外的事情。你把你的应用逻辑写在tuxedo中,你就可以保证你的数据是安全的。

性能。有些数据库性能不好,比如oracle一个连接就是好多M,连接数一多,机器内存就没了,有了tuxedo之后,tuxedo负责连接数据库,连接数比较少,tuxedo可以用排队的方式来处理这些数据库请求,这样提高了性能。中间件的高级应用好象还可以把数据库分布在不同的机器上,由tuxedo动态分配前、后台的请求和处理,把它们搞在不同的机器上,所以你用了中间件之后如果后台数据库处理来不及,可以加一台机器,前台请求太多(比如网站)可以加多前台机器。你可以灵活的调整性能。

应用服务器做的人好象就更多了。而且应用服务器这东西和中间件类似(逻辑上)我觉得它应用也是中间件的一种,不过大家一般说中间件都是指的狭义的中间件,就是tuxedo这些。

中间件应用领域很广的。简直大一点的应用都可以用到中间件。国内也有一些开发商自己写中间件,不过好象是自己用,没形成市场。

1、打开代码窗口,添加引用:Imports SystemDataSqlClient。

2、输入以下代码:

“Public conn1  As SqlConnection = New SqlConnection _

("server=192168179; Initial Catalog= student; User ID= panqe;PWD=shentai768@")”,vb就已经成功连接sql数据库了。

3、代码详解:声明关键字Public(因为是全局变量,所以用Public 来声明)。

4、连接参数。

5、如果SQL 数据库就在本机,则用以下代码连接:

("server=; Integrated Security=False;Initial Catalog= student; User ID= panqe;PWD=shentai768@")。

6:如果代码太长,影响可读性,可以用空格加"_"后,回车换行。

看了你上面说的,你是在做毕业设计吧,冒昧的问一句要使用什么语言开发?

图书信息管理系统是毕业设计项目里最普遍的,常常作为教学的基础事例,所以给你一些小小建议和设计思路,希望能给予你帮助。

1、作为毕业设计可能要求不需要那么复杂,通讯加密可能用不到。

2、对于管理系统整体架构的设计,分三部分就行,也就是MVC三层结构。

V代表View,表示层,所有显示界面都是在这层设计

C代表Control,控制层,所有业务控制逻辑写在这层里

M代表Medol,数据模型层, *** 作数据的方法写在这里面

3、知道什么是MVC,就可以开始选择你的语言去设计了,选择一门语言,你们开发管理系统估计,除了java、就是C#了。然后选择设计模式BS还是CS,一般都是BS的,基于浏览器开发的web系统,基于java的结合jsp开发,基于C#的结合asp进行

4、然后选择你一个你最熟悉使用的数据库,毕业设计系统,必须要有数据库才行,要不展示你动态网站开发特性。目前最常用的有Oracle、SQL Server、MySQL,建议你使用MySQL,比较小好安装,不过创建表时,一定要注意编码格式问题,不然容易乱码,一般建议使用UTF-8,界面也要跟着同步

5、前几个主要条件确定了,可以开发了,看你上面说的,你是组长吧,就好比我们开发中的Leader,你负责设计功能并分配任务给你部下。开发一个软件首先要有个demo,才能开发。就是模型,你可以用纸画,把界面画出来,把你要添加什么样的控件,每个页面要实现什么功能,点击某个控件会出现什么功能,要想清楚。介于是毕业设计,我想应该不需要太多时间去设计。图书管理系统为例,大概可能就分为用户管理,图书信息管理,图书租借管理三大功能模块。用户管理中包括用户的增删改查、权限的分配。图书信息管理中包括图书信息的增删改查,图书租借就是一个功能。这样小功能分为10个。每个都是一个界面。需要你去想他们之间的关系,并先把界面画出来,每个组员分两个功能,正好10个功能。还有一个登录注册界面、主界面菜单自己设计吧,登录管理员能进显示个界面,登录学生能显示哪个界面,好好设计一下权限。

6、界面画出来了,你这时候就得想怎么和数据库进行沟通了。这个时候需要了解数据设计知识,表的设计需要知道现实中抽象出来的实体是什么,还有实体的属性有什么。目前来说,你最少有三个实体,一个是用户,一个是图书,最后一个借阅记录表。每个表代表一个实体,一个表的字段代表它的属性。比如:用户表,它有什么属性,id(确定一个用户唯一的标识)、学号、教师号、姓名、性别、专业、权限级别、创建时间、删除时间等信息。图书表:Id、书名、书类别、总数量、剩余量等。借阅记录表:id,借书人id,图书id,借阅开始时间,还书时间等。把表信息设计出来了,就开始用SQL创建表,一般都用varchar类型,因为字符串类型可以存储任何类型数据,包括数字,字母,字符等,和界面类型之间可以转化,用时比较方便。

7、编写写Medol层,每种语言在连接数据时都差不多,需要知道数据名称,用户名、密码。然后连接,编写对数据库增删改查的代码。前台传来要增删改查的数据,要确定对哪个表进行增删改查,你都可以用你编写通用Medol层对数据库进行 *** 作实现。

8、逻辑Control控制层,就需要你对前台功能业务的需求去开发了。比如你要添加一个用户信息,那就得用insert语句, *** 作表可能是Account表,id设置为数据自动生成,你需要插入姓名、学号或者教师号等信息,与此同时,还要在界面选择该用户的权限,转化为数字插入到数据库中。在登录的时候,先select role from Account a where aname = '李四' and apassword ='123456',看看有没有查询结果,没有则没有该用户,在界面显示该用户不存在,如果有值,就知道该用户权限,根据权限值,决定要显示哪些功能菜单。这就是业务逻辑。

不知道以我的开发经验写的开发过程,能不能帮助到你,祝你一切顺利,有什么问题可以随时联系我。

以上就是关于实例讲解如何使用C++ *** 作MySQL数据库类全部的内容,包括:实例讲解如何使用C++ *** 作MySQL数据库类、sqldatasource配置不上数据库、vb用ado连接sql数据库(vb与sql数据库连接)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9466731.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存