首先在MyEclipse中配置好数据源并打开。
选择需要生成pojo的表。
在右键菜单中选择 Hibernate Reverse Engineering,按下面的步骤进行设置。
生成pojo和dao之后,可以移动到相关的包。在DAO类中可以通过重构,将方法提取到DAO接口。
注意:如果表中没有主键,则会生成一个额外的类,并使用全部字段作为联合主键。
在使用ODBC连接数据库时,会出现如下问题:
1. 如果为Any CPU或者X64平台,则出现:The specified DSN contains an architecture mismatch between the Driver and Application
查阅资料,使用Wow64下的ODBCAD32.exe来添加系统DSN可解决问题,但实践下来无任何效果
2.如果为x86平台,则会出现:找不到数据源或者驱动程序
在使用JET OLEDB连接数据库时,出现问题如何解决:
1. 连接带有密码的ACCESS数据库时出现“无法启动应用程序。工作组信息文件丢失,或是已被其它用户以独占方式打开”的解决方法:
此问题是由数据库的连接串引起的,可用下面的串连接即可
"Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=true;Data Source=E:\data1.mdb;Jet OLEDB:Database Password=1111 "
2. The 'Microsoft.Jet.OLEDB.4.0' provider is not registered on the local machine
未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。
将系统编译目标改为X86即可,原因是未安装64bit的JET OLEDB驱动程序
需要注意的是,系统ODBC数据源保存在 HKLM\Software\Wow6432Node\ODBC\ODBC.INI\ODBC Data Sources键下
using System;
using System.Collections.Generic;
using System.Text;
namespace TncsConfig
{
/// <summary>
/// The types of data sources that can be set.
/// </summary>
public enum DataSourceType { System, User }
/// <summary>
/// Provides methods and tools to manage the Odbc data sources on the machine.
/// </summary>
public class OdbcDataSourceManager
{
// Returns a list of data source names from the local machine.
public System.Collections.SortedList GetAllDataSourceNames()
{
// Get the list of user DSN's first.
System.Collections.SortedList dsnList = GetUserDataSourceNames();
// Get list of System DSN's and add them to the first list.
System.Collections.SortedList systemDsnList = GetSystemDataSourceNames();
for (int i = 0; i < systemDsnList.Count; i++)
{
string sName = systemDsnList.GetKey(i) as string;
DataSourceType type = (DataSourceType)systemDsnList.GetByIndex(i);
try
{
// This dsn to the master list
dsnList.Add(sName, type);
}
catch
{
// An exception can be thrown if the key being added is a duplicate so
// we just catch it here and have to ignore it.
}
}
return dsnList;
}
/// <summary>
/// Gets all System data source names for the local machine.
/// </summary>
public System.Collections.SortedList GetSystemDataSourceNames()
{
System.Collections.SortedList dsnList = new System.Collections.SortedList();
// get system dsn's
Microsoft.Win32.RegistryKey reg = (Microsoft.Win32.Registry.LocalMachine).OpenSubKey("Software");
if (reg != null)
{
reg = reg.OpenSubKey("ODBC");
if (reg != null)
{
reg = reg.OpenSubKey("ODBC.INI");
if (reg != null)
{
reg = reg.OpenSubKey("ODBC Data Sources");
if (reg != null)
{
// Get all DSN entries defined in DSN_LOC_IN_REGISTRY.
foreach (string sName in reg.GetValueNames())
{
dsnList.Add(sName, DataSourceType.System);
}
}
try
{
reg.Close();
}
catch { /* ignore this exception if we couldn't close */ }
}
}
}
reg = (Microsoft.Win32.Registry.LocalMachine).OpenSubKey("Software");
if(reg!=null){
reg = reg.OpenSubKey("Wow6432Node");
if(reg!=null){
reg = reg.OpenSubKey("ODBC");
if (reg != null)
{
reg = reg.OpenSubKey("ODBC.INI");
if (reg != null)
{
reg = reg.OpenSubKey("ODBC Data Sources");
if (reg != null)
{
// Get all DSN entries defined in DSN_LOC_IN_REGISTRY.
foreach (string sName in reg.GetValueNames())
{
dsnList.Add(sName, DataSourceType.System);
}
}
try
{
reg.Close();
}
catch { /* ignore this exception if we couldn't close */ }
}
}
}
}
return dsnList;
}
/// <summary>
/// Gets all User data source names for the local machine.
/// </summary>
public System.Collections.SortedList GetUserDataSourceNames()
{
System.Collections.SortedList dsnList = new System.Collections.SortedList();
// get user dsn's
Microsoft.Win32.RegistryKey reg = (Microsoft.Win32.Registry.CurrentUser).OpenSubKey("Software");
if (reg != null)
{
reg = reg.OpenSubKey("ODBC");
if (reg != null)
{
reg = reg.OpenSubKey("ODBC.INI");
if (reg != null)
{
reg = reg.OpenSubKey("ODBC Data Sources");
if (reg != null)
{
// Get all DSN entries defined in DSN_LOC_IN_REGISTRY.
foreach (string sName in reg.GetValueNames())
{
dsnList.Add(sName, DataSourceType.User);
}
}
try
{
reg.Close();
}
catch { /* ignore this exception if we couldn't close */ }
}
}
}
return dsnList;
}
}
}
update student,statistic set student.score1=statistic.score1 where student.paperid=statistic.paperid and student.score1 is NULL
BEGIN
DECLARE studentName,iip VARCHAR(16);
DECLARE iContestId,LoginFlag,iPaperId,iMinutes INT;
DECLARE stime datetime;
DECLARE ntime datetime DEFAULT NOW();
DECLARE bGameOver bit;
select starttime,minutes into stime,iMinutes from contests where current=1;
if stime-ntime>300 THEN
SELECT '离考试开始时间超过5分钟,不允许用户登录!' as msg;
else
select stuname,contests.testid,student.login,student.starttime,paperid,gameover,ipadd into studentName,iContestId,LoginFlag,stime,iPaperId,bGameOver,iip from student,contests where student.stuid=studentid and student.password=passwd and student.contestid=contests.testid and contests.current=1;
if (iContestId is null) THEN
select '用户不存在或者密码错误!' as msg;
ELSEIF bGameOver THEN
SELECT '您已结束考试,不能再次进入考试!' as msg;
ELSEIF LoginFlag=1 and ip<>iip THEN
SELECT '用户已经登录考试,不能重复登录!' as msg;
ELSEIF iPaperId is null THEN
SELECT '试卷不存在!' as msg;
ELSEIF stime is null THEN
#改变用户登录标志为已登录
#记录该用户的考试开始时间
update student set login=1,starttime=ntime,ipadd=ip where student.stuid=studentid and contestid=iContestId;
#返回登录成功信息,学生姓名,考试编号,试卷编号,考试开始时间,考试时长等信息
select 'success' as msg,studentName as sname,iContestId as testid,iPaperId as paperid,ntime as starttime,iMinutes as minutes;
ELSE
#改变用户登录标志为已登录
#考生换机,扣除已使用时间,开始考试时间不变
update student set login=1,ipadd=ip where student.stuid=studentid and contestid=iContestId;
#返回登录成功信息,学生姓名,考试编号,试卷编号,考试开始时间,剩余考试时长等信息
select 'success' as msg,studentName as sname,iContestId as testid,iPaperId as paperid,stime as starttime,iMinutes as minutes;
END IF;
END IF;
END
小插曲:
一开始的时候存储过程写错了,红色部分写成了student.stuid=stuid ,结果记录的总是最后一个人的登录IP和登录时间,然后当用户重新登录时,因为IP不一样,总是登录不到考试系统中去
1、必须给数据库用户super权限,否则无法执行存储过程。用root用户创建的存储过程,其他用户在调用时必须在数据库url上加上参数,比较完整的url如下:
jdbc:mysql://10.28.79.2:3306/cbbt?noAccessToProcedureBodies=true
2、在存储过程中的select中使用in子句,以及select返回多条记录的时候的处理方法
BEGIN
DEClare qid,qtype,qscore int;
DECLARE stopFlag int DEFAULT 0;
DECLARE qtitle,qoa,qob,qoc,qod,qans varchar(1000);
DECLARE qnum int DEFAULT 1;
#定义游标
DECLARE Que_ResultSet CURSOR FOR select tid,title,optiona,optionb,optionc,optiond,type,answer,score,type from problems WHERE FIND_IN_SET(tid,ids) ORDER BY tid;
DECLARE CONTINUE HANDLER FOR NOT FOUND set stopFlag=1;
set stopFlag=0;
OPEN Que_ResultSet;
REPEAT
FETCH Que_ResultSet INTO qid,qtitle,qoa,qob,qoc,qod,qtype,qans,qscore,qtype;
IF NOT stopFlag then #没有这行的话,最后一条记录会重复两次
BEGIN
if qtype=1 or qtype=2 THEN
insert into panswer(paperid,problemid,answer,score,type) values(pid,qnum,qans,qscore,qtype);
ELSE
insert into panswer(paperid,problemid,answer,score,type) values(pid,qnum,qoa,qscore,qtype);
end IF;
set qnum=qnum+1;
END;
end if;
UNTIL stopFlag = 1 END REPEAT;
CLOSE Que_ResultSet;
select tid,title,optiona,optionb,optionc,optiond,type from problems WHERE FIND_IN_SET(tid,ids) ORDER BY tid;
END
有参数的情况
CallableStatement cstmt=conn.prepareCall("{call hasContest(?)}");
cstmt.registerOutParameter(1, Types.BOOLEAN);
cstmt.execute();
boolean b=cstmt.getBoolean(1);
无参数的情况
CallableStatement cstmt=conn.prepareCall("{call hasContest}");
ResultSet rs=cstmt.executeQuery();
rs.next();
return rs.getBoolean(1);
给定的数据库用户必须具有执行的权限,同时在数据的url中要添加参数,如下所示
jdbc:mysql://10.28.79.2:3306/cbbt?noAccessToProcedureBodies=true
DataTable dt = new DataTable();
string sql = String.Format("select [msgid],[teacher],[msgdate] from inbox where [msgdate] like '{0}%' and [userid]='{1}'", date, username);
OleDbDataAdapter da = new OleDbDataAdapter(sql, cn);
da.Fill(dt);
dgvInbox.DataSource = dt;
遇到了这个问题,解决的方法:
1、把原有的数据库文件备份,安装时不要指定原来的数据库数据目录。待安装完成后再附加数据库
2、再次安装时会遇到“以前进行的程序创建了挂起的文件操作,运行安装程序前,必须重新启动 ”,其实可以不重启动的:
和mysql connector/c++相比,只要在开始时设置好字符集,之后不需要进行转码操作。
conn.set_option(new mysqlpp::SetCharsetNameOption("gbk"));
//查询方法1
vector<mysqlpp::Row> v;
query.storein(v);
cout.setf(ios::left);
cout<<setw(10)<<"username"<<setw(10)<<"password"<<endl;
for (vector<mysqlpp::Row>::iterator it = v.begin(); it != v.end(); ++it) {
cout<<setw(10)<<it->at(0)<<setw(10)<<it->at(1)<< endl;
}
//查询方法2
mysqlpp::StoreQueryResult res = query.store();
if(res){
cout.setf(ios::left);
cout<<setw(10)<<"username"<<setw(10)<<"password"<<endl;
for (size_t i = 0; i < res.num_rows(); ++i)
cout << setw(10) << res[i]["username"] << setw(10) << res[i]["password"] << endl;
}else {
cerr << "Failed to get stock table: " << query.error() << endl;
return 1;
}
//修改记录
query<<"update users set password='hello' where username='沈健'";
query.execute();
//插入
query<<"insert into users(username,password) values('飞翔','123456')";
query.execute();
//删除记录
query<<"delete from users where username='遨游'";
query.execute();
//查询
result = stmt->executeQuery("select * from users");
while(result->next())
{
string username = result->getString("username");
string password = result->getString("password");
cout << utf2ansi(username) << " : " << password << endl;
}
//插入
string sql="insert into users(username,password) values('" + ansi2utf8(string("飞翔"))+ "','asdfgh')";
stmt->executeUpdate(sql);
//删除
sql="delete from users where id=4";
stmt->executeUpdate(sql);
//修改
sql="update users set password='hello' where username='" + ansi2utf8(string("沈健")) +"'";;
stmt->executeUpdate(sql);
查出来的数据需要转换成ANSI编码,传给mysql服务器的数据需要转换为unicode编码(mysql数据库中所建的数据库、表和字段采用utf-8编码)
下面是相应的转换函数
//将标准string(unicode)转换为string(ansi)
string utf2ansi(const string &src){
int nLen = MultiByteToWideChar( CP_UTF8, 0, src.data(), -1, NULL, NULL );
LPWSTR lpwsz = new WCHAR[nLen];
MultiByteToWideChar( CP_UTF8, 0, src.data(), -1, lpwsz, nLen );
int nLen1 = WideCharToMultiByte( CP_ACP, 0, lpwsz, nLen, NULL, NULL, NULL, NULL );
LPSTR lpsz = new CHAR[nLen1];
WideCharToMultiByte( CP_ACP, 0, lpwsz, nLen, lpsz, nLen1, NULL, NULL );
string str(lpsz);
delete []lpsz;
return str;
}
//将标准string(ansi)转换为string(unicode)
string ansi2utf8(const string &src){
int nLen = MultiByteToWideChar( CP_ACP, 0, src.data(), -1, NULL, NULL );
LPWSTR lpwsz = new WCHAR[nLen];
MultiByteToWideChar( CP_ACP, 0, src.data(), -1, lpwsz, nLen );
int nLen1 = WideCharToMultiByte( CP_UTF8, 0, lpwsz, nLen, NULL, NULL, NULL, NULL );
LPSTR lpsz = new CHAR[nLen1];
WideCharToMultiByte( CP_UTF8, 0, lpwsz, nLen, lpsz, nLen1, NULL, NULL );
string str(lpsz);
delete []lpsz;
return str;
}
1、环境准备
下载mysql connector/c++并解压
2、在项目设置中
(1)项目属性,配置属性,C/C++,常规,附加包含目录:将第一步解压出来的目录中的include和include/cppconn添加进去
(2)项目属性,配置属性,链接器,输入,附加依赖项:mysqlcppconn.lib mysqlcppconn-static.lib libmysql.lib
(3)项目属性,配置属性,链接器,常规,附加库目录:将第一步解压出来的目录中的lib目录添加进去
(4)编译项目
(5)运行时,需要将mysqlcppconn.dll libmysql.dll复制到生成可执行文件的目录下
1、mysql++的准备
从http://tangentsoft.net/mysql++/releases/mysql++-3.0.9.tar.gz下载源代码,解压缩后,用VS2008打开VS2008文件夹中的解决方案文件(sln),注意此时要用到mysql的include目录和libmysql.lib,如果你在本机上安装了mysql数据库,则可以从安装目录中找到,将include和libmysql.lib添加到项目的额外的包含文件目录和库文件目录中,并在链接选项的输入中键入 libmysql.lib。如果不想安装mysql服务器,也可以下载mysql connector C driver,其中也包含了相应的文件。
设置好之后编译mysql++,如果无误。双击运行其中的install.hta完成安装过程。
2、使用mysql++的项目的相关设置
(1)添加额外的包含文件目录:
(2)添加额外的库文件目录,并将 libmysql.lib mysqlpp_d.lib 加入到 链接器|输入|附加依赖项中
(3)编译代码
(4)运行时要将libmysql.dll和mysqlpp_d.dll放到生成的可执行文件的文件夹下
#include <iostream>
#include <iomanip>
#include <mysql++.h>
#include <stdio.h>
#include <Windows.h>
using namespace std;
using namespace mysqlpp;
int main(){
//在取得连接之前首先设置字符编码
mysqlpp::Connection conn(false);
conn.set_option(new mysqlpp::SetCharsetNameOption("GBK"));
conn.connect("mydb","127.0.0.1","user","password",3306);
mysqlpp::Query query=conn.query();
vector<mysqlpp::Row> v;
query<<"select * from nations";
query.storein(v);
cout.setf(ios::left);
cout<<setw(10)<<"Nation"<<setw(10)<<"Notation"<<endl;
for (vector<mysqlpp::Row>::iterator it = v.begin(); it != v.end(); ++it) {
cout<<setw(10)<<it->at(0)<<setw(10)<<it->at(1)<< endl;
}
getchar();
return 0;
}
#include <iomanip>
#include <mysql_connection.h>
#include <mysql_driver.h>
#include <cppconn/driver.h>
#include <cppconn/statement.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
using namespace std;
void RunConnectMySQL()
{
try{
//sql::Driver *driver;
sql::mysql::MySQL_Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *result;
//driver = get_driver_instance();
driver=sql::mysql::get_mysql_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "user", "password");
stmt = con->createStatement();
stmt->execute("use doclibexp");
result = stmt->executeQuery("select * from nations");
while(result->next())
{
string nation = result->getString("Nation");
string notation = result->getString("Notation");
cout << nation << " : " << notation << endl;
}
delete stmt;
delete con;
}catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
}
int main(int argc, char **argv)
{
RunConnectMySQL();
getchar();
return 0;
}