赞
踩
前言: 今天开始正式进入MySQL的学习,希望这篇文章能够帮助到大家!
下载链接:
下载链接
打开链接之后直接点击No thanks, just start my download. 即可下载
如果该版本不是你想要的,也可以选择去Oracle官网或者MySQL官网下载其他版本
安装步骤就是一路next,这里不多介绍,需要注意的是:学习过程中,MySQL设置的密码尽量简单一点,容易记住
关于MySQL需要知道的:
MySQL是 “客户端-服务器” 结构的程序
1个MySQL服务器上,可以包含多个数据库,
1个数据库利用包含多个数据表,
1个数据表可以包含多个数据行
1个数据行可以包含多个数据列,一个数据行也可以叫一条记录
如图:
创建数据库(如果数据库名字存在,会报错):
create database 数据库名;
如果不存在该名称的数据库,就创建数据库;如果存在,就什么的不做,也不会报错,但是有警告:
create database if not exists 数据库名;
显示警告:
show warnings;
设置字符编码:
MySQL里面的utf8是阉割版的utf8,在MySQL中真正的utf8是utfmb4
create database if not exists 数据库名 charset utf8mb4;
语法:
show databases;
例如:
以上这四个数据库是系统自带的,安装好就有的数据库
删库非常危险,慎重使用!!!
drop database 数据库名;
也可以添加条件:
drop database if not exists 数据库名;
use 数据库名;
数据类型 | 大小 | 说明 | 对应Java中的类型 |
---|---|---|---|
bit(M) | 默认为1,M表示位数 | 表示二进制数,M取1~64 | |
tinyint | 1字节 | Byte | |
smallint | 2字节 | Short | |
int | 4字节 | Integer | |
bigint | 8字节 | Long | |
float(M,D) | 4字节 | 单精度浮点数,M表示总长度,D表示小数点位,不能精确表示小数 | Float |
double(M,D) | 8字节 | 双精度浮点数,M表示总长度,D表示小数点位,不能精确表示小数 | Double |
decimal(M,D) | M/D最大值+2 | M表示总长度,D表示小数点位,能精确表示小数 | BigDecimal |
numeric(M,D) | M/D最大值+2 | M表示总长度,D表示小数点位,能精确表示小数 | BigDecimal |
以上类型都是有符号类型(能够表示负数),常用的有int、bigint、double、decimal
数据类型 | 大小 | 说明 | 对应Java类型 |
---|---|---|---|
varchar(size) | 0~65535字节 | 可变长度字符串,size表示字符个数 | String |
char(size) | 0~65535字节 | 定长字符串,size表示字符个数 | String |
text | 0~65535字节 | 长文本数据(可变长,无需指定最大长度,是自适应的) | String |
mediumtext | 0~16777215字节 | 中等长度文本数据 | String |
blob | 0~65535字节 | 二进制数据 | byte[] |
可变长:根据存储的数据自动调整存储空间,例如char(10)与varchar(10),能保存的最大长度是10个字符,如果只存储了5个字符,char申请的存储空间是10个字符,可变长的varchar申请的存储空间是5个字符。
常用的有varchar
数据类型 | 大小 | 说明 | 对应Java类型 |
---|---|---|---|
datetime | 8字节 | 能表示范围:1000年到9999年 | java.util.Date、java.sql.Timestamp |
timestamp | 4字节 | 能表示范围:1970年到2038年 | java.util.Date、java.sql.Timestamp |
timestamp(时间戳):当前时间与1970年1月1日0时0分0秒的时间之差(单位可以是秒/毫秒/微秒…),只能表示到2038年,不适用
常用的有:datetime
总结: 上述类型并不是数据库全部的类型,不同的数据库支持的类型也有差别,掌握以下类型:int、bigint、double、decimal、varchar、datetime
大前提:先选中某个数据库!!!!
语法:
create table 表名(列名 类型,列名 类型.....);
例如:
create table test(id int,name varchar(20));
在命令行中执行SQL语句,执行成功会提示Query OK
show tables;
此时会展示已经创建好的表
desc 表名;
例如:
desc是describe的缩写,desc只能查看表的结构(有哪些列,每个列的情况),不能查看表中具体的内容
Field: 字段(列的名字)
Type: 列的类型,int(11),11表示位宽,最多只显示11个字符长度
NULL: 列是否允许为空,yes表示允许
key: 主键/外键(本文后面会介绍到)
Default: 默认值,可以手动指定
Extra: 补充信息
drop table 表名;
整个表的内容都会删除,包括数据
慎重使用!!!
使用comment、–、#
如:
comment: comment比较特殊,用法如下(创建表的时候使用)
关键字alter
添加列:
alter table 表名 add 新增的列名 类型;
修改列的类型:
alter table 表名 modify 要修改的列名 类型;
删除列:
alter table 表名 drop 要删除的列名;
修改表名:
alter table 要修改的表名 rename to 新表名;
添加主键:
alter table 表名 add primary key(列名);
删除主键:
alter table 表名 drop primary key;
添加外键:
alter table 表名 add constraint 添加的外键约束名 foreign key (设为外键的列名) references 参考的表名;
删除外键:
alter table 表名 drop foreign key 外键约束名;
基本语法:
insert into 表名 values(值,值,值...);
插入的数据类型要和表对应列类型匹配
插入数据需要和列的个数、数据类型、顺序匹配
如果要插入的数据包含中文,必须保证创建数据库时指定的字符集为utf8/gbk
例子
我们先准备好一个学生表,表的结构如下:
insert into student values(1,'张三');
insert into student values('111',222);
上图代码中,虽然插入第一列的是字符串类型,但是系统会尝试自动转成int;第二列插入的是整数类型,系统会尝试转成字符串。
insert into 表名(列名,列名...) values(值,值...);
为指定的列的值:如果允许为空值,则为空值;如果不允许为空值,则为默认值;如果没有指定默认值插入失败
insert into student(id) values(2);
insert into 表名 values(值,值...),(值,值...),(值,值...);
如:
insert into student values(1,'张三'),(2,'李四'),(3,'王五');
遵循格式:
年-月-日空格时:分:秒
insert into test values('2024-05-11 15:10:30');
获取系统当前时间,使用函数now(),如:
insert into test values(now());
也就是将查询的结果插入表中(可以指定列)
insert into 表名 select语句;
要求:select得到的结果集合要和insert into的表的列数、类型、顺序匹配
例如:将student1中年龄小于20的记录插入到student2中
insert into student2 select * from student1 where age < 20;
关键字:select
生成临时表,不会改变原始数据
select * from 表名;
例如
select * 的操作慎用,因为实际工作中,如果表非常大,数据非常多,此时使用select 操作可能会将硬盘、网卡带宽吃满,其他客户端访问数据库就无法正常进行
select 列名,列名... from 表名;
select 表达式 from 表名;
遍历每一行,取出想要的列代入表达式,结果为临时表,不会改变原来的数据
例:
有表grades如下:
查询每个同学的英语成绩和数学成绩的总和,语句如下
select math+english from grades;
查询结果:
如果表达式比较复杂无法直接观察,此时可以取别名
select 列名 as 别名 from 表名;
as 可以省略(不建议省略,容易看混)
例如:
多个行的数据如果出现相同的值,就只保留一份(针对也是临时表)
select distinct 列名 from 表名;
例如:
如果要查询多列,多列都重复才能触发去重效果
例如:
查询的是math和name,虽然math重复了,但是name没有重复,没有触发去重效果
针对查询结果进行顺序/降序排列,使用order by
select 列名 from 表名 order by 想要进行排序的列名 desc;-- 降序
select 列名 from 表名 order by 想要进行排序的列名 asc;-- order by默认的就是升序,asc 可以省略
desc,asc分别是descend、ascend的缩写
例:按数学成绩降序:
按数学成绩升序(asc可以省略不写)
另外,可以指定多个列,先按第一列排序,第一列相同则按照第二列排序以此类推
例如:按照数学成绩排序,如果数学成绩一样则按照英语成绩排序
查询过程可以指定筛选条件,查询结果会保留满足条件的记录
select 列名 from 表名 where 条件;
条件指的是条件表达式
比较运算符:
比较运算符 | 说明 |
---|---|
>、>=、<、<= | 大于、大于等于、小于、小于等于 |
= | 等于,null不安全,null=null的结果为null |
<=> | 等于,null安全,null<==>null结果是 true |
!=、<> | 不等于 |
between a and b | 表示连续的范围,[a,b) |
in(a1,a2,…) | 表示非连续的范围(离散的) |
is null | 是null |
is not null | 不是null |
like | 字符匹配 |
逻辑运算符:
逻辑运算符 | 说明 |
---|---|
and | 多个条件都为真,结果才是真 |
or | 任意一个条件为真,结果就为真 |
and 优先级高于or
执行顺序问题(大部分解释是这样,但是并不靠谱):
遍历表,取出每一行
把当前行,代入到where条件,根据条件真假决定这一行是否需要查询出来
再根据select后面写的列名/表达式,来进行筛选列/进行计算/别名
如果有order by则进行排序
like、not like
%表示任意长度
_代表任意一个字符
例如:
查询学生表(student)中以李开头的学生的所有内容
select * from student where name like '李%';
查询课程表(course)中,以’结构’结尾的课程名
select cname from course where cname like '%结构';
%表示可以是任意长度的字符串
查询学生表中姓名倒数第二个字为’德’的学生的所有内容
select * from student where name like '%德_';
is null、is not null、<=>
看例子
原始数据如下
null=null和null<=>null的区别
限制一次查询最多能查多少个记录
select 列名 from 表名 limit n;
从下标m开始查n条记录(原来的表中的第一条记录的下标是0)
select 列名 from 表名 limit m offset n;
select 列名 from 表名 limit m,n;
聚合是针对行和行之间的操作,需要搭配聚合函数
函数 | 说明 |
---|---|
count([distinct] 表达式) | 返回查询结果的数量(行数) |
sum([distinct] 表达式) | 返回查询结果的总和 |
avg([distinct] 表达式) | 返回查询结果的平均值 |
max([distinct] 表达式) | 返回查询结果的最大值 |
min([distinct] 表达式) | 返回查询结果的最小值 |
distinct是可选项,表示去重,前面介绍过
select count(*) from 表名;
-- 表示查询这张表有多少个记录(多少行),如果某个记录存在空值null,查询结果也会包含这列
select count(列名) from 表名;
-- 查询这一列的记录个数(多少行),如果这列存在空值null,查询结果不会包含空值(重名也计算)
select sum(列名/表达式) from 表名;
sum操作的这一列的类型必须是数字类型,遇到空值null直接跳过不参与运算
3. avg 针对指定列进行求和
select avg(列名/表达式) from 表名;
avg操作的这一列的类型必须是数字类型,遇到空值null直接跳过不参与运算
select max(列名/表达式) from 表名;
max操作的这一列的类型必须是数字类型,遇到空值null直接跳过不参与运算
5. min 针对指定列进行求最小值
select min(列名/表达式) from 表名;
min操作的这一列的类型必须是数字类型,遇到空值null直接跳过不参与运算
使用group by时,指定一个列,把列的值相同的行归到一组中
语法如下
select 列名 from 表名 ... group by 想要分组的列名;
例:
有员工薪资表如下
使用group by分组
将role值相同的归为一组,进行group by分组时,select后面的列名一般写group by分组的列或者搭配聚合函数的列
例如:
统计每个部门(role)的平均薪资:
统计每个部门的人数:
与order by搭配使用
当需要指定分组的条件时,可以使用having(不能使用where)
例:统计薪资平均值,以role分组,但是除去老板
注意:having是分组的条件,而where是没有分组时的条件
联合查询也就是多表查询,查询设计多个表
笛卡尔积:简单来说,就是拿着第一个表的每一行依次和第二个表进行匹配
如:
有学生表和班级表,以及这两个表的笛卡尔积
也就是将第一张表(学生表)中每一条记录,依次和第二张表(班级表)依次进行排列组合,多表查询就是基于笛卡尔积,但是在笛卡尔积中,有一些记录是不合理的,例如上述的张三的班级编号既有1又有2,但真实情况是张三的班级编号是2,如果两个表不存在某个列具有对应关系(对应关系如上述的班级编号),则这两个表进行笛卡尔积是无意义的。
在SQL语句中,如何进行笛卡尔积?
我们创建上述例子的两个表
笛卡尔积的SQL语句为:
select * from 表1,表2;
例如
语法:
select 列名 from 表1 [inner]join 表2 on 连接条件 and 其他条件;-- 表1join表2就相当于表1和表2进行笛卡尔积,inner表示内连接,可以省略
select 列名 from 表1,表2 where 连接条件 and 其他条件;-- 也就是把join换成逗号,把on换成where
只包含两个表中同时具备的数据,
不支持from多个表,只能使用join,MySQL中也不支持全外连接
左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件; -- 表1为基准
右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件; -- 表2为基准
例如:有两张表
左外连接:左表为基准,会确保左表中的每个记录都出现在,如果左表中的记录在右边中没有对应的记录,会把右表的字段填成null
右外连接和左外连接逻辑是一样的:确保右表中所有的记录都出现在结果中,如果右边中的记录在左边中没有对应的相关字段,则填成null
外连接和内连接可以总结为下面这张图:
自连接,就是一张表自己和自己进行笛卡尔积,自连接本质上是把行关系转换成列关系,自连接的语法如下
select 列名 from 表1 as 别名1,表1 as 别名2;
表1和表1是同一个表
例如:
如果不取别名,就会出现下面的报错:
同样的,自连接也需要指定连接条件(否则会出现许多无效记录):
总结:如果发现查询的条件是针对两行而不是两列,可以使用自连接,但是如果表的数据量非常大,要谨慎操作
子查询简单来说就是套娃(嵌套次数过多容易脑瓜子嗡嗡,不推荐使用)
例如:查询和张三同班的同学,
select * from student
where classid = (select classid from student where name = '张三');
多行子查询,使用in
例如:查询语文和英语的成绩信息
select * from score
where courseid in( select id from course where name = '语文' or name = '英语');
合并查询使用union关键字,可以把多个select查询结果合并成一个
select 列名 from 表名 条件 union select 列名 from 表名 条件;
可以把两个查询的结果合并在一起,针对不同表查询也可以
如果不想去重,可以使用union all
select 列名 from 表名 条件 union select 列名 from 表名 条件;
要求:合并的两个集合类型、个数、顺序、要匹配
update 表名 set 列名 = 值,列名 = 值 ...;
后面可以加上条件where/limit/order by
例:
删除的是硬盘上的一条符合条件的记录,如果没有规定条件,则是删除所有的记录(不会删除表)
delete from 表名 条件;
约束是数据库针对表中的数据,进行的一系列校验检查,约束类型有not null、unique、default、primary key、foreign key等
表示某列不能为空值,语法:
create table 表名 (属性)
例:创建表时,指定某列的值不能为空
在插入/修改数据时,插入/修改id属性就不能为空,如果有空则插入/修改失败
unique表示唯一,某列的每行必须有唯一值,在插入、修改时,不能插入/修改成存在过的值
unique如何知道数据是否存在重复?插入、修改之前会进行一次查询操作
例:指定学生表的name为unique
插入一条姓名为张三的记录后,又一次插入姓名为张三的记录,此时插入失败
default表示默认,指定某列的默认值,插入一条记录,如果不指定某行的值,会设置为默认值,例如:
创建学生表时,指定name的默认值为‘无名’
查看一下student的详细信息:default为‘无名’,如果创建表时不指定默认值,则默认是null
此时插入数据如果不指定该列的值,这列的值就会被设置为我们指定的默认值,如:
primary key表示主键,主键是一行唯一标识一条数据的属性,例如一个学校中,学生的学号就可以设置为主键,因为一个学校的学生学号不可能重复
primary key可以看成是not null和unique的结合,主键的值不能为空,也不能重复
例:创建学生表,将学号设为主键
查看表的详细信息:PRI指的就是primary 表示该属性是主键
在进行插入/修改之前,会进行一次查询,查看是否存在重复的主键值,如果存在,插入失败/修改
如果主键的类型是整型,可以搭配auto_increment使用,表示自增主键,此时插入记录可以不指定主键的值,MySQL会自动分配主键值,每次都会记录自增主键的最大值,后续插入数据是按最大值进行分配,同时也可以手动指定其他的值
创建学生表
如:
此时表中数据为
foreign key表示外键,外键涉及两个表,语法格式
create table 表名 (列名 类型,...... foreign key(列名) references 表名(列名));
创建class表
创建student表,student中外键为classid,引用自class表
此时外键约束出现了,如果要往student表中插入数据,必须保证插入的数据的classid在class表中存在,否则插入失败
父表:制约的表(class表),子表:被约束的表(student表)
如何知道classid存不存在?插入时会触发对class表的查询(数据库内部完成)
如果父表的某个记录被子表引用了,此时不能删除/修改父表中对应的记录了
删除表:需确保先删除子表,再删除父表否则出错:
场景:商品表:(goodsid,goodsname,price),订单表:(orderid,goodsid);如果某个需要商品下架,如何删除?
逻辑删除:额外添加一列,表示标记
索引,相当于一个特殊的“目录”,有了索引的存在,能够加快查询速度,尽可能避免对表数据的遍历。
引入索引的缺点:
需要消耗额外的存储空间
引入索引,虽然可以提高查询速度,但是可能会影响增、删、改的效率(增删改的时候需要同步更新维护索引)
操作索引的SQL语句
show index from 表名;
如果建表时指定了主键,会自动生成主键索引,索引是按照列的方式创建的,可以给某个列创建索引。如果以某个列创建索引,当查询的时候以该列为条件时,索引才能生效,提高查询速度,否则无法生效。
除了主键外,unique、foreign key也会自带索引
可以给非主键、外键、unique的列手动创建索引,语法如下:
create index 索引名 on 表名(列名);
创建索引,也是危险操作~因为一旦数据量比较大,就会触发大量的硬盘IO,所以在最初建表时就提前规划好建立哪些索引
语法
drop index 索引名 on 表名;
只能删除自己手动创建的索引,自动生成的索引无法删除,删除索引也是危险操作~~
构建索引,也就是引入一些数据结构,对数据进行存储,从而提高查找速度
数据库中,索引保存的数据结构主要为B+树,为啥不用别的数据结构?
顺序表、链表不适合查找,栈、队列也不适合查找,
二叉搜索树:可以提高查找效率,但是问题在于保存数据较多时,树的高度就会变高,比较的次数也就会变高,会造成非常大的硬盘IO
哈希表:只能进行"相等"的查询,不能进行范围查询(比如>、<、between and),也无法进行like这样的模糊查询
适合给数据库做索引的数据结构,就是B+树,什么是B+树?
想要了解B+树,得先知道B树(也可以写作B-树)
B树: 平衡的n(n>2)叉搜索树(每个结点可以有多个子树),这样树的高度就大大降低了,如图
树的高度降低了,每个结点的比较次数变多了(比较逻辑:和某个结点比较的时候,先进行一次硬盘IO,把所有的结点内容读取出来),但是硬盘IO减少了,
B+树: 针对B树改进的数据结构
B+树的优点:
索引相当于书的目录,能够提高查询速度
消耗了更多的存储空间
可能会影响增、删、改的效率(可能提高也可能降低,也可能没有影响)
show index from 表名; – 查看表的索引(主键、外键、unique会自动生成索引)
create index 索引名 on 表名(列名); – 给指定的列创建索引
drop index 索引名 on 表名; – 删除索引(只能删除自己手动创建的索引)
事务是用来解决某些特定场景的问题的,有些场景完成某个操作,需要多个SQL语句配合完成~
想象一个场景:
张三在玩王者农药,想要充648点券买皮肤,于是给马花藤的账户充了648
先创建表~~
create table account( id int primary key auto_increment,
name varchar(20) comment '账户名称',
money decimal(11,2) comment '金额');
insert into account(name, money) values
('马花藤', 99999999),
('张三', 1000);
充值逻辑:
update account set money = money-648 where name = '张三';
update account set money = money+648 where name = '马花藤';
两个sql必须都执行完毕转账才能完成,假设第一条update执行成功后,突然出现网络问题,主机断电了或者数据库崩了,后面的语句无法执行,导致张三的账户里减少了648,而马花藤的账户金额没有增加。这种情况显然是不对的,如何避免这种情况?使用事务,保证上面两条语句要么全部执行成功,要么全部都执行失败
语法:
start transaction; -- 开启事务
sql语句
rollback; -- 回滚,表示sql语句全部执行成失败
start transaction;
sql语句
commit;-- 提交,表示sql语句全部执行成功
所谓事务:就是将多个需要执行的sql语句,包装成一个整体,要么这个整体都执行完,要么都不执行(不是真的不执行,而是还原成出现问题之前的状态,这样的机制也叫回滚(rollback))
1、原子性:上述的包装成的整体也可以称为一个原子,表示这个整体不能拆分了,这样的特征叫原子性
2、一致性:事务执行前和执行后,数据库中的数据都是合法状态,不会出现非法的临时结果状态(比如转账,不能出现:A转账给B,A的账户余额少了,而B账户余额没有增加)
3、持久性:事务执行完毕后,会修改硬盘上的数据,事务都是持久生效的
4、隔离性:隔离性描述的是:多个事务并发执行时,相互之间的影响是怎样的。什么是并发?MySQL是客户端–服务器结构的程序,一个服务器,可能会给多个客户端同时提供服务。所以,如果这些同时执行的事务恰好也是针对同一个表,进行增删改查就会出现下面问题
解决办法:约定好:A在修改数据时,B不能读取数据 --> 给写加锁
解决办法:约定好:一个事务在读取数据的时候,其他事务不能修改正在读取的数据 --> 给读加锁
解决办法:约定:只要有事务在读取数据,其他事务就不要干任何操作 --> 串行化,也就是说多个客户端同时提交多个事务给服务器,服务器是一个一个执行事务,而不是同时执行
隔离性描述的是针对上述问题如何解决的,在mysql中提供了4个隔离级别,可以通过设置配置文件来设置当前服务器的隔离级别
实际工作中,很少直接使用命令行/图形化界面 的客户端来操作数据库,更多的是使用C++、Java、Python等语言来操作数据库。数据库提供了API供我们使用代码来操作数据库。数据库有很多种Oracle、MySQL、SQL server这些数据库提供的API是不一样的,于是Java自身制定了一套标准,要求这些数据库都要把自己的API转换成和兼容Java的API,而JDBC就是由Java制定的针对数据库操作的API。
MySQL本身的API是C语言的API,把C语言的API转换成兼容JDBC的Java的API需要MySQL官方提供的mysql-connector,如何下载mysql-connector?
下载方法:去Maven中央仓库Maven中央仓库
输入mysql,点击Search
我们可以看到有两个选项,第一个选项的版本比较新,第二个选项是老的经典的版本
选择对应版本(根据自己的mysql的版本来选择,如果mysql是5系列的版本,那么connector也必须是5系列的只要是5开头的就可以)
我们随便选一个版本,点击jar按钮即可下载
把下载好的connector导入到项目中,才能编写我们的代码来进行数据库的操作
随便取个名字
将下载好的jar文件复制到刚才创建好的lib路径
直接选中lib然后Ctrl+v粘贴,点击OK
复制好之后还有一步,右键刚才的lib,点击Add as Library(告诉lib是一个库目录)
点击OK
添加完成之后的效果是这样的
以上方法是简单粗暴的方法导入jar包,实际开发并不会这样操作,如何操作,后续再介绍~
接下来,就可以开始写java代码了
JDBC使用步骤
方法1:利用了向上转型和向下转型
DataSource dataSource = new MysqlDataSource();//MysqlDataSource是刚才导入的.jar包里面的
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncoding=utf8&useSSL=false");//数据源,要访问的数据库在哪里
((MysqlDataSource)dataSource).setUser("root");//访问数据库的账户
((MysqlDataSource)dataSource).setPassword("1234");//访问数据库的密码,这里假设密码是1234
上述字符串
"jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncoding=utf8&useSSL=false"中,127.0.0.1是一个特殊的IP地址,表示本机的地址,因为我们用的MySQL服务器基本上都是在自己的电脑上,如果服务器在其他地方,填对应的IP地址即可,3306表示指的是端口号,用于区分一个主机上的应用程序
方法2:
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setURL("jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncoding=utf8&useSSL=false");
dataSource1.setUser("root");
dataSource1.setPassword("1234");
Connection connection = dataSource.getConnection();
String sql = "insert into student values(?,?)";//变量sql表示要执行的sql语句,问号表示占位符
PreparedStatement statement = connection.prepareStatement(sql);//
int n = statement.executeUpdate();
//处理的是更新操作相关的语句(包括create,delete,update等除查询外的操作),返回值n表示几行受到了影响
ResultSet resultSet = statement.executeQuery();
//处理查询操作相关的SQL,返回值是ResultSet,可以理解为数据集合
statement.close();
connection.close();
resultSet.close();//如果处理了查询操作相关的SQL,需要加上这句,如果没有则不加
例如:
public static void main(String[] args) throws SQLException { Scanner scanner = new Scanner(System.in); //1.创建数据源对象 MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setURL("jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncoding=utf8&useSSL=false"); //字符串的内容表示("jdbc:mysql://数据库服务器的IP地址/数据库名?characterEncoding=utf8&useSSL=false"); dataSource.setUser("root"); dataSource.setPassword("111111"); //2.和数据库建立网络连接 Connection connection = dataSource.getConnection(); //3.构造SQL语句 String sql = "insert into student values(?,?)";//问号表示占位符, PreparedStatement statement = connection.prepareStatement(sql); int id = scanner.nextInt(); String name = scanner.next(); //设置占位符的相关值也就是设置上述?号的值 statement.setInt(1, id); statement.setString(2, name); // 4. 把 SQL 发送到服务器上进行执行 int n = statement.executeUpdate(); System.out.println(n + "行受到影响"); //5.关闭资源 statement.close(); connection.close(); }
实用案例:
在jdbctest数据库中有学生表student,初始状态表中没有数据
使用代码,通过控制台输入数据,并插入到student表中
public static void main(String[] args) throws SQLException { // 1. 创建数据源 MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncoding=utf8&useSSL=false"); dataSource.setUser("root");//账号 dataSource.setPassword("111111");//密码 // 2. 建立连接 Connection connection = dataSource.getConnection(); // 3. 构建 sql String sql = "insert into student values(?,?)"; PreparedStatement statement = connection.prepareStatement(sql); //3.1 在控制台输入要插入的值 Scanner scanner = new Scanner(System.in); System.out.println("请输入学生id"); int id = scanner.nextInt(); System.out.println("请输入学生姓名"); String name = scanner.next(); statement.setInt(1, id);//1表示下标,从1开始!!,id表示列 statement.setString(2, name); // 4. 执行 sql int n = statement.executeUpdate(); // 5. 关闭对应的资源 statement.close(); connection.close(); }
运行程序,分别输入1,张三
再次查询学生表
可以看见学生表中多了一条记录,
另外还可以使用java代码进行查询语句的操作
如:
初始数据:
使用java代码查询
public static void main(String[] args) throws SQLException { // 1. 创建数据源 MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncoding=utf8&useSSL=false"); dataSource.setUser("root");//账号 dataSource.setPassword("111111");//密码 // 2. 建立连接 Connection connection = dataSource.getConnection(); // 3. 构建 sql String sql = "select * from student"; PreparedStatement statement = connection.prepareStatement(sql); // 4. 执行 sql ResultSet resultSet = statement.executeQuery();//返回值是ResultSet,可以理解为数据集合 // 5. 遍历结果集合 while (resultSet.next()) { // 循环里针对一行进行处理 System.out.println(resultSet.getInt("id") + "\t" + resultSet.getString("name")); } // 6. 关闭对应的资源 resultSet.close(); statement.close(); connection.close(); }
输出结果:
关于MySQL的内容就介绍到这了,以上内容能应付大部分的面试和笔试,感谢大家支持~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。