Mysql++学习(五)------专用SQL结构

专用SQL结构(SSQLS) 特性可以让你很轻易的定义用来匹配SQL表的C++结构.最通俗的理解:对于SQL表中的每一个字段,SSQLS结构都有一个变量与之对应.但是,MySQL++内部也会使用SSQLS的其他方法,操作符来提供简洁的功能.

要定义SSQLSes,需要使用定义在ssqls.h中的宏,这也是MySQL++唯一没有自动加入mysql++.h的头文件.

sql_create

假如你有如下SQL表

CREATE TABLE stock (
    item CHAR(30) NOT NULL,
    num BIGINT NOT NULL,
    weight DOUBLE NOT NULL,
    price DECIMAL(6,2) NOT NULL,
    sdate DATE NOT NULL,
    description MEDIUMTEXT NULL)

你可以定义一个对应的C++结构如下

sql_create_6(stock, 1, 6,
    mysqlpp::sql_char, item,
    mysqlpp::sql_bigint, num,
    mysqlpp::sql_double, weight,
    mysqlpp::sql_decimal, price,
    mysqlpp::sql_date, sdate,
    mysqlpp::Null<mysqlpp::sql_mediumtext>, description)

stock结构声明有着相同名字的数据成员对应SQL的每一列,同时该结构还包含一些成员函数,操作符以及隐藏数据成员.

sql_create_# call调用中,字段名称前面的是C++数据类型.

有时候你必须使用MySQL++的特殊数据类型来对应数据结构,考虑description字段的类型,MySQL++的 sql_mediumtext类型就是std::string的一个等价.

通常结构如下:

sql_create_#(NAME, COMPCOUNT, SETCOUNT, TYPE1, ITEM1, ... TYPE#, ITEM#)

“#”是变量的数量,“NAME”是你希望创建的结构名称,“TYPEx”是变量类型,“ITEMx”是变量名称.

SSQLS对比和初始化

sql_create_#添加了一些成员函数和操作来支持SSQLS对象之间的比较,COMPCOUNT数量表示用来比较的字段的个数,上面例子中为1,意味着只比较item字段,将主键放到最前面并且指定比较个数,可以很好利用这一特性.sql_create_#创建的第二个参数是SETCOUNT,如果非0,它将增加一个构建函数和一个set()成员函数,该函数接受指定参数来设置结构第N个字段的值.

sql_create_6(stock, 1, 2,
    mysqlpp::sql_char, item,
    mysqlpp::sql_bigint, num,
    mysqlpp::sql_double, weight,
    mysqlpp::sql_decimal, price,
    mysqlpp::sql_date, sdate,
    mysqlpp::Null<mysqlpp::sql_mediumtext>, description)

stock foo("Hotdog", 52);

COMPCOUNT 和SETCOUNT 的值不可以相等,如果相等,会导致产生参数列表相同的两个构建函数.

查询数据

mysqlpp::Query query = conn.query("select item, description from stock");
vector<stock> res;
query.storein(res);

for(auto i = res.begin(); i != res.end(); i++)
{
    cout << i->item << ‘\t‘ ;
    cout << i->description << endl;
}

在定义了SSQLS结构后,可以直接将查询结构放入相应容器,进行各种操作.

增加数据

//create a stock object
stock new_row(
         "Hot dog", 100, 1.5, 130, mysqlpp::sql_date("2014-11-30"), mysqlpp::null
     );
//execute a query
mysqlpp::Query query = conn.query();
query.insert(new_row);

cout << "Query: " << query << endl;
query.execute();

首先,创建一个要插入的SSQLS对象,然后,创建查询对象,最后执行

批量插入也很容易,只要加一个循环即可

vector<stock> lots_of_stuff;
...populate the vector somehow...
query.insert(lots_of_stuff.begin(), lots_of_stuff.end()).execute();

MySQL对于SQL查询长度有所限制,默认最大为1M.因此,使用insert批量插入时,容器中的查询长度可能超过限制.

在这种情况下使用Query::insertfrom(),它是INSERT和execute()的组合.

mysqlpp::Query::MaxPacketInsertPolicy<> insert_policy(1000);
query.insertfrom(stock_vector.begin(), stock_vector.end(),
insert_policy);

它采用最大包策略,该例中指定一个查询最大为1000,它会自动检测查询是否超过限制,然后分割执行查询.

