1、SQL分类:
DDL -- Data Definition Languages:数据定义语言,定义数据库对象(数据库,表,字段)
DML -- Data Manipulation Language:数据操作语言,对数据库表中的数据进行增删改
DQL -- Data Query Language:数据库查询语句,查询数据库中表的记录
DCL -- Data Control Language:数据库控制语言,创建数据库用户、控制数据库的访问权限
2、DDL 数据库,表,字段操作
1、DDL-- 数据库操作
查询:
查询所有数据库:
show databases;//查看所有数据库 show create database 数据库名;//查看数据库定义语句
查询当前使用的数据库:
select database();
创建:
create database [if not exists] 数据库名 [dafault charset 字符集] [collate 排序规则];
删除:
drop database [if exists] 数据库名;
使用:
use 数据库名;
2、DDL-- 表操作
1、查询:
查询当前数据库所有表:
show tables;
查询表结构:
desc 表名;
查询指定表的建表语句:
show create table 表名;
2、创建:
create table 表名(
字段1 字段1类型 [ comment 字段1注释 ], #comment 是添加注释的意思
字段2 字段2类型 [ comment 字段2注释 ],
字段3 字段3类型 [ comment 字段3注释 ],
...........
字段n 字段n类型 [ comment 字段n注释 ],
)[ comment 表注释 ];
例如:
create table test(
id int(10) comment '编号',
`name` varchar(20) comment '姓名',
age int(3) comment '年龄',
gender varchar(3) comment '性别'
) comment '测试表';
3、数据类型
数值类型:
无符号:在数据类型后加上unsigned。如:id int(10) unsigned;
精度:数字总位数(包括小数)标度:小数位数。如:money double(10,2) unisigned;
字符串类型:
时期时间类型:
4、修改:
添加字段:
alter table 表名 add 字段名 数据类型(长度) [ comment '注释' ] [ 约束 ];
alter table test add nickname varchar(10) comment '昵称';
修改:
修改数据类型:alter table 表名 modify 字段名 新数据类型(长度)
修改字段名和字段类型:alter table 表名 change 旧字段名 新字段名 类型(长度) [ comment ‘注释’ ] [ 约束 ];
alter table test change nickname username varchar(30) comment '用户名';
删除字段:
alter table 表名 drop 字段名;
alter table test drop username;
修改表名:
alter table 表名 rename to 新表名;
alter table test rename to test1;
5、删除
删除表:
drop table [ if exists ] 表名;
drop table if exists test; #if exists要放在表名前
删除表后重新创建该表:(用于清空表中所有数据)
truncate table 表名;
3、DML 表中字段数据操作
1、添加字段数据:
给指定字段添加数据:
insert into 表名 ( 字段名1,字段名2,...... ) values ( 值1,值2,..... );
给全部字段添加数据:(不指定字段名,要按顺序写值)
insert into 表名 values ( 值1,值2,...... );
批量添加数据:
insert into 表名 ( 字段名1,字段名2,...... ) values (值1,值2,.....), (值1,值2,.....), (值1,值2,.....);
insert into 表名 values ( 值1,值2,..... ), ( 值1,值2,..... ), ( 值1,值2,..... );
注:字段名与值要一 一对应。
INSERT INTO test1( id, `name`, age, gender )
VALUES ( 1, 'alice', 18, '女' ),(2,'Tom',19,'男' );
2、修改字段数据:
uptate 表名 set 字段名1 = 值1,字段名2 = 值2,....... [ where 条件 ];
注:如果没有where约束条件,默认修改整张表。
update test1 set name='bob', gender='男' where id = 1;
3、删除字段数据
delete from 表名 [ where 条件 ];
delete from test1 WHERE id = 2;
注:delete 不加条件默认删除整张表。且不能删除某一字段的值(可以使用update)
4、DQL 查询操作
完整语法:
select 字段列表
from 表名列表
where 调节列表
group by 分组字段列表
having 分组后条件列表
order by 排序字段列表
limit 分页参数
1、基本查询
1、查询多个字段:
select 字段1,字段2,字段3 ...... from 表名;
select * from 表名;(查询全部字段信息)
2、设置别名:AS
select 字段1 AS 别名,字段2 AS 别名 ....... from 表名;
3、去除重复记录:distinct
select distinct 字段列表 from 表名;
2、条件查询:where
1、语法
select 字段列表 from 表名 where 条件列表;
2、条件查询
比较运算符:
大于:>。 小于:= 。小于等于:或!=。
在 ... 和 ... 之间 between ... and ... 。在 ... 之中 in( ... ) 。模糊查询 like 。
为空 is null。并且和 and或&& 。或者 or或 ||。非!或not。
注:like中%代表任意个字符,_待变任意一个字符。长度为三可写出三个下划线_ _ _
3、聚合查询:聚合函数
将一列数据作为一个整体,进行纵向计算。
用法:select 聚合函数( 字段列表 ) from 表名;
聚合函数:
count 统计数量
max 最大值
min 最小值
avg 平均值
sum 求和
注:聚合函数不计算 null 值。
4、分组查询:group by
1、语法:
select 字段列表
from 表名
where 条件
group by 分组字段名
having 分组后过滤条件
where和having的区别:
1、执行时机不同:where是分组之前进行过滤,不满足where条件不参与分组,而having是分组之后对结果进行过滤。
2、判断条件不同:where不能对聚合函数进行判断,having可以。
5、排序 ASC,DESC
语法:select 字段列表 from 表名 order by 字段1 排序方式,字段2 排序方式, .......;
排序方式:
ASC: 升序(默认)
DESC:降序
6、分页 limit
语法:select 字段列表 from 表名 limit 起始索引,查询记录数;
7、执行顺序
之前学习的是编写顺序
执行顺序:from -> where -> group by , having -> select -> order by -> limit
select 字段列表 4
from 表名列表 1
where 调节列表 2
group by 分组字段列表 3
having 分组后条件列表 3
order by 排序字段列表 5
limit 分页参数 6
完整版:
(1) FROM
(3) JOIN
(2) ON
(4) WHERE
(5) GROUP BY (开始使用SELECT中的别名,后面的语句中都可以使用)
(6) AVG,SUM.... (聚合函数)
(7) HAVING
(8) SELECT
(9) DISTINCT
(10) ORDER BY
(11) LIMIT
5、DCL 用户和权限操作
1、管理用户
1、查询用户:
use mysql;
select * from user; //mysql数据库中user表存储了所有用户信息
2、创建用户
语法:create user '用户名'@'主机名' identified by '密码';
注:主机名是指定登陆的主机,%为通配符表示任意主机。
create user 'itcast'@'localhost' identified by '123456';
3、修改用户密码
语法:alter user '用户名'@'主机名' identified with mysql_native_password by '新密码';
alter user 'itcast'@'localhost' identified with mysql_native_password by '1234';
4、删除用户
语法:drop user '用户名'@'主机名';
drop user 'itcast'@'localhost';
注:DCL开发人员用的很少,主要是数据库管理人员DBA运维使用。
2、权限控制
主要权限
1、查询权限
语法:show grants for '用户名'@'主机名';
show grants for 'itcast'@'localhost';
2、授予权限
语法:grant 权限列表 on 数据库.表名 to '用户名'@'主机名';
注:* 为通配符,代表所有。例如:赋予所有数据库所有表写成: *.*
grant all on itcast.* to 'itcast'@'localhost';
3、撤销权限
revoke 权限列表 on 数据库.表名 from '用户名'@'主机名';
revoke all on itcast.* from 'itcast'@'localhost';
6、函数
是指一段可以被另一个程序调用的程序或代码。
1、字符串函数
select concat('hello','world!'); //打印helloworld!
select lpad('01',5,'-'); //打印---01
select substring('helloworld',1,5);//打印hello
注:mysql索引从1开始
2、数值函数
3、日期函数![](https://i-blog.csdnimg.cn/blog_migrate/09b7d31c8dae6ce3b91d37cc68b4e65f.png)
select curdate(); //打印当前日期
select curtime(); //打印当前时间
select now();
//打印当前日期加时间
select month(now());
//打印当前月份
select day(now());
//打印当前日
select datediff('2022-1-1','2021-1-1');//打印365(前面日期减后面)
4、流程控制函数
5、开窗函数(8.0新特性)
8.0之前的版本实现排名:
通过设置变量进行排名
set命令设置变量。:= 为赋值符号。变量前加@为获取变量值。例如:
set @i:=0;
select @i:=@i+1;
或
select @i:=@i+1 from (select @i:=0) as t;
7、约束
作用于表中字段上的规则,用于限制在表中的数据。
例如:(创建时添加)
#创建一个用户表,并添加相关约束
create table user(
id int primary key auto_increment,
`name` varchar(10) not null unique,
age int check(age>0 and age<120),
gendar char(1) default '男'
)comment '用户表';
具体操作:(建表后添加。主键,唯一,外键用 add,drop;默认值用 set, drop;非空,自增用 modify )
1.主键约束
添加:alter table table_name add primary key (字段)
删除:alter table table_name drop primary key
2.唯一约束
添加:alter table table_name add unique 约束名(字段)
删除:alter table table_name drop key 约束名
3.默认值
添加:alter table table_name alter 列名 set default '值'
删除:alter table table_name alter 列名 drop default
4.非空约束
添加:alter table table_name modify 列名 数据类型 not null
删除:alter table table_name modify 列名 数据类型 null
5.自动增长
添加:alter table table_name modify 列名 int auto_increment
删除:alter table table_name modify 列名 int
6.外键约束
添加:alter table table_name add constraint 约束名
foreign key(外键列)
references 主键表(主键列)
删除外键约束:(需要删除 外键约束 和 外键索引)
第一步:删除外键:
alter table table_name drop foreign key 约束名
第二步:删除索引:
alter table table_name drop index 索引名
注:约束名和索引名一样
外键行为:![](https://i-blog.csdnimg.cn/blog_migrate/3ddd6fd8b361746103bf11fc3ae79d2e.png)
语法:alter table 表名 add constraint foreign key (外键字段) references 主表名(主表字段名) on update cascade on delete set null;
8、多表查询
多表关系:一对一,一对多,多对多。
自然连接。内连接。外连接:左外连接,右外连接。自连接。
自然连接: 自动判断列名和数据类型相同的列,并已此列为连接条件(natural join)
using:自动连接有时会自动判断列出错,通过using可以指定自然连接的列
1、内连接:(不加 where 条件会造成笛卡儿积现象)
隐式内连接:select 字段列表 from 表1,表2 where 条件......;
显式内连接:select 字段列表 from 表1 inner join 表2 on 连接条件......;
2、外连接
左外连接:select 字段列表 from 表1 left join 表2 on 条件......;
右外连接:select 字段列表 from 表1 right join 表2 on 条件......;
3、自连接(自己连接自己)
select 字段列表 from 表1 join 表1 on 条件......;
4、联合查询
把两个查询结果合并起来,两个查询语句字段列表类型和个数要一致。
union all (不去重)
union(去重)
9、子查询
1、标量子查询(内层子查询返回为一个值)
2、列子查询(子查询返回为一列)
常用操作符:in, not in, any, some, all
3、行子查询(子查询返回为一行)
常用操作符:=, <>, in, not in
语法:
select 字段列表 where(字段列表1,字段列表2,.......)操作符 (子查询)
注:子查询返回的行数要与字段列表相同,代表:字段列表1与子查询的第2行作比较,字段列表2与子查询的第2行作比较 ...... 。即:(a, b, c) = (1, 2, 3) => a=1, b=2, c=3
4、表子查询(子查询返回为多行)
常用操作符:in
注:1、行子查询进阶版。(a, b, c) in (1, 2, 3)(4, 5, 6) => a=1, b=2, c=3和 a=4, b=5, c=6 两个条件。
2、子查询还可以作表,参与外连接等操作
10、事务
mysql 事务默认自动提交
控制事务方式一自动提交:
查询mysql事务是否自动提交语句:
select @@autocommit;
设置是否自动提交语句:
set @@autocommit = 0/1;(只有本次会话有效)
1代表自动,0代表手动
提交事务语句:commit;
回滚事务语句:rollback;
方式二手动提交:
开启事务:start transaction; 或 begin;
提交事务语句:commit;
回滚事务语句:rollback;
事务四大特性:
并发事务问题:(脏读,不可重复读,幻读)
事务隔离级别:(安全性越高,效率越低)![](https://i-blog.csdnimg.cn/blog_migrate/bc4f4584edbcfd86edfd54157d61e628.png)
查看事务级别语句:select @@transaction_isolation;
设置事务隔离级别:set [session/global] transaction isolation level 事务隔离级别
11、存储引擎
1、mysql体系结构:
2、存储引擎:
默认引擎:InnoDB
查看当前数据库支持的存储引擎:show engines;
1、在创建表时,指定存储引擎
create table 表名(
#语句
) engine = 引擎名;
2、存储引擎特点:
InnoDB: 兼顾高可靠性和高性能的通用存储引擎,MySQL5.5后成为默认引擎
特点:DML操作遵循ACID模型,支持事务;
行级锁,提高并发访问性能;
支持外键约束,保证数据的完整性和正确性。
MyISAM: 早期mysql默认
特点:1、不支持事务和外键
2、支持表锁,不支持行锁
3、访问速度快
Memory: 存储在内存,只能临时用
特点:1、内存存放,速度快
2、底层hash索引
3、存储引擎选择:![](https://i-blog.csdnimg.cn/blog_migrate/0decabc88f581829b1eba8412fae653c.png)
12、索引
1、索引优缺点:
B+树索引结构:
Hash索引:
特点:1、只能用于对等比较(=,in),不支持范围查询(>,
2、无法利用索引完成排序操作
3、查询效率高,通常只需要一次检索就可以了,效率通常要高于B+树
支持hash索引的只有Memory引擎,而InnoDB中具有自适应hash功能,hash索引是存储引擎根据B+树索引在指定条件下自动构建的。
2、索引分类
聚集索引:必须有且只能有一个,为主键,没有为第一个唯一索引字段,没有就字段生成一个虚拟键
二级索引:可以又多个
3、索引语法:
1、查询索引:show index from 表名
2、创建索引:create [ unique/fulltext ] index 索引名 on 表名( 字段1,字段2,......);
3、删除索引:drop index 索引名 on 表名;
4、sql 性能分析
1、查看sql执行频率语句:
show global status like 'Com______';(7个_)
2、慢查询日志:
查看慢查询日志状态:show variables like 'slow_query_log';(默认关闭)
设置打开慢查询日志:修改/etc/my.cnf,加入:
slow_query_log=1;#开启mysql慢日志
long_query_time=2;#设置慢日志时间为2秒,超过2秒的语句会被记录
慢日志文件位置:/var/lib/mysql/localhost-slow.log(注:localhost是自己的主机名)
总结:根据sql语句执行频率和慢查询日志进行对这类语句进行优化
3、profile 详情
能够查看每一条语句的执行情况。
查看数据库是否支持profile,通过have_profiling参数:
select @@have_profiling;
默认关闭,开启profiling:
select @@profiling; //查看是否开启
set profiling = 0/1; //1代表开启,0代表关闭
之后就可以通过以下语句操作profile:
show profiles; #查看每一条SQL的耗时情况
#查看指定query_id的sql语句各阶段耗时情况
show profile for query query_id;
#查看指定query_id的sql语句cpu的使用情况
show profile cpu for query query_id;
4、explain 执行计划
除查看select基本信息外,还可以查看select语句执行过程中表如何连接以及连接的顺序。
语法:(直接在 select 语句之前加上关键字 explain/desc )
explain select 字段列表 from 表名 where 条件;
主要依次关注:type -> possible_keys -> key -> key-len -> Extra
5、索引使用规则
1、最左前缀法则:(顺序无所谓,最左列存在即可)
2、范围索引:( >会中断后续列使用索引,但>=不会,所以尽量使用带=的范围条件)
3、索引列运算:不要在索引列上进行运算操作,索引会失效
4、字符串不加引号:查询字符串类型字段不加引号会使索引失效
5、模糊查询:如果仅仅尾部模糊,索引不会失效;只要头部迷糊,索引会失效
6、or 连接的条件:如果or连接的条件只有一边有索引,索引失效;都有才生效
7、SQL提示:是优化数据库的一个重要手段,通过人为提示来达到优化数据库的目的
use index (索引名): 建议使用这个索引(可以不使用)
ignore index (索引名): 忽视这个索引
force index (索引名): 强制使用这个索引
explainselect 字段列表 from 表名 use index(索引名) where 条件;
//use index() 处选择这三种之一
8、覆盖索引与回表查询:如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引’。即只需扫描索引而无须回表。
9、前缀索引:为了避免存储很长的字符串,查询时浪费大量磁盘IO。只将字符串的一部分前缀作为索引,提高效率。
语法:create index 索引名 on 表名(列(前缀长度));
前缀长度选择:尽量使截取的部分重复率小,并且尽量使截取的长度小
10、单列索引和联合索引:查询字段同时存在两个索引,系统会字段判断选择性能好的索引(推荐使用联合索引)
6、索引设计原则
13、SQL优化
1、insert 优化:
批量插入,手动提交事务,主键顺序插入
大批量插入数据:使用load指令(千条以上)
#客户端连接服务器时,加上参数 --local-infile
mysql --local-infile -u root -p
#设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;
#执行load指令将准备好的数据,加载到表结构中
load data local infile '文件路径名' into table '表名' fields terminated by '分隔符' lines terminated by '一行结束符';
#例如:
load data local infile '/root/sql.log' into table 'tb_user' fields terminated by ',' lines terminated by '\n';
2、主键优化
1、页分裂:
2、页合并:
3、主键设计原则:
3、order by 优化
触发器
创建语法:
create trigger 触发器名字
before/after insert/update/delete
on 表名 for each row
begin
语句体;
end;
查看触发器:show triggers;
删除:drop trigger [数据库名] 触发器;没有指定数据库名,默认删除本数据库的。
关键字 old 和 new:old代表旧数据,new代表新数据
注:行级触发器,语句每影响一行,触发器就触发一次。
//TODO 后续待更新
14、锁
1、全局锁:
对整个数据库实例加锁,加锁后只能查,不能增删改。
加全局锁语句:
flush tables with read lock;
2、表级锁
每次锁住一张表
1、表锁:表共享读锁(read),表独占写锁(write)
语法:
加锁:lock tables 表名... read/write 释放锁:unlock tables 或客户端断开连接。
读锁:自己和其他客户端都只能查,不能增删改。
写锁:自己客户端可以增删改查,其他客户端增删改查都不行。
2、元数据锁:
系统会自动加元数据锁。为了避免DML和DCL冲突。
3、意向锁:
加意向锁:
与其他锁的互斥性:
3、行级锁
每次加锁锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。
间隙锁主要避免出现幻读现象
15、JDBC
JDBC编程六步(需要背会)
1.注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
2.获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
3.创建数据库操作对象(专门执行sql语句的对象)
4.执行SQL语句(DQL,DML…)
5.处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
6.释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)
需要用到的类和方法
1、DriverManager类(都是静态方法):
registerDriver( Driver对象 ) 注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
getConnection( url, user, password ) 连接数据库
2、Connection类:
Statement createStatement() 创建一个 Statement对象,用于将SQL语句发送到数据库(连接数据库后,必须通过此方法创建sql语句操作数据库)
commit() 提交事务
rollback() 回滚
setAutoCommit(boolean) 设置是否默认提交事务
3、Statement类:
int executeUpdate(String sql) 执行给定的增删改SQL语句,返回受影响的行数,0表示执行失败。
ResultSet executeQuery(String sql) 执行给定的查询SQL语句,返回一个 ResultSet 结果集对象
4、ResultSet类:
boolean next() 将光标移动到数据的下一行,返回false表示下一行没有数据了
getXXX( index ) 返回指定索引行的数据,XXX为数据类型,对于 sql 返回的列数据类型,String可以接受任意数据类型的 sql 值,但操作返回值时需要强转。
5、Properties类:(java 读取 properties 配置文件)
构造方法:
Properties() 创建一个Properties对象。
常用方法:
load(InputStream inStream) 连接Properties文件
load(Reader reader) 连接Properties文件
getProperty(String key) 获取指定键的值。
三种配置方式
1、mysql下载驱动,导入依赖
2、mysql下载驱动,导入依赖
后面同方法一。
3、maven导入依赖(推荐)
然后下滑选择想要的版本,点击。如图选择5.1.49版本为例:
然后将指定的内容添加到pom.xml文件中。
连接mysql
第一种连接方式:
DriverManager类:
registerDriver( Driver对象 ) 注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
getConnection( url, user, password ) 连接数据库
public static void main(String[] args) throws SQLException {
// ## 五、JDBC编程六步(需要背会)
// 1.注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
DriverManager.registerDriver(new Driver());
// 2.获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.10.100:3306/lianxi?useUnicode=True&characterEncoding=utf8&useSSL=false", "root", "123456");
// 3.创建数据库操作对象(专门执行sql语句的对象)
Statement statement = conn.createStatement();
// 4.执行SQL语句(DQL,DML…)
int i = statement.executeUpdate("insert into student values('110','lisa','女',20,'95031')");
if (i == 1) {
System.out.printf("插入成功");
} else System.out.printf("插入失败");
// 5.处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
// 6.释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)
statement.close();
}
第二种连接方式:(反射注册驱动)
除注册驱动不同外,其余全部相同。
Class.forName("com.mysql.jdbc.Driver");
三:还可以用配置文件存储连接信息
//properties文件:
DriverName=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.10.100:3306/lianxi?useUnicode=True&characterEncoding=utf8&useSSL=false
user=root
passwd=123456
//通过java读取properties文件中的内容即可
增删改查:
增删改相同,执行相应的 sql 语句即可。例如:
public static void main(String[] args) throws SQLException {
// ## 五、JDBC编程六步(需要背会)
// 1.注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
DriverManager.registerDriver(new Driver());
// 2.获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.10.100:3306/lianxi?useUnicode=True&characterEncoding=utf8&useSSL=false", "root", "123456");
// 3.创建数据库操作对象(专门执行sql语句的对象)
Statement statement = conn.createStatement();
// 4.执行SQL语句(DQL,DML…)
int i = statement.executeUpdate("insert into student values('110','lisa','女',20,'95031')");
if (i == 1) {
System.out.printf("插入成功");
} else System.out.printf("插入失败");
// 5.处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
// 6.释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)
statement.close();
}
查询不用 executeUpdate() 方法,用 executeQuery() 方法。
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
Properties properties = new Properties();
properties.load(new FileReader("C:\\customFiles\\javaFiles\\JDBCtest\\JDBCtest\\src\\main\\resources\\MySqlFile.properties"));
Class.forName(properties.getProperty("DriverName"));
Connection connection = DriverManager.getConnection(properties.getProperty("url"), properties.getProperty("user"), properties.getProperty("passwd"));
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from student");
while (resultSet.next()){
String sno = resultSet.getString(1);
String sname = resultSet.getString(2);
String sgender = resultSet.getString(3);
int sage = resultSet.getInt(4);
String sclass = resultSet.getString(5);
System.out.println("学号:" + sno + ", 姓名:" + sname + ", 性别:" + sgender + ", 年龄:" + sage + ", 班级:" + sclass);
}
statement.close();
}
sql注入
预编译防止sql注入
第四行把要运行的条件写出 ?占位符,编译后再通过setString( index, value ....)方法传入值,把每个传入的数据仅看作字符串,不具备其他任何特殊含义,可以有效防止 sql 注入
public static void main(String[] args) throws SQLException {
DriverManager.registerDriver(new Driver());
Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.10.100:3306/lianxi?useUnicode=True&characterEncoding=utf8&useSSL=false", "root", "123456");
PreparedStatement statement1 = conn.prepareStatement("select * from student where sno=?");
statement1.setString(1, "101");
ResultSet resultSet = statement1.executeQuery();
while (resultSet.next()) {
String sno = resultSet.getString(1);
String sname = resultSet.getString(2);
String sgender = resultSet.getString(3);
int sage = resultSet.getInt(4);
String sclass = resultSet.getString(5);
System.out.println("学号:" + sno + ", 姓名:" + sname + ", 性别:" + sgender + ", 年龄:" + sage + ", 班级:" + sclass);
}
resultSet.close();
}
模糊查询
由于%本来就是字符,所以不用特别处理,预编译支持。
事务
//开启事务方法
conn.setAutoCommit(false);
//提交事务
conn.commit();
//回滚
conn.rollBack();
乐观锁和悲观锁
悲观锁:事务必须排队执行。数据锁住了,不允许并发。 (行级锁: select后面添加for update )
乐观锁:支持并发,事务也不需要排队,只不过需要一个版本号。
1、悲观锁
顾名思义,就是比较悲观的锁,总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
2、乐观锁
反之,总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。
数据库连接池
Druid(德鲁伊)连接池
//1、导入jar包
见下
//2、定义配置文件
见下
//3、加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("配置文件路径"));
//4、获取连接处对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5、获取数据库连接
Connection connection = fataSource.getConnection();
//之后就可以利用connction进行数据库操作了(同普通jdbc)
1、导入jar包
maven或下载
2、定义配置文件