MySQL基础

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、日期函数

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 索引名

注:约束名和索引名一样

外键行为:

语法: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;

事务四大特性:

并发事务问题:(脏读,不可重复读,幻读)

事务隔离级别:(安全性越高,效率越低)

查看事务级别语句: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、存储引擎选择:

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、定义配置文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值