MySQL

> 数据库
> 操作系统,数据结构与算法
> 离散数学,数字电路,体系结构,编译原理

数据库

::DB::(DataBase)
概念:软件 安装在操作系统之上
作用:存储,管理


数据库分类

关系型:SQL

  • MySQL Oracle SqlServer DB2 SQLlite

非关系型:NoSQL

  • Redis MongDB

::DBMS::数据库管理系统


MySQL简介

是一个关系型数据库管理系统
5.7稳
8.0
尽量不要使用exe
使用压缩包安装


数据库语言

CRUD增删改查

DDL 定义

DML 操作

DQL 查询

DCL 控制


操作数据库

不区分大小写

操作数据库(了解)

  1. 创建数据库

    create database [if not exists] school
    
  2. 删除数据库

    drop database [if exists] school 
    
  3. 使用数据库

    USE `school`
    
  4. 查询数据库

    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&gt;=90 and studentresult&lt;=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&gt;=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&gt;0 负&gt;-1 正&gt;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密码 数据库 表明 &gt;物理磁盘位置/文件名
    mysqldump -hlocalhost -uroot -p123456 school student &gt;D:/a.sql
    mysqldump -hlocalhost -uroot -p123456 school student result &gt;D:/b.sql
    #导入
    # 登录
    mysql -uroot -p123456
    use school
    source d:/a.sql
    # 未登录 mysql -u用户名 -p密码 库名&lt; 备份文件
    
    

数据库的归约,三大范式

规范数据库设计

  • 分析需求:分析业务和需求处理的数据库的需求
  • 概要设计:设计关系图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、导入数据库驱动

  • image-20210517142651097
  • 将mysql-connector-java-5.1.47.jar粘贴到lib目录下
  • 右键lib->add as library
  • image-20210518161249675

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&amp;characterEncoding=utf8&amp;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&amp;characterEncoding=utf8&amp;useSSL=true";
// jdbc:mysql://主机地址:端口号/数据库名?参数1&amp;参数2&amp;参数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&gt;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&gt;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&gt;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&gt;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注入,效率更高

  1. 新增

  2. 删除

  3. 更新

    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&gt;0){
                    System.out.println("更新成功!");
                }
    
    
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(co,st,rs);
            }
    
    
        }
    }
    
    
  4. 查询

    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);
            }
        }
    }
    
    
  5. 防止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