diy数据库(二)--网络通信类
一、首先,我们先实现OSS层的ossSocket类。供数据库client和数据库引擎进行通信
友情提示:相应上面的类图的头文件和源码附在了本文的最以下。
int _fd ;//socket的文件描写叙述符
socklen_t _addressLen ;//地址长度
socklen_t _peerAddressLen ;//对方地址的长度
struct sockaddr_in _sockAddress ;//本地的socket地址 ipv4
struct sockaddr_in _peerAddress ;//对方的socket地址 ipv4
bool _init ;//代表是否已经初始化
int _timeout ;//代表超时时间,包含读和写的超时
这是一个基础类,都是对socket的通用的操作,实现方法也比較常见。
这里主要注意的有几点:
1.读写sockt时要注意信号中断带来的错误ENTRY,对于中断。我们要手动处理。
2.因为数据库需的操作须要有实时性。我们须要设置TCP_NODELAY套接字选项,来关闭TCP的Nagle算法
3.我们的ossSocket类中的读写函数有一个特点就是添加了时间限制。即我们要求在给定时间參数的范围类得带可读或可写的socket,不然推断读写超时
4.为了防止socket进入timewait状态,我们须要设置SO_REUSEADDR套接字选项
5.当向一个已经收到RST的套接字运行写操作时,内核会向用户进程发送一个SIGPIPE信号。
该信号的默认行为是终止进程。
send()函数的最后一个參数能够设MSG_NOSIGNAL,来禁止内核发送SIGPIPE信号。
附录:
下面是头文件:ossSocket.hpp
#ifndef OSSNETWORK_HPP_
#define OSSNETWORK_HPP_ #include "core.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define SOCKET_GETLASTERROR errno//系统的错误码
#define OSS_EAGAIN EAGAIN
#define OSS_EINTR EINTR
#define closesocket close // by default 10ms timeout
#define OSS_SOCKET_DFT_TIMEOUT 10000//默认10毫秒的超时 // max hostname
#define OSS_MAX_HOSTNAME NI_MAXHOST//hostname的
#define OSS_MAX_SERVICENAME NI_MAXSERV #include "core.hpp" typedef int SOCKET; class _ossSocket
{
private ://全部
int _fd ;//socket的文件描写叙述符
socklen_t _addressLen ;//地址长度
socklen_t _peerAddressLen ;//对方地址的长度
struct sockaddr_in _sockAddress ;//本地的socket地址 ipv4
struct sockaddr_in _peerAddress ;//对方的socket地址 ipv4 bool _init ;//代表是否已经初始化
int _timeout ;//代表超时时间,包含读和写的超时
protected:
unsigned int _getPort ( sockaddr_in *addr ) ;//得到端口
int _getAddress ( sockaddr_in *addr, char *pAddress, unsigned int length ) ;//得到地址 public :
int setSocketLi ( int lOnOff, int linger ) ;//设置close连接时对发送缓冲区中数据的操作
void setAddress(const char * pHostName, unsigned int port );
// Create a listening socket
_ossSocket();//设置默认的socket的属性
_ossSocket ( unsigned int port, int timeout = 0 ) ;//设置socket的属性
_ossSocket ( const char *pHostname, unsigned int port, int timeout = 0 ) ;<span style="font-family: Arial, Helvetica, sans-serif;">// 创建一个clientsocket</span>
_ossSocket ( int *sock, int timeout = 0 ) ;<span style="font-family: Arial, Helvetica, sans-serif;">//通过accept的到的socket的fd来构建</span> ~_ossSocket ()
{
close () ;
}
int initSocket () ;//初始化函数
int bind_listen () ;//将socket绑定到一个端口
bool isConnected () ;//推断连接状态
int send ( const char *pMsg, int len,
int timeout = OSS_SOCKET_DFT_TIMEOUT,
int flags = 0 ) ;
int recv ( char *pMsg, int len,
int timeout = OSS_SOCKET_DFT_TIMEOUT,
int flags = 0 ) ;//收到固定长度的数据才返回(timeout=0表示永远不会超时)
int recvNF ( char *pMsg, int &len,
int timeout = OSS_SOCKET_DFT_TIMEOUT ) ;//不用收到固定长度的数据 int connect () ;
void close () ;
int accept ( int *sock, struct sockaddr *addr, socklen_t *addrlen,
int timeout = OSS_SOCKET_DFT_TIMEOUT ) ;
//一下是几个辅助函数
/*当我们发送小包的时候。tcp会把几个小包组合成一个大包来发送。这个功能能够关闭*/
int disableNagle () ;//关闭打包发送特性,关闭tcp中的Nagle功能,小包的发送会更实时 unsigned int getPeerPort () ;
int getPeerAddress ( char *pAddress, unsigned int length ) ; unsigned int getLocalPort () ;
int getLocalAddress ( char *pAddress, unsigned int length ) ; int setTimeout ( int seconds ) ;//设置超时 static int getHostName ( char *pName, int nameLen ) ;//得到域名
static int getPort ( const char *pServiceName, unsigned short &port ) ;//把服务名转化为端口号。全部的服务都在/etc/server文件中面
int setAnsyn () ;
}; typedef class _ossSocket ossSocket ; #endif
下面是实现ossSockt.cpp
#include "ossSocket.hpp"
#include "pd.hpp" //创建一个监听的socket
_ossSocket::_ossSocket ( unsigned int port, int timeout )
{//设置监听套接字的各种属性
_init = false ;
_fd = 0 ;
_timeout = timeout ;
memset ( &_sockAddress, 0, sizeof(sockaddr_in) ) ;
memset ( &_peerAddress, 0, sizeof(sockaddr_in) ) ;
_peerAddressLen = sizeof(_peerAddress) ;
_addressLen = sizeof( _sockAddress ) ;
//监听套接字特有
_sockAddress.sin_family = AF_INET ;
_sockAddress.sin_addr.s_addr = htonl ( INADDR_ANY ) ;
_sockAddress.sin_port = htons ( port ) ; } // Create a socket
_ossSocket::_ossSocket ()
{
_init = false ;
_fd = 0 ;
_timeout = 0 ;
memset ( &_sockAddress, 0, sizeof(sockaddr_in) ) ;
memset ( &_peerAddress, 0, sizeof(sockaddr_in) ) ;
_peerAddressLen = sizeof(_peerAddress) ;
_addressLen = sizeof( _sockAddress ) ;
} // 创建一个client的套接字
//pHostname是对方机器的机器名(假设不是机器名就当做对方机器的ip地址)。port是对方机器的端口号
_ossSocket::_ossSocket ( const char *pHostname, unsigned int port, int timeout )
{
struct hostent *hp ;
_init = false ;
_timeout = timeout ;
_fd = 0 ;
memset ( &_sockAddress, 0, sizeof(sockaddr_in) ) ;
memset ( &_peerAddress, 0, sizeof(sockaddr_in) ) ;
_peerAddressLen = sizeof(_peerAddress) ;
_sockAddress.sin_family = AF_INET ;
if ( (hp = gethostbyname ( pHostname ) ) )//
_sockAddress.sin_addr.s_addr = *((int*)hp->h_addr_list[0] ) ;
else
_sockAddress.sin_addr.s_addr = inet_addr ( pHostname ) ;
_sockAddress.sin_port = htons ( port ) ;
_addressLen = sizeof(_sockAddress ) ;
} // 由已经得到的套接字来创建socket
_ossSocket::_ossSocket ( int *sock, int timeout )//SOCKET就是int类型
{
int rc = DIY_OK ;
_fd = *sock ;
_init = true ;
_timeout = timeout ;
_addressLen = sizeof( _sockAddress ) ;
memset ( &_peerAddress, 0, sizeof(sockaddr_in) ) ;
_peerAddressLen = sizeof(_peerAddress) ;
rc = getsockname ( _fd, (sockaddr*)&_sockAddress, &_addressLen ) ;//得到本地的ip地址
if ( rc )
{
//PD_LOG ( PDERROR, "Failed to get sock name, error = %d",
// SOCKET_GETLASTERROR ) ;
_init = false ;
}
else
{
rc = getpeername ( _fd, (sockaddr*)&_peerAddress, &_peerAddressLen ) ;//得到远端的ip地址
//PD_RC_CHECK ( rc, PDERROR, "Failed to get peer name, error = %d",
//SOCKET_GETLASTERROR ) ;
}
done :
return ;
error :
goto done ;
} int _ossSocket::initSocket ()
{
int rc = DIY_OK ;
if ( _init )
{
goto done ;
}
memset ( &_peerAddress, 0, sizeof(sockaddr_in) ) ;
_peerAddressLen = sizeof(_peerAddress) ;
_fd =socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ;//创建socket
if ( -1 == _fd )
{
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to initialize socket, error = %d",
// SOCKET_GETLASTERROR ) ;
goto error;
}
_init =true ;
// set timeout
setTimeout ( _timeout ) ;
done :
return rc ;
error :
goto done ;
} //设置SO_LINGER选项
int _ossSocket::setSocketLi ( int lOnOff, int linger )
{
int rc = DIY_OK ;
struct linger _linger ;
_linger.l_onoff = lOnOff ;
_linger.l_linger = linger ;
rc = setsockopt ( _fd, SOL_SOCKET, SO_LINGER,
(const char*)&_linger, sizeof(_linger) ) ;
return rc ;
} void _ossSocket::setAddress(const char *pHostname, unsigned int port )
{
struct hostent *hp ;
memset ( &_sockAddress, 0, sizeof(sockaddr_in ) ) ;
memset ( &_peerAddress, 0, sizeof(sockaddr_in) ) ;
_peerAddressLen = sizeof(_peerAddress) ;
_sockAddress.sin_family = AF_INET ;
if ( ( hp = gethostbyname ( pHostname )))
_sockAddress.sin_addr.s_addr = *((int*)hp->h_addr_list[0] ) ;
else
_sockAddress.sin_addr.s_addr = inet_addr ( pHostname ) ; _sockAddress.sin_port = htons ( port ) ;
_addressLen = sizeof(_sockAddress ) ;
} //监听端口
int _ossSocket::bind_listen ()
{
int rc = DIY_OK ;
int temp = 1 ;
rc = setsockopt ( _fd, SOL_SOCKET,
SO_REUSEADDR, (char*)&temp, sizeof(int) ) ;//SO_REUSEADDR确定这个端口能够反复使用
if ( rc )
{
//PD_LOG ( PDWARNING, "Failed to setsockopt SO_REUSEADDR, rc = %d",
// SOCKET_GETLASTERROR ) ;
goto error;
}
rc = setSocketLi ( 1, 30 ) ;
if ( rc )
{
//PD_LOG ( PDWARNING, "Failed to setsockopt SO_LINGER, rc = %d",
// SOCKET_GETLASTERROR ) ;
goto error;
}
rc = ::bind ( _fd, (struct sockaddr*)&_sockAddress, _addressLen ) ;
if ( rc )
{
//PD_RC_CHECK( DIY_NETWORK, PDERROR,
// "Failed to bind socket, rc = %d", SOCKET_GETLASTERROR ) ;
goto error;
}
rc = listen ( _fd, SOMAXCONN ) ;
if ( rc )
{
//PD_RC_CHECK( DIY_NETWORK, PDERROR,
// "Failed to listen socket, rc = %d", SOCKET_GETLASTERROR ) ;
goto error;
}
done :
return rc ;
error :
close () ;
goto done ;
} //发送函数
//发送函数也有超时timeout
int _ossSocket::send ( const char *pMsg, int len,
int timeout, int flags )
{
int rc = DIY_OK ;
int maxFD = _fd ;
struct timeval maxSelectTime ;
fd_set fds ; maxSelectTime.tv_sec = timeout / 1000000 ;
maxSelectTime.tv_usec = timeout % 1000000 ;
// if len == 0, then let's just return
if ( 0 == len )
{
return DIY_OK ;
}
//监測在时间范围类socket是否可写
while ( true )
{
FD_ZERO ( &fds ) ;
FD_SET ( _fd, &fds ) ;
rc = select ( (int)(maxFD + 1), NULL, &fds, NULL,
timeout>=0?&maxSelectTime:NULL ) ;
if ( 0 == rc )//rc=0表示超时
{
// timeout
rc = DIY_TIMEOUT ;//超时
goto done ;
}
// if < 0, something wrong
if ( 0 > rc )//rc<0表示有错误
{
rc = error ;
if ( EINTR == rc )//假设失败是由于收到中断,继续
{
continue ;
}
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to select from socket, rc = %d", rc ) ;
}
if ( FD_ISSET ( _fd, &fds ) )
{
break ;
}
} while ( len > 0 )
{
rc = ::send ( _fd, pMsg, len, MSG_NOSIGNAL | flags ) ;//禁止send()函数向系统发送异常消息,不收到sigpipe
if ( rc <= 0 )
{
if(rc<0&&errno==EINTR)
rc=0;//假设失败是由于中断。继续
else
{
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to send, rc = %d", SOCKET_GETLASTERROR ) ;
rc=-1;
goto error;
}
}
len -= rc ;
pMsg += rc ;
}
rc = DIY_OK ;
done :
return rc ;
error :
goto done ;
} bool _ossSocket::isConnected ()
{
int rc = DIY_OK ;
rc = ::send ( _fd, "", 0, MSG_NOSIGNAL ) ;//尝试发送一个零字节的信息
if ( 0 > rc )
return false ;
return true ;
} int _ossSocket::recv ( char *pMsg, int len,
int timeout, int flags )
{
int rc = DIY_OK ;
int retries = 0 ;
int maxFD = (int)_fd ;
struct timeval maxSelectTime ;
fd_set fds ; if ( 0 ==len )
return DIY_OK ;
maxSelectTime.tv_sec = timeout / 1000000 ;
maxSelectTime.tv_usec = timeout % 1000000 ;
while ( true )
{
FD_ZERO ( &fds ) ;
FD_SET ( _fd, &fds ) ;
rc = select ( maxFD+1, &fds, NULL, NULL,
timeout>=0? &maxSelectTime:NULL ) ;
// 0 means timeout
if ( 0 == rc )
{
rc = DIY_TIMEOUT ;
goto done ;
}
// if < 0 something wrong
if ( 0 > rc )
{
rc = error ;
if ( EINTR==rc )
{
continue ;
}
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to select from socket, rc = %d", rc ) ;
rc=DIY_NETWORK;
goto error;
}
if ( FD_ISSET ( _fd, &fds ) )
{
break ;
}
}
while ( len > 0 )
{
rc = ::recv ( _fd, pMsg, len, MSG_NOSIGNAL|flags ) ;
if ( rc > 0 )
{
if ( flags & MSG_PEEK )
{
goto done ;
}
len -= rc ;
pMsg += rc ;
}
else if ( rc == 0 )//网络关闭。收到fin
{
//PD_RC_CHECK ( DIY_NETWORK_CLOSE, PDWARNING,
// "Peer unexpected shutdown" ) ;
goto error;
}
else
{
rc = error ;
if ( EINTR == rc )
{
continue ;
}
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Recv() Failed: rc = %d", rc ) ;
goto error;
}
}
rc = DIY_OK ;
done :
return rc ;
error :
goto done ;
} int _ossSocket::recvNF ( char *pMsg, int &len,
int timeout )
{
int rc = DIY_OK ;
int retries = 0 ;
int maxFD = (int)_fd ;
struct timeval maxSelectTime ;
fd_set fds ; // if we don't expect to receive anything, no need to continue
if ( 0 == len )
return DIY_OK ; maxSelectTime.tv_sec = timeout / 1000000 ;
maxSelectTime.tv_usec = timeout % 1000000 ;
// wait loop until either we timeout or get a message
while ( true )
{
FD_ZERO ( &fds ) ;
FD_SET ( _fd, &fds ) ;
rc = select ( maxFD + 1, &fds, NULL, NULL,
timeout>=0? &maxSelectTime:NULL ) ; // 0 means timeout
if ( 0 == rc )
{
rc = DIY_TIMEOUT ;
goto done ;
}
// if < 0, means something wrong
if ( 0 > rc )
{
rc = error ;
// if we failed due to interrupt, let's continue
if ( EINTR == rc )
{
continue ;
}
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to select from socket, rc = %d", rc ) ;
goto error;
}
if ( FD_ISSET ( _fd, &fds ) )
{
break ;
}
}
rc = ::recv ( _fd, pMsg, len, MSG_NOSIGNAL ) ; if ( rc > 0 )
{
len = rc ;
}
else if ( rc == 0 )
{
//PD_RC_CHECK ( DIY_NETWORK_CLOSE, PDWARNING,
// "Peer unexpected shutdown" ) ;
goto error;
}
else
{
rc = error ;
goto error;
}
// Everything is fine when get here
rc = DIY_OK ;
done :
return rc ;
error :
goto done ;
} int _ossSocket::connect ()
{
int rc = DIY_OK ;
rc = ::connect ( _fd, (struct sockaddr *)&_sockAddress, _addressLen ) ;
if ( rc )
{
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to connect, rc = %d", SOCKET_GETLASTERROR ) ;
goto error;
}
rc = getsockname ( _fd, (sockaddr*)&_sockAddress, &_addressLen ) ;
if ( rc )
{
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to get local address, rc = %d", rc ) ;
goto error;
}
// get peer address
rc = getpeername ( _fd, (sockaddr*)&_peerAddress, &_peerAddressLen ) ;
if ( rc )
{
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to get peer address, rc = %d", rc ) ;
goto error;
}
done :
return rc ;
error :
goto done ;
} void _ossSocket::close ()
{
if ( _init )
{
int i = 0 ;
//i = ::closesocket ( _fd ) ;
i = ::close ( _fd ) ;
_init = false ;
}
} int _ossSocket::accept ( int *sock, struct sockaddr *addr, socklen_t *addrlen,
int timeout )
{
int rc = DIY_OK ;
int maxFD = (int)_fd ;
struct timeval maxSelectTime ; fd_set fds ;
maxSelectTime.tv_sec = timeout / 1000000 ;
maxSelectTime.tv_usec = timeout % 1000000 ;
while ( true )
{
FD_ZERO ( &fds ) ;
FD_SET ( _fd, &fds ) ;
rc = select ( maxFD + 1, &fds, NULL, NULL,
timeout>=0?&maxSelectTime:NULL ) ; // 0 means timeout
if ( 0 == rc )
{
*sock = 0 ;
rc = DIY_TIMEOUT ;
goto done ;
}
// if < 0, means something wrong
if ( 0 > rc )
{
rc = SOCKET_GETLASTERROR ;
// if we failed due to interrupt, let's continue
if ( EINTR == rc )
{
continue ;
}
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to select from socket, rc = %d",
// SOCKET_GETLASTERROR);
goto error;
} // if the socket we interested is not receiving anything, let's continue
if ( FD_ISSET ( _fd, &fds ) )
{
break ;
}
}
rc = DIY_OK ;
*sock = ::accept ( _fd, addr, addrlen );
if ( -1 == *sock )
{
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to accept socket, rc = %d",
// SOCKET_GETLASTERROR ) ;
goto error;
}
done :
return rc ;
error :
close () ;
goto done ;
} int _ossSocket::disableNagle ()
{
int rc = DIY_OK ;
int temp = 1 ;
rc = setsockopt ( _fd, IPPROTO_TCP, TCP_NODELAY, (char *) &temp,
sizeof ( int ) ) ;
if ( rc )
{
//PD_LOG ( PDWARNING, "Failed to setsockopt, rc = %d", SOCKET_GETLASTERROR ) ;
return rc;
} rc = setsockopt ( _fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &temp,
sizeof ( int ) ) ;
if ( rc )
{
//PD_LOG ( PDWARNING, "Failed to setsockopt, rc = %d", SOCKET_GETLASTERROR ) ;
return rc;
}
return rc ;
} unsigned int _ossSocket::_getPort ( sockaddr_in *addr )
{
return ntohs ( addr->sin_port ) ;
} int _ossSocket::_getAddress ( sockaddr_in *addr, char *pAddress, unsigned int length )
{
int rc = DIY_OK ;
length = length < NI_MAXHOST ? length : NI_MAXHOST ;
rc = getnameinfo ( (struct sockaddr *)addr, sizeof(sockaddr), pAddress,
length,
NULL, 0, NI_NUMERICHOST ) ;
if ( rc )
{
//PD_RC_CHECK ( DIY_NETWORK, PDERROR,
// "Failed to getnameinfo, rc = %d", SOCKET_GETLASTERROR ) ;
goto error;
}
done :
return rc ;
error :
goto done ;
} int _ossSocket::setAnsyn () //异步非堵塞
{
return fcntl(_fd, F_SETFL, O_NONBLOCK | fcntl(_fd, F_GETFL, 0));
} unsigned int _ossSocket::getLocalPort ()
{
return _getPort ( &_sockAddress ) ;
} unsigned int _ossSocket::getPeerPort ()
{
return _getPort ( &_peerAddress ) ;
} int _ossSocket::getLocalAddress ( char * pAddress, unsigned int length )
{
return _getAddress ( &_sockAddress, pAddress, length ) ;
} int _ossSocket::getPeerAddress ( char * pAddress, unsigned int length )
{
return _getAddress ( &_peerAddress, pAddress, length ) ;
} int _ossSocket::setTimeout ( int seconds )
{
int rc = DIY_OK ;
struct timeval tv ;
tv.tv_sec = seconds ;
tv.tv_usec = 0 ;
// windows take milliseconds as parameter
// but linux takes timeval as input rc = setsockopt ( _fd, SOL_SOCKET, SO_RCVTIMEO, ( char* ) &tv,
sizeof ( tv ) ) ;
if ( rc )
{
//PD_LOG ( PDWARNING, "Failed to setsockopt, rc = %d",
// SOCKET_GETLASTERROR ) ;
return rc;
} rc = setsockopt ( _fd, SOL_SOCKET, SO_SNDTIMEO, ( char* ) &tv,
sizeof ( tv ) ) ;
if ( rc )
{
//PD_LOG ( PDWARNING, "Failed to setsockopt, rc = %d",
// SOCKET_GETLASTERROR ) ;
return rc;
} return rc ;
} int _ossSocket::getHostName ( char *pName, int nameLen )
{
return gethostname ( pName, nameLen ) ;
} int _ossSocket::getPort ( const char *pServiceName, unsigned short &port )
{
int rc = DIY_OK ;
struct servent *servinfo ;
servinfo = getservbyname ( pServiceName, "tcp" ) ;
if ( !servinfo )
port = atoi ( pServiceName ) ;
else
port = (unsigned short)ntohs(servinfo->s_port) ;
return rc ;
}
diy数据库(二)--网络通信类的更多相关文章
- django模型——数据库(二)
模型--数据库(二) 实验简介 模型的一些基本操作,save方法用于把对象写入到数据库,objects是模型的管理器,可以使用它的delete.filter.all.order_by和update等函 ...
- 第三百零七节,Django框架,models.py模块,数据库操作——表类容的增删改查
Django框架,models.py模块,数据库操作——表类容的增删改查 增加数据 create()方法,增加数据 save()方法,写入数据 第一种方式 表类名称(字段=值) 需要save()方法, ...
- 学习实践:使用模式,原则实现一个C++数据库訪问类
一.概述 在我參与的多个项目中.大家使用libMySQL操作MySQL数据库,并且是源代码级复用,在多个项目中同样或相似的源代码.这种复用方式给开发带来了不便. libMySQL的使用比較麻烦.非常e ...
- 五 Django框架,models.py模块,数据库操作——表类容的增删改查
Django框架,models.py模块,数据库操作——表类容的增删改查 增加数据 create()方法,增加数据 save()方法,写入数据 第一种方式 表类名称(字段=值) 需要save()方法, ...
- Sql数据库帮组类
这段时间闲下来写了一些东西,重新写了一个简单的数据库帮组类 public class MyDBHelper { public static readonly string connString = C ...
- ACCESS数据库C#操作类(包含事务)
转自http://blog.csdn.net/allen3010/article/details/6336717 这个是针对ACCESS数据库操作的类,同样也是从SQLHELPER提取而来,分页程序的 ...
- UML学习(二)-----类图
UML学习(二)-----类图 http://www.cnblogs.com/silent2012/archive/2011/09/07/2169946.html http://www.cnblogs ...
- 常用数据库的驱动类/URL/默认端口
常用数据库的驱动类/URL/默认端口 1.Oracle: 格式: 驱动:oracle.jdbc.driver.OracleDriver URL:jdbc:oracle:thin ...
- android中与SQLite数据库相关的类
为什么要在应用程序中使用数据库?数据库最主要的用途就是作为数据的存储容器,另外,由于可以很方便的将应用程序中的数据结构(比如C语言中的结构体)转化成数据库的表,这样我们就可以通过操作数据库来替代写一堆 ...
- 【转载】微软官方提供的Sqlserver数据库操作帮助类SQLHelper类
在.NET平台中,C#语言一般使用ADO.NET组件来操作Sqlserver数据库,通过ADO.NET组件可以实现连接数据库.查询数据集.执行SQL语句以及关闭数据库连接等操作,为此网上有很多开发者自 ...
随机推荐
- 【转】Quartz.NET
原文链接:http://www.cnblogs.com/tommyli/archive/2009/02/09/1386644.html Quartz.NET是一个开源的作业调度框架,是OpenSymp ...
- notepad++编辑器写python需注意使用utf-8编码
语言:python3.4 文本编辑器:notepad++ 报错:SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xb4 in ...
- NLS_LANG在客户端不能确定,字符集转变将造成不可预期的后果
原因:1,没有客服端配置字符集2,客户端字符集跟服务端字符集不一致 解决:1,打开plsql 帮助-支持信息看看uls_lang是否设置 2,查看服务器端字符集 Select *from V$NLS_ ...
- python request包使用指西
request是Python的一个网络模块包,使用它可以快速写一些强大的爬虫脚本
- POJ1450:Gridland 【杂题】
题目大意:先给出了TSP的背景,然后给出一个n*m的单位格点的图,图中除边缘上的点与八个方向的点有边连接,距离为欧拉距离,求从左上角出发的TSP 思路:从水题列表中看到的题,但看一开始给出的backg ...
- 多边形之战(bzoj 2927)
Description 多边形之战是一个双人游戏.游戏在一个有n个顶点的凸多边形上进行,这个凸多边形的n-3条对角线将多边形分成n-2个三角形,这n-3条对角线在多边形的顶点相交.三角形中的一个被染成 ...
- excludepathpatterns 无效
踩坑了,调了好久才调出来. 原因: 访问的API /XXX 已经转换为 /error 了. 把“/error” 也加入 excludepathpatterns 里面即可.
- POJ 2438 哈密顿回路
Children's Dining Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4730 Accepted: 754 ...
- c++ 实现 key-value缓存数据结构
c++ 实现 key-value缓存数据结构 概述 最近在阅读Memcached的源代码,今天借鉴部分设计思想简单的实现了一个keyvalue缓存. 哈希表部分使用了unordered_map,用于实 ...
- Java面试题总结之JDBC 和Hibernate
1.100 用户同时来访数据库,要采取什么技术? 答:采用数据库连接池. 2.什么是ORM? 答:对象关系映射(Object—Relational Mapping,简称ORM)是一种为了解决面向对象与 ...