略
1、navicat
命令行下输入
mysql -uroot -p
net start mysql80
net stop mysql80
#或者
sc start mysql80
sc stop mysql80
MySQL Connector/C++8.0 是一个MySQL数据库连接器,用于连接到MySQL服务器的C++应用程序。Connector/C++ 可用于访问实现文档存储的MySQL服务器,或以传统方式使用SQL语句。Connector/C++ 8.0 的首选开发环境是支持开发使用 X DevAPI 的 C++ 应用程序,或使用 X DevAPI for C 的普通 C 应用程序,但 Connector/C++ 8.0 还支持开发使用旧的基于 JDBC 的 API 的 C++ 应用程序连接器/C++ 1.1。
在线手册
//包含头文件
#include "mysql/jdbc.h"
//1 获得驱动
auto m_driver = sql::mysql::get_mysql_driver_instance();
//2 连接数据库
auto m_conn = m_driver->connect(m_hostName, m_user, m_password);
//3 执行语句
auto stmt = m_conn->createStatement();
stmt->execute("create database db");//创建数据库db
stmt->execute("use db");//使用名字叫做db的数据库
//创建一张表存储图片 mediumblob 最大16MB
stmt->execute("create table tb1(id int not null primary key auto_increment, imgbuffer mediumblob)");
//4 向表中插入内容
auto pre_stmt = m_conn->prepareStatement("insert into tb1(name,imgbuffer) values(?,?)");
//插入int类型数据
pre_stmt->setInt(1, 1000);
//插入二进制数据,比如有 char* blobData; 它的数据长度是 length;
std::strstreambuf buf(reinterpret_cast(blobData), length);
std::istream stream(&buf);
pre_stmt->setBlob(2, &stream);
//数据插入完成后提交更新(在执行更新之前,一定要保证 blobData 数据有效,否则将会失败)
pre_stmt->executeUpdate();
//5 查询blob字段内容
try {
auto st = m_conn->createStatement();
st->execute("use db");
auto re = st->executeQuery("select imgbuffer from tb1");
while (re->next())
{
auto is = re->getBlob("imgbuffer");
std::istreambuf_iterator eos;
std::string s(std::istreambuf_iterator(*is), eos);
auto buffer_size = s.length();
void* buffer = malloc(buffer_size);
std::memcpy(buffer, s_c_str, buffer_size);//将数据拷贝到准备好的内存中,使用完后需要 free(buffer)
}
}
catch (SQLException& e) {
//异常 e.what();
}
//方式一
QImage image;
image.load(fileName);
//将QImage转化为QByteArray
QByteArray imageArray;
QBuffer buffer(&imageArray);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG");
int buffer_size = imageArray.length();
void* imgbuffer = malloc(buffer_size);
memcpy(imgbuffer, imageArray.data(), len);
//写入blob字段中
std::strstreambuf buf(reinterpret_cast(imgbuffer), buffer_size);
std::istream stream(&buf);
pre_stmt->setBlob(2, &stream);
//方式二
QFile file(fileName);
if (file.open(QIODevice::ReadOnly))
{
QByteArray dataarray(file.readAll());
QBuffer buffer(&dataarray);
buffer.open(QIODevice::ReadOnly);
int buffer_size = dataarray.length();
void* imgbuffer = malloc(buffer_size);
memcpy(imgbuffer, dataarray.data(), buffer_size);
//写入blob字段中
std::strstreambuf buf(reinterpret_cast(imgbuffer), buffer_size);
std::istream stream(&buf);
pre_stmt->setBlob(2, &stream);
}
//读取blob字段内容
long* data_ptr = new long;
auto buffer_size = pDB->getData((void**)&data_ptr);//具体读取方式见参考代码
//将data_ptr中的内容转为QImage
QImage img;
img.loadFromData((const uchar*)(data_ptr), buffer_size);
数据库放在数据库中,SQL是用于访问和处理数据库的标准的计算机语言,SQL是Structured Query Language的缩写,是指结构化查询语言。
特点:
数据类型 | 说明 |
---|---|
int | |
bigint | |
char(n) | 字符/字符串,固定长度 n |
varchar(n) | 字符/字符串,可变长度,最大长度 n |
text | |
mediumtext | |
longtext | |
numeric(a,b) | 精确数值,总位数 a,小数点后位数 b(四舍五入) |
decimal(8,2) | 整体8位,小数保留2位(自动做4舍5入) |
date | 存储年、月、日的值 |
在线手册
-- 查看所有数据库
show databases;
-- 查看所有表
show tables;
-- 查看表结构 desc + 表名
desc employees;
-- 创建数据库,该命令的作用:
-- 1. 如果数据库不存在则创建,存在则不创建。
-- 2. 创建RUNOOB数据库,并设定编码集为utf8
create database if not exists 数据库名 default charset utf8 collate utf8_general_ci;
use 数据库名;
drop database if exists 数据库名;
create table if not exists 表名(
列名 类型,
列名 类型,
列名 类型
)default charset=utf8;
-- 可选项
ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;
-- 举例
create table if not exists tb1(
id int not null auto_increment primary key, -- 不允许为空 & 主键 & 自增
name varchar(16) not null, -- 不允许为空
email varchar(32) null, -- 允许为空(默认)
age int default 3 -- 插入数据时,如果不给age列设置值,默认值:3
)default charset=utf8;
mysql> desc tb1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| email | varchar(32) | YES | | NULL | |
| age | int | YES | | 3 | |
+-------+-------------+------+-----+---------+----------------+
drop table 表名;
-- 方式1
delete from 表名;
-- 方式2 速度更快,但是不可恢复
truncate table 表名;
alter table 表名 add 列名 类型;
alter table 表名 add 列名 类型 default 默认值;
alter table 表名 add 列名 类型 not null default 默认值;
alter table 表名 add 列名 类型 not null primary key auto_increment;
alter table 表名 drop column 列名;
alter table 表名 modify column 列名 类型;
alter table 表名 modify column 原列名 新列名 新类型;
alter table 表名 alter 列名 set default 1000;
alter table 表名 alter 列名 drop default;
alter table 表名 add primary key(列名);
alter table 表名 drop primary key;
-- 方式1
delete from 表名;
-- 方式2 速度更快,但是不可恢复
truncate table 表名;
-- 第一种方式
insert into tb1(name,email,age) values("张三","**@qq.com",18),("李四","**@qq.com",18);
-- 第二种方式
insert into tb1 values(3,"王五","**@qq.com",18);
delete from tb1 where id=2;
-- 查询表中所有内容
select * from tb1;
+----+------+-----------+------+
| id | name | email | age |
+----+------+-----------+------+
| 1 | 张三 | **@qq.com | 18 |
| 3 | 王五 | **@qq.com | 18 |
| 4 | 张三 | NULL | 22 |
| 5 | 张三 | NULL | 22 |
| 6 | 唐三 | NULL | 22 |
+----+------+-----------+------+
select * from tb2;
+------+-------+
| id | title |
+------+-------+
| 1 | 开发 |
| 2 | 运营 |
+------+-------+
-- 查询字段 name,age
select name,age from tb1;
+------+------+
| name | age |
+------+------+
| 张三 | 18 |
| 王五 | 18 |
| 张三 | 22 |
| 张三 | 22 |
| 唐三 | 22 |
+------+------+
-- 查询名字叫张三的
select name,age from tb1 where name="张三";
+------+------+
| name | age |
+------+------+
| 张三 | 18 |
| 张三 | 22 |
| 张三 | 22 |
+------+------+
-- 更多的条件查询
select * from tb1 where id > 3;
select * from tb1 where id = 1;
select * from tb1 where id >= 1;
select * from tb1 where id != 1;
select * from tb1 where id between 2 and 4;
select * from tb1 where id=4 and name="张三";
select * from tb1 where (id=4 or name="张三") and age=22; -- 此条结果对应在下方
+----+------+-------+------+
| id | name | email | age |
+----+------+-------+------+
| 4 | 张三 | NULL | 22 |
| 5 | 张三 | NULL | 22 |
+----+------+-------+------+
select * from tb1 where id in(3,4);
select * from tb1 where id not in(3,4);
select * from tb1 where exists(select * from tb2 where id=8);
select * from tb1 where id in(select id from tb2);-- 此条结果对应在下方
+----+------+-----------+------+
| id | name | email | age |
+----+------+-----------+------+
| 1 | 张三 | **@qq.com | 18 |
+----+------+-----------+------+
select * from (select * from tb1 where id>3) as T where T.name="张三";-- 此条结果对应在下方
+----+------+-------+------+
| id | name | email | age |
+----+------+-------+------+
| 4 | 张三 | NULL | 22 |
| 5 | 张三 | NULL | 22 |
+----+------+-------+------+
select
id,name,
case name when "张三" then "法外狂徒" else "安全人员" end v1
from tb1;
+----+------+----------+
| id | name | v1 |
+----+------+----------+
| 1 | 张三 | 法外狂徒 |
| 3 | 王五 | 安全人员 |
| 4 | 张三 | 法外狂徒 |
| 5 | 张三 | 法外狂徒 |
| 6 | 唐三 | 安全人员 |
+----+------+----------+
-- 在 WHERE 子句中使用 LIKE 运算符来搜索匹配字符串中的指定模式,百分号(%)匹配零个、一个或多个字符。如:
select id,name,age from tb1 where name like("张%") ;
+----+----------+------+
| id | name | age |
+----+----------+------+
| 1 | 张三改名 | 18 |
| 4 | 张三改名 | 22 |
| 5 | 张三改名 | 22 |
+----+----------+------+
-- 查询邮箱为空的员工信息
select * from tb1 where email is null;
+----+----------+-------+------+
| id | name | email | age |
+----+----------+-------+------+
| 4 | 张三改名 | NULL | 22 |
| 5 | 张三改名 | NULL | 22 |
| 6 | 唐三 | NULL | 22 |
+----+----------+-------+------+
update tb1 set name="张三改名" where name="张三";
+----+----------+-----------+------+
| id | name | email | age |
+----+----------+-----------+------+
| 1 | 张三改名 | **@qq.com | 18 |
| 3 | 王五 | **@qq.com | 18 |
| 4 | 张三改名 | NULL | 22 |
| 5 | 张三改名 | NULL | 22 |
| 6 | 唐三 | NULL | 22 |
+----+----------+-----------+------+
同一字段中可能会出现重复值,使用关键词 distinct 可以去掉重复值,用法如下:
select distinct 字段名 from 表名;
select distinct name from tb1;
and 和 or 可以用在 where 子句中把两个或多个条件结合起来。and 运算符要求两个条件都成立;or 运算符要求两个条件中只要有一个成立即可。如:
select 字段名 from 表名 where 字段 n 运算符 值 n and|or 字段 m 运算符 值 m;
-- 查询出第3部门里工资大于等于5000的员工
select * from employees where deptno=3 and salary >= 5000;
select * from employees where (deptno=3 or deptno=1) and salary<5000;
in 运算符是在 where 子句中指定多个搜索条件可以匹配的值。in 运算符实际是多个or条件的合并。如:
select 字段名 from 表名 where 字段名 in(值1, 值2,…);
-- in 匹配多个值 列出员工号为3和5的员工:
select name from employees where empno in(3,5);
-- 前面的SQL语句相当于
select name from employees where empno=3 or empno=5;
-- 否定形式
select name from employees where empno not in(3,5);
-- 嵌套
select name from employees where deptno in (select deptno from dept where loc like '一楼%');
between 运算符用于选取介于两个值之间的数据范围内的值,这些值可以是数字,字符串或日期。between 运算符包括开始和结束值,相当于 >= and <=。
语法:select 字段名 form 表名 where 字段名 between 值1 and 值2;
select name from employees where hiredate between '2013-01-01' and '2013-12-31';
select name from employees where hiredate not between '2013-01-01' and '2013-12-31';
order by 用于对结果集进行排序, 默认按升序进行排序, 也可以指定 desc 按降序对结果集进行排序。如:
select 字段名 from 表名 order by 字段1,字段2,… asc|desc;
-- 降序
select name,salary from employees order by salary desc;
索引可以提高访问数据的速度。创建索引的语法如下:
create index 索引名 on 表名(字段1,字段2,…)
使用索引时 SQL 语句的语法和不使用索引并没有任何不同,SQL 语句会自动使用索引提高访问数据的速度。
create index in_name on employees(name);
视图是基于 SQL 语句的结果集的可视化表,视图中的字段就是来自一个或多个数据库中的真是的表中的字段。
视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。
语法:create view 视图名 as select 语句;
-- 把10月1日之前雇佣的员工的姓名和工资列出来
create view employees_2021 as select name,salary from employees where hiredate < '2021-10-01';
-- 查询视图
select * from employees_2021;
-- 更新视图中的数据(同时也将修改employees表中的数据)
update employees_2021 set salary=salary+400 where name='张三';
null 值代表遗漏的未知数据,它的作用是未知的或不适用的值的占位符。
如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL值保存。
字段值是否为 NULL 的判断不能用 = 或者 <> 进行判断,要用 is null 或者 is not null 。
-- 查询邮箱为空的员工信息
select * from tb1 where email is null;
join 连接是基于多个表之间的共同字段把它们结合起来进行查询的一种方法。连接分为以下几种:
语法:
select 字段名 as from 表1 join 表2 where 子句;
-- 找出在员工表和经理表中同时出现的员工
select name,title from employees inner join managers on employees.empno=managers.empno;
子查询也称嵌套查询,是一种嵌套在其他SQL语句的WHERE字句中的查询。子查询用于为主查询返回其所需数据,或者对检索数据进行进一步的限制。
语法:
select 字段1,字段2,… from 表名 where 字段名 操作符 (子查询);
-- 查询在二楼办公的员工的姓名
select from employees where deptno in(select deptno from dept where loc like '二楼%');
作用
在 SQL 语句中可以为表名或字段名指定临时使用的别名(Alias),别名只在当前的SQL 语句中生效,它通常比字段名更具有可读性。
别名有以下应用场景:
别名的语法
select 字段名 as 别名 from 表名 as 别名;
as 可以省略。
select name 姓名, salary 工资 from employees e;
-- 为函数取别名
select count(*) 总人数 from employees;
count 函数统计符合条件的记录数,count(*)统计表中的记录总数,count(字段名)统计指定字段不为null的记录数。
-- 统计表中所有员工
select count(*) from employees;
-- 统计员工表中所有部门号不为 null 的员工
select count(deptno) from employees;
-- 统计员工表中部门号为 null 的员工
select * from employees where deptno is null;
max 函数返回所选字段的最大值,用法是 max(字段名)。
-- 查询员工表中工资最高的员工
select max(salary) from employees;
min 函数返回所选字段的最小值,用法是 min(字段名)。
group by 语句用于结合统计函数,根据一个或多个列对结果集进行分组。语法如下:
select 字段名,统计函数 from 表名 where 子句 group by 字段名;
-- 按部门统计员工的平均工资
select deptno,avg(salary) from employees group by deptno;
having 子句和where子句类似,都是对查询的结果集进行过滤。它们的过滤对象不同,where 子句对被选择的列进行过滤,而having 子句则对group by 子句产生的组进行过滤。
语法:
select 字段名,统计函数 from 表名 where 子句 group by 字段名 having 统计函数 运算符 值;
-- 查询部门员工平均工资小于4500的部门
select deptno,avg(salary) from employees group by deptno having avg(salary)<4500;
主键的全称是主键约束,表的主键由表中的一个字段或多个字段组成,主键唯一代表表中一条记录,关系数据库中通常每个表都有一个主键,没有主键的表通常是不严谨的设计产物。主键由以下特点:
违法主键约束的记录将不能被插入
#导入
mysqldump -u root -p mydb < D:/aa.sql
#导出
mysqldump -u root -p mydb > D:/aa.sql #有结构有数据
mysqldump -u root -p -d mydb > D:/aa.sql #有结构无数据