MySQL

> 数据库
> 操作系统,数据结构与算法
> 离散数学,数字电路,体系结构,编译原理
数据库
::DB::(DataBase)
概念:软件 安装在操作系统之上
作用:存储,管理
数据库分类
关系型:SQL
- MySQL Oracle SqlServer DB2 SQLlite
非关系型:NoSQL
- Redis MongDB
::DBMS::数据库管理系统
MySQL简介
是一个关系型数据库管理系统
5.7稳
8.0
尽量不要使用exe
使用压缩包安装
数据库语言
CRUD增删改查
DDL 定义
DML 操作
DQL 查询
DCL 控制
操作数据库
不区分大小写
操作数据库(了解)
-
创建数据库
create database [if not exists] school -
删除数据库
drop database [if exists] school -
使用数据库
USE `school` -
查询数据库
SHOW DATABASES --查看所有数据库
数据库列类型
> 数值
- tinyint 1字节
- smallint 2字节
- mediumint 3字节
- int 4字节
- bigint 8字节
- float 4字节
- double 8字节
- decimal 金融计算使用
> 字符串
- char 0~255
- varchar 0~65535
- tinytext 2^8-1
- text 2^16-1 保存大文本
> 时间日期
java.util.Date
- date YYYY-MM-DD 日期
- time HH:mm:ss 时间
- datetime YYYY-MM-DD HH:mm:ss
- timestamp 时间戳 1970.1.1到现在的毫秒数
- year 年份
> null
- 没有值
- 注意:不要用null进行运算
数据库的字段属性(重点)
Unsigned:
- 无符号的整数
- 不能声明为负数
ZF zerofill:
- 0填充的
- 不足的位数,使用0来填充
自增UN:
- 自动在上一条记录的基础上+1
- 通常用来设计主键,必须为整数
- 可自定义设计主键自增的起始值、步长
非空NN:
- 必须有值
- null不填默认是null
默认:
- 设置默认值
基本字段:
| id | 主键 |
| version | 乐观锁 |
| is_delete | 伪删除 |
| gmt_create | 创建时间 |
| gmt_update | 修改时间 |
创建数据库表
-- not null非空 auto_increment自增 comment注释 default默认值
create table if not exists `student`(
`id` int(4) not null auto_increment comment '学号',
`name` varchar(30) not null default '匿名' comment '姓名',
`pwd` varchar(20) not null comment '密码',
`sex` varchar(2) not null default '女' comment '性别',
`birthday` datetime default null comment '出生日期',
`address` varchar(100) default null comment '地址',
`email` varchar(50) default null comment '邮箱',
primary key(`id`)
)engine=innodb default charset=utf8
格式
create table [if not exists] '表明'(
`字段名` 列类型 [属性] [索引] [注释],
...
`字段名` 列类型 [属性] [索引] [注释]
)[表类型][字符集设置][注释]
常用命令
show create database school -- 查看创建数据库的语句
show create table student -- 查看数据表的定义语句
desc student -- 显示表的结构
数据表类型
INNODB 默认
MYISAM 早年
| MYISAM | INNODB | |
|---|---|---|
| 事务支持 | × | √ |
| 数据行锁定 | × | √ |
| 外键 | × | √ |
| 全文索引 | √ | × |
| 表空间大小 | 小 | 大 |
| 节约空间,速度快 | 安全性高,多表多用户操作 |
所有数据存在data
修改删除表
-- 修改表名 alter table 旧表名 rename as 新表名
alter table studenta rename as student
-- 增加字段 alter table 表名 add 字段名 列属性
alter table student_a add age int(11)
-- 修改字段
-- alter table 表名 modify 字段名 列属性
alter table student_a modify age varchar(11) -- 修改约束
-- alter table 表名 change 字段名 列属性
alter table student_a change age age1 int(11) -- 重命名
-- 删除字段 alter table 表名 drop 字段名
alter table student_a drop age1
-- 删除表
drop table if exists student_a
所有创建删除尽量加上判断
MySQL数据管理
外键(了解)
alter table `student` add constraint `FK_gradeid` foreign key(`gradeid`) references `grade`(`gradeid`);
以上为物理外键,不建议
DML语言(全部记住)
DML语言:数据操作语言
- insert
- update
- delete
添加
-- insert into 表名([字段名1,字段名2,字段名3])value('值1','值2','值3')
insert into `grade`(`gradename`,`pwd`) values('大四','qqqqqq')
insert into `grade`(`gradename`) values('大三'),('大四')
修改
-- update 表名 set 列名='具体值'[,`列名`='具体值',...] where 条件
update `student` set `name`='aa' where id = 1
where条件(一定要写!)
| 操作符 | 含义 | 范围 | 结果 |
|---|---|---|---|
| = | 等于 | 5=6 | false |
| <>或!= | 不等于 | 5<>6 | true |
| > | |||
| < | |||
| <= | |||
| >= | |||
| between...and... | 在...之间 | [2,5] | |
| and | 和 | ||
| or | 或 |
current_time变量时间
删除
delete from `student` where id = 1;
清空
truncate `student`
> truncate 和 delete区别
-
相同点:都能删除数据,都不会删除表结构
-
不同点:
truncate 重新设置自增列 计数器归零,不会影响事物
delete删除的问题,重启数据库:(了解)
- innoDB 自增列从1开始(存在内存中,断电即失)
- MyISAM从上个增量开始(存在文件中,不丢失)
DQL查询数据(最重点)
Date Quary LANGUAGE(DQL)
select语法
select [all|distinct]
{*|table.*|[table.field1[as alias1][,table.field2[as alias2][,...]]}
from table_name [as table_alias]
[left|right|inner join table_name2] -- 联合查询
[where ...] -- 满足条件
[group by ...] -- 结果按哪几个字段分组
[having] -- 过滤分组的字段记录必须满足次要条件
[order by ...] -- 指定查询记录按一个或多个条件排序
[limit {[offset,]row_count|row_countoffset offset}]; -- 指定查询记录从哪条至哪条
Select字段
-- select 字段,... from 表
select * from student
select `name`,`pwd` from student
select `name` as 姓名,`pwd` as 密码 from student as 学生表 -- 别名as
-- 函数 concat(a,b)拼接字段
select concat('姓名:',name) as 新名字 from student;
-- 结果 新名字
-- 姓名:aaa
distinct 去重
select distinct `gradename` from grade
表达式
文本、列、null、函数、计算表达式、系统变量
-- select 表达式 from 表
select version() -- 查版本号(函数)
select 100*3-1 as 计算结果 -- 计算(表达式)
select @@auto_increment_increment -- **查询自增步长(变量)**
select `id`,`age`+1 as '加一岁后' from student
where条件子句
返回布尔值
逻辑运算符
| 运算符(尽量用英语) | 描述 |
|---|---|
| and && | 与 |
| or || | 或 |
| not ! | 非 |
select `studentid`,`studentresult` from result
where studentresult>=90 and studentresult<=100
select `studentid`,`studentresult` from result
where studentresult between 90 and 100
模糊查询:比较运算符
| 运算符 | 语法 | 描述 |
|---|---|---|
| is null | a is null | null为真 |
| is not null | a is not null | 不为null为真 |
| between | a between b and c | 之间为真 |
| like | a like b 注:结合%和_使用 | 字符中有b |
| in | a in (a1,a2,a3...) 注意:a1...必须为具体值 | 为其中的某个值为真 |
-- like %(任意个字符) _(一个字符)
select `id`,`name` from `student`
where name like 'a_' -- 查询姓a的
where name like '%a%' -- 查询名字中有a的
联表查询

-- join(连接的表) on(判断的条件) 连接查询
-- where 等值查询(可以把on改成where)
-- inner join 交集
select s.studentid,studentname,strdentresult
from student as s
inner join result as r
where s.studentid = r.studentid
-- right join 右查询
select s.studentid,studentname,strdentresult
from student as s
right join result as r
on s.studentid = r.studentid
-- left join 左查询
select s.studentid,studentname,strdentresult
from student as s
left join result as r
on s.studentid = r.studentid
| 操作 | 描述 |
|---|---|
| inner join | 如果表中至少有一个匹配就返回 |
| right join | 返回所有右表值,即使左表中没有 |
| left join | 返回所有左表值,即使右表中没有 |
-- 查参加了考试的同学的学号,姓名,科目,分数
select s.studentid,studentname,subjectid,result
from student as s
right join result as r
on r.studentid=s.studentid
inner join subject as sub
on r.subjectid=sub.subjectid
查哪些数据 select... 注意:如有相同数据必须(表明.数据)
在那几个表中 from 表 as 别名
*什么连接方式 xxx join 连接的表 as 别名
*什么条件 on 交叉条件
*什么连接方式 xxx join 连接的表 as 别名
*什么条件 on 交叉条件
> from a right join b
> from a left join b
自连接
核心:一张表拆为两张一样的表
父类
| myid | name |
|---|---|
| 2 | 水果 |
| 3 | 蔬菜 |
| 4 | 其他 |
子类
| fatherid | myid | name |
|---|---|---|
| 2 | 5 | 西瓜 |
| 3 | 6 | 西兰花 |
| 4 | 7 | 大米 |
| 4 | 8 | 飞机 |
父类---子类(结果)
| 父类 | 子类 |
|---|---|
| 水果 | 西瓜 |
| 蔬菜 | 西兰花 |
| 其他 | 大米 |
| 其他 | 飞机 |
select name as '父',name as '子'
from things as f,things as z
where f.myid=z.fatherid
分页limit和排序order by
排序:升序降序
order by result asc -- 升序
order by result desc -- 降序
分页
语法:limit 起始值,页面大小
limit 0,5 显示1~5条数据
limit 1,5 显示2~6条数据
-
pagesize:页面大小
-
n:当前页
-
(n-1)*pagesize起始值
-
总数/页面大小=总页数
-- 查询学生id,姓名,课程,分数
select s.studentid,studentname,subject,result
from student s
inner join result r
on r.studentid=s.studentid
inner join subject sub
on r.subjectid=sub.subjectid
where subjectname='数据结构'
order by result asc -- 升序
limit 5,5
子查询
where(这个值是计算出来的)
本质:在where语句中嵌套一个子查询语句
-- 查询分数不小于80分的学生学号和姓名
select distinct studentid,studentname
from student where studentid in(
select studentid from result where result>=80 and studentid=(
select subjectid from subject where subjectname ='高等数学'
)
)
mysql函数
常用函数
-- 数学运算
select abs(-8) -- 绝对值
select ceiling(9.4) -- 向上取整
select floor(9.4) -- 向下取整
select rand() -- 0-1随机数
select sign() -- 判断数的符号 0>0 负>-1 正>1
-- 字符串
select char_length('产生的') -- 字符串长度3
select concat('我','爱') -- 拼接
select insert('成都市',1,2,'是') -- (原值,开始位置,个数,替换的值) 是市
select lower('LOVE') -- love
select upper('love') -- LOVE
聚合函数(常用)
- sun()
- count()
- ave()平均
- max()
- min()
select now()现在时间
md5()加密
分组和过滤
group by
having
分组
ACID原则:
原子性
一致性
持久性
隔离性(问题:脏读、不可重复的、幻读)
-- 事物自动提交关闭
set autocommit = 0
-- 开始事物
start transaction
insert (update)
insert (update)
-- 提交
commit
-- 回滚
rollback
-- 事物自动提交开启
set autocommit = 1
-- 了解
savepoint -- 保存点
rollback to savepoint -- 回滚到保存点
release savepoint -- 撤销保存点
索引(找的快)
索引分类
-
主键索引(PRIMARY KEY)
-
唯一索引 (UNIQUE KEY)
-
常规索引 (KEY/INDEX)
-
全文索引 (FULLTEXT)
快速定位数据
myisam才有
测试索引explain
-- 创建表增加索引
alter table school.student add fulltext index `name`(`name`);
explain -- 分析SQL执行状况
explain select * from student; -- 常规索引
explain select * from student where match(name) against('刘');
-- 不用看
delimiter $$ -- 写函数前必写,标志
create function mock_data() -- 创建函数,了解
returns int -- 返回值
begin -- 开始
declear num int default 1000000; -- 定义
declear i int default 0; -- 定义
while i<num do="" --="" 循环插入="" insert="" into="" num(`numname`,`num`)="" value="" (concat('用户',i),concat('18',floor(rand()*((8999999999-100000000)+100000000)));="" set="" i="i+1;" end="" while;="" return="" i;="" end;="" select="" mock_data()="" num(`num`)="" concat('18',floor(rand()*((8999999999-100000000)+100000000))="" ```="" ```sql="" *="" from="" num="" where="" `name`="用户9999" ;="" id_表名_字段名="" create="" index="" 索引名="" on="" 表(字段)="" id_num_numname="" num(`numname`)="" 创建索引两种方式="" alter="" table="" school.student="" add="" `name`(`name`);="" ###="" 索引原则="" -="" 不是越多越好()="" 不要对经常变动的数据加索引="" 小数据量不需要索引="" 索引一般加在经常查询的字段上="" 索引的数据结构="" hash类型的索引="" btree:innodb默认的数据结构="" 参考:https:="" blog.csdn.net="" wufuhuai="" article="" details="" 79631466(看!!!!)="" ##="" 权限管理="" 用户管理=""> sql命令
用户表:user
本质:对这张表增删改查
- **创建用户 create user 用户名 identified by '密码'**
```sql
create user new identified by '123456'
-
修改密码
-- 修改当前密码 set password = password('1111') -- 修改指定密码 set password for new = password('1111') -
重命名 rename user 原名 to 新名
rename user new to new1 -
用户授权 all privileges 全部权限 ,库 表
grant all privileges on *.* to new -- 除了给别人授权,其他权限都有 -
查询权限
show grants for new show grants for root@localhost -- 查看root权限 -
root权限
grant all privileges on *.* to 'root@localhost' with grant option -
撤销权限
revoke all privileges on *.* from new -
删除用户
drop user new
备份
why:
-
保证重要数据不丢失
-
数据转移
数据库备份方式:
-
拷贝物理文件(磁盘文件夹data文件)
-
可视化工具(右键[数据库、表]导出)
-
命令行 mysqldump(cmd)
# 导出 # mysqldump -h主机 -u用户名 -p密码 数据库 表明 >物理磁盘位置/文件名 mysqldump -hlocalhost -uroot -p123456 school student >D:/a.sql mysqldump -hlocalhost -uroot -p123456 school student result >D:/b.sql #导入 # 登录 mysql -uroot -p123456 use school source d:/a.sql # 未登录 mysql -u用户名 -p密码 库名< 备份文件
数据库的归约,三大范式
规范数据库设计
- 分析需求:分析业务和需求处理的数据库的需求
- 概要设计:设计关系图e-r图
设计数据库步骤
- 收集信息,分析需求
- 标识实体(把需求落地到每个字段)(xx表,xx表)
- 标识实体之间的关系(xx表-xx表)
三大范式
- 第一范式(1NF)
- 原子性:保证每一列不可再分
- 第二范式(2NF)
- 前提:满足第一范式
- 每张表只描述一件事
- 第三范式(3NF)
- 前提:满足第一、二范式
- 每一列与主键直接相关
规范和性能问题:
关联查询的表不得超过三张表
JDBC(重点)
数据库驱动
JDBC
简化开发人员(对数据库统一)操作,提供的(java操作数据库的)规范称JDBC
java.sql
javax.sql
导入一个数据库驱动包 mysql-connector-java-5.1.47.jar
JDBC项目
> 创建测试数据库
create database jdbcstudy character set utf8 collate utf8_general_ci;
use jdbcstudy;
create table users(
id int primary key,
name varchar (40),
password varchar(40),
email varchar(60),
birthday date
);
insert into users(id,name,password,email,birthday)
values(1,'zhangsan','123456','zs@sina.com','1980-12-04'),
(2,'lisi','123456','ls@sina.com','1981-12-04'),
(3,'wangwu','123456','ww@sina.com','1982-12-04');
1、idea创建一个普通项目
2、导入数据库驱动
- 将mysql-connector-java-5.1.47.jar粘贴到lib目录下
- 右键lib->add as library
3、编写测试代码
- 右键src->new->package->com.jdbc.lesson01
- 右键lesson01->new->java class->First
package com.jdbc.lesson01;
import java.sql.*;
public class FirstDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//固定写法
//2.用户信息和url
String url ="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
//useUnicode支持中文编码 characterEncoding设定中文字符集为utf-8 useSSL使用安全
String username = "root";
String password = "123456";
//3.连接数据库成功 Connection代表数据库
Connection connection = DriverManager.getConnection(url,username,password);//驱动管理获得链接
//4.执行sql的对象 Statement执行sql对象
Statement statement = connection.createStatement();
//5.执行sql的对象执行sql,查看返回结果
String sql ="select * from users";
ResultSet resultSet = statement.executeQuery(sql);//返回的结果集
while (resultSet.next()){
System.out.println("id=" + resultSet.getObject("id"));
System.out.println("name=" + resultSet.getObject("name"));
System.out.println("password=" + resultSet.getObject("password"));
System.out.println("email=" + resultSet.getObject("email"));
System.out.println("birthday=" + resultSet.getObject("birthday"));
}
//6.释放连接
resultSet.close();
statement.close();
connection.close();
}
}
> DriverManager Connection
Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动
Connection connection = DriverManager.getConnection(url,username,password);
//connection代表数据库(数据库设置自动提交,事物提交,事务回滚)
connection.rollback();
connection.commit();
connection.setAutoCommit();
> URL
String url ="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
// jdbc:mysql://主机地址:端口号/数据库名?参数1&参数2&参数3
> Statement 执行sql的对象 PrepareStatement执行sql的对象
Statement statement = connection.createStatement();
statement.executeQuery(); // 查询操作返回resultset
statement.execute(); // 执行任何SQL
statement.executeUpdate(); // 更新、插入、删除都用这个,返回一个受影响的行数
> ResultSet 查询的结果集,封装了所有查询结果
获得指定的数据类型
ResultSet resultSet = statement.executeQuery(sql);
resultSet.getObject();
resultSet.getString();
resultSet.getInt();
遍历,指针
resultSet.beforeFirst();//移动到最前面
resultSet.afterLast();//移动到最后
resultSet.next();
resultSet。absolute();// 指定行
> 释放资源
resultSet.close();
statement.close();
connection.close();
statement对象(主要核心会变的)
向数据库发送sql语句,增删改查
两个方法
- executeQuery
- executeUpdate
> create 添加数据
executeUpdate
Statement statement = connection.createStatement();
String sql = "insert into user(...)values(...)";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.pringln("插入成功!!!");
}
> delete 删除
executeUpdate
Statement statement = connection.createStatement();
String sql = "delete from user where id=1";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.pringln("删除成功!!!");
}
> update 修改
executeUpdate
Statement statement = connection.createStatement();
String sql = "update user set name='' where name=''";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.pringln("修改成功!!!");
}
> read 查
executeQuery
Statement statement = connection.createStatement();
String sql = "select * from user where id=1";
ResultSet rs = statement.executeQuery(sql);
while(rs.next()){
//根据获取的数据类型,分别调用rs的相应方法映射到java对象中
}
> 代码实现
1、提取工具类(许多代码不变的)
package com.jdbc.lesson02.utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
static {
try{
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//1.驱动只用加载一次
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
//释放资源
public static void release(Connection co, Statement st, ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(co!=null){
try {
co.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2、编写增删改executeUpdate
// 增加
package com.jdbc.lesson02;
import com.jdbc.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestInsert {
public static void main(String[] args) {
Connection co =null;
Statement st =null;
ResultSet rs = null;
try {
co = JdbcUtils.getConnection();//获取连接
st = co.createStatement();//获得sql执行对象
String sql = "insert into users(id,name,password,email,birthday)" +
"values(5,'zasan','123456','z@sina.com','1980-10-04')";
int i = st.executeUpdate(sql);
if(i>0){
System.out.println("插入成功!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils.release(co,st,rs);
}
}
}
3、查询
package com.jdbc.lesson02;
import com.jdbc.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestSelect {
public static void main(String[] args) {
Connection co = null;
Statement st = null;
ResultSet rs = null;
try {
co = JdbcUtils.getConnection();
st = co.createStatement();
//SQL
String sql = "select * from users where id=1";
rs = st.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils.release(co,st,rs);
}
}
}
> SQL注入问题
sql存在漏洞,会被攻击,导致数据泄露
package com.jdbc.lesson02;
import com.jdbc.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SqlZhuru {
public static void main(String[] args) {
//login ("aaa","123456");
login ("'od '1=1","'or'1=1");
}
//登录业务
public static void login(String username,String password) {
Connection co = null;
Statement st = null;
ResultSet rs = null;
try {
co = JdbcUtils.getConnection();
st = co.createStatement();
//SQL
//select * from users where name=''or '1=1' and password =''or'1=1'
String sql = "select * from users where name='"+username+"' and password ='"+password+"'";
rs = st.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getString("name"));
System.out.println(rs.getString("password"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils.release(co,st,rs);
}
}
}

PrepareStatement对象
防止sql注入,效率更高
-
新增
-
删除
-
更新
package com.jdbc.lesson03; import com.jdbc.lesson02.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; public class TestUpdate { public static void main(String[] args) { Connection co = null; PreparedStatement st = null; ResultSet rs = null; try { co = JdbcUtils.getConnection(); //区别 //使用?占位符代替参数 String sql ="update users set name=? where id=?"; st = co.prepareStatement(sql);//预编译sql,先写sql不执行 //手动赋值 st.setString(1,"奥是"); st.setInt(2,1); //执行 int i = st.executeUpdate(); if(i>0){ System.out.println("更新成功!"); } } catch (SQLException e) { e.printStackTrace(); }finally { JdbcUtils.release(co,st,rs); } } } -
查询
package com.jdbc.lesson03; import com.jdbc.lesson02.utils.JdbcUtils; import java.sql.*; public class TestSelect { public static void main(String[] args) { Connection co = null; PreparedStatement st = null; ResultSet rs = null; try { co = JdbcUtils.getConnection(); String sql = "select * from users where id = ?"; st = co.prepareStatement(sql);//预编译 st.setInt(1,1);//传递参数 rs = st.executeQuery();//执行 if(rs.next()){ System.out.println(rs.getString("name")); } } catch (SQLException e) { e.printStackTrace(); }finally { JdbcUtils.release(co,st,rs); } } } -
防止sql注入
package com.jdbc.lesson03; import com.jdbc.lesson02.utils.JdbcUtils; import java.sql.*; public class SqlZhuru { public static void main(String[] args) { //login ("lisi","123456"); login ("''or 1=1","''or 1=1"); } //登录业务 public static void login(String username,String password) { Connection co = null; PreparedStatement st = null; ResultSet rs = null; try { co = JdbcUtils.getConnection(); //PreparedStatement把传递进来的参数当作字符,若存在转义字符则忽略,'会被转义 String sql = "select * from users where name=? and password=?"; st = co.prepareStatement(sql); st.setString(1,username); st.setString(2,password); rs = st.executeQuery(); while (rs.next()){ System.out.println(rs.getString("name")); System.out.println(rs.getString("password")); } } catch (SQLException e) { e.printStackTrace(); }finally{ JdbcUtils.release(co,st,rs); } } }
使用idea连接数据库

事务
都成功或都失败
ACID原则
package com.jdbc.lesson04;
import com.jdbc.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestTransation {
public static void main(String[] args) {
Connection co = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
co = JdbcUtils.getConnection();
//关闭自动提交功能,开启事务
co.setAutoCommit(false);
String sql1 = "update account set money = money-100 where name = 'q'";
st = co.prepareStatement(sql1);
st.executeUpdate();
String sql2 = "update account set money = money+100 where name = 'qq'";
st = co.prepareStatement(sql2);
st.executeUpdate();
//业务完毕
co.commit();
System.out.println("yes");
} catch (SQLException e) {
try {
co.rollback();//失败回滚
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JdbcUtils.release(co,st,rs);
}
}
}
数据库连接池
连接-释放 十分浪费系统资源
池化技术:预先准备一些资源
常用连接数=最小连接数
最大连接数(业务最高承载上限)
等待超时
编写连接池:实现一个接口DataSource
> 开源数据源实现
DBCP
C3P0
Druid:阿里巴巴
使用这些数据连接池后就不用写连接数据库代码了
> DBCP
需要用到的JAR包
commons-dbcp-1.4.jar commons-pool-1.6.jar
> C3P0
需要用到的JAR包
c3p0-0.9.5.5.jar mchange-commons-java-0.2.19.jar
DataSource接口不变,方法就不变
--以上是业务级别MySQL
浙公网安备 33010602011771号