还有两个策略类:MaxPacketInsertPolicy和RowCountInsertPolicy,它们都提供了在查询长度在一定范围类的策略方法,如果不适用,也可以研究下lib/insertpolicy.*,然后自己写策略类.策略类本质都是些类模板.

修改数据

//execute a query
mysqlpp::Query query = conn.query("select * from stock ");
query << "where item = " << mysqlpp::quote << "abc";
//get query result in a storeResult
mysqlpp::StoreQueryResult res = query.store();
if(res)
{
        stock row = res[0];
        stock orig_row = row;
        row.item = "hamburger";
        query.update(orig_row, row);
        cout << "Query : " << query <<endl;
        query.execute();
}

首先取出要修改的记录,然后修改相应字段,再用新字段代替原字段,执行替换操作.

用关联容器来存放SSQLS

//execute a query
mysqlpp::Query query = conn.query("select * from stock ");
//get query result in a storeResult
set<stock> res;
query.storein(res);
if(res.size())
{
       for(auto i = res.begin(); i != res.end(); ++i)
       {
            cout << i->item.c_str() << ‘\t‘ << i->num << ‘\t‘ << i->price << endl;
       }
}

改变表名

默认情况下,数据库表和SSQLS结构拥有相同的表名称.你也可以用如下方法全局修改查询中使用的表名.

stock::table("MyStockData");

也可以修改每个实例中的表名

stock s;
s.instance_table("AlternateTable");

在多个模块中使用SSQLS

// File my_ssqls.h:
#if !defined(EXPAND_MY_SSQLS_STATICS)
#   define MYSQLPP_SSQLS_NO_STATICS
#endif
sql_create_X(Y, Z....) // the SSQLS definition
// File foo.cpp, a mere user of the SSQLS:
#include "my_ssqls.h"
// File my_ssqls.cpp, which owns the SSQLS:
#define EXPAND_MY_SSQLS_STATICS
#include "my_ssqls.h"

利用SSQLS的内部构件

sql_create宏为每个SSQLS定义了一些有用的方法,这些方法大多用于库内部,以下伪码展示了一些用法.

// Basic form
template <class Manip>
stock_value_list<Manip> value_list(cchar *d = ",",
  Manip m = mysqlpp::quote) const;  

template <class Manip>
stock_field_list<Manip> field_list(cchar *d = ",",
  Manip m = mysqlpp::do_nothing) const;  

template <class Manip>
stock_equal_list<Manip> equal_list(cchar *d = ",",
  cchar *e = " = ", Manip m = mysqlpp::quote) const;  

// Boolean argument form
template <class Manip>
stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,] ]
  bool i1, bool i2 = false, ... , bool i5 = false) const;  

// List form
template <class Manip>
stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,] ]
  stock_enum i1, stock_enum i2 = stock_NULL, ...,
  stock_enum i5 = stock_NULL) const;  

// Vector form
template <class Manip>
stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,] ]
  vector<bool> *i) const;  

...Plus the obvious equivalents for field_list() and equal_list()

下面例子演示通过查询的一条记录来构建一个查询

在C++和SQL中使用不同的字段名称

sql_create_complete_5(stock, 1, 5,
    mysqlpp::sql_char, m_sItem, "item",
    mysqlpp::sql_bigint, m_nNum, "num",
    mysqlpp::sql_double, m_fWeight, "weight",
    mysqlpp::sql_decimal, m_fPrice, "price",
    mysqlpp::sql_date, m_Date, "sdate")

继承自一个SSQLS

sql_create_2(
  Base, 1, 2,
  mysqlpp::sql_varchar, a,
  mysqlpp::sql_int, b
);

class Derived : public Base
{
public:
  // default constructor[14]
  Derived() :
  Base()
  {
  }

  // for-comparison constructor[15]
  Derived(const mysqlpp::sql_varchar& _a) :
  Base(_a)
  {
  }

  // full creation constructor
  Derived(const mysqlpp::sql_varchar& _a, const mysqlpp::sql_int& _b) :
  Base(_a, _b)
  {
  }

  // population constructor[16]
  Derived(const mysqlpp::Row& row) :
  Base(row)
  {
  }

  // functionality added to the SSQLS through inheritance
  bool do_something_interesting(int data);
};
时间: 2024-11-05 22:31:33

Mysql++学习(五)------专用SQL结构的相关文章

mysql学习之四:sql语句学习2

创建数据库: CREATE DATABASE stefan; 删除数据库: DROP DATABASE stefan; 重命名数据库: 重命名数据库没有直接的办法. 已经不再使用的方法: RENAME DATABASE stefan TO LCDB; 创建表格语法: CREATE TABLE 表名称 ( 列名称1 数据类型, 列名称2 数据类型, 列名称3 数据类型, .... )   查看一个表格结构: DESCRIBE Persons;     ALTER TABLE 语句用于在已有的表中添

mysql学习之五:sql语句学习3

好吧,大家觉得这种字体还是比较好看,所有我们就换这种字体了. INSERT INTO 语句用于向表格中插入新的行. 语法 INSERT INTO 表名称 VALUES (值1, 值2,....) 我们也可以指定所要插入数据的列: INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....) Update 语句用于修改表中的数据. 语法: UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 DELETE 语句用于删除表中

mysql学习之三:sql语句学习

SQL 是一门 ANSI 的标准计算机语言,用来访问和操作数据库系统.SQL 语句用于取回和更新数据库中的数据.SQL 可与数据库程序协同工作,比如MySQL. MS Access.DB2.Informix.MS SQL Server.Oracle.Sybase 以及其他数据库系统. 不幸地是,存在着很多不同版本的 SQL 语言,但是为了与 ANSI 标准相兼容,它们必须以相似的方式共同地来支持一些主要的关键词(比如 SELECT.UPDATE.DELETE.INSERT.WHERE 等等).

【MySQL学习】-- 0x02 .sql 文件导入及编码问题解决

买了本sql必知必会,从官网down了个例子,然而不清楚怎么导入,里面的readme写的是用workbench,然而把我坑了,官网没有centos的发行版本了.最后百度好久才偶然发现,那边给的txt文件是可以导入的. 在mysql中用source create.sql即可 然而还有个问题 ascii '\0' apperared in the statement... more查看是不能显示,发现是编码问题.直接用notepad++改了下编码就好了. use Sales; source crea

MySQL 学习五 SQL实用函数

0 select now() 显示当前时间. 1 select char_length('andyqan')   显示字符长度. 2 日期格式化         select date_format(now(), '%y-%m-%d') 3 添加/减少日期时间         select date_add(now(), interval 1 day) 4 类型转换       select cast(187000000  as char) 5 加密函数 MD5是不可逆的,也就是不可破解的. 但

MySql学习(五) —— 数据库优化理论篇(一)

一.数据库管理系统 数据库管理系统(Database Management System, DBMS) 衡量是否是数据库的标准: ACID:是指在数据库管理系统(DBMS)中事务所具有的四个特性: 1) 原子性(Atomicity) 2) 一致性(Consistency) 3)隔离性(Isolation) 4)持久性(Durability) 1.关系型数据库:是建立在关系数据库模型基础上的数据库,借助于关系代数等概念和方法来处理数据库中的数据,同时也是一个被组织成一组拥有正式描述性的表格,该形式

【MySQL学习】-- 0x03 .sql 创建用户及其对应数据库

------创建数据库(略)------------ ---------创建用户mysql5.6以上用insert创建用户是有问题的--------- GRANT USAGE ON *.* TO 'user01'@'localhost' IDENTIFIED BY '123456' WITH GRANT OPTION; -----------授权------------- ----这里我创建了个Library数据库给user01----------- grant all privileges o

我的MYSQL学习心得(五)

我的MYSQL学习心得(五) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) MYSQL中的运算符很多,这一节主要讲MYSQL中有的,而SQLSERVER没有的运算符 安全等于运算符(<=>) 这个操作符和=操作符执行相同的比较操作,不过<=>可以用来判断NULL值. 在两个操作数均为NULL时,其返回值为1而不为NULL: 而当一个操作数为NULL时,其返回值为0而不为NULL. 下面分别是 SELECT N

我的MYSQL学习心得(十五)

我的MYSQL学习心得(十五) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL学习心得(五) 我的MYSQL学习心得(六) 我的MYSQL学习心得(七) 我的MYSQL学习心得(八) 我的MYSQL学习心得(九) 我的MYSQL学习心得(十) 我的MYSQL学习心得(十一) 我的MYSQL学习心得(十二) 我的MYSQL学习心得(十三) 我的MYSQL学习心得(十四) 这一篇<我的MYSQL学习心得(十五)>