MySQL


mysql安装地址: MySQL :: Download MySQL Community Server

mysql常用命令
exit;	--退出连接
flush privileges;	--刷新权限
show databases;	--查看所有数据库
show tables;	--查看所有表
desc table;		--查看表结构
use 数据库名称;	--切换数据库
describe 表名;	--显示表的信息
数据库数据类型

数值型

  • tinyint 十分小的数据 1个字节
  • smallint 较小的数据 2个字节
  • mediumint 中等大小的数据 3个字节
  • int 标准的整数 4个字节常用的
  • bigint 较大的数据 8个字节
  • float 浮点数 4个字节
  • double 浮点数 8个字节
  • decimal 字符串形式的浮点数金融计算的时候,一般是使用decimal

字符串

  • char 字符串固定大小 0~255
  • varchar 可变字符串 0~65535
  • tinytext 微型文本 2^8-1
  • text 文本串 2^16-1

时间

  • date YYYY-MM-DD 日期格式
  • time HH-mm-ss 时间格式
  • datetime YYYY-MM-DD HH-mm-ss 日期时间
  • timestamp 时间戳
  • year 年份
数据库基本概念

1、数据库英文单词:DataBase 简称:DB

2、什么是数据库?

​ 1、用于存储和管理数据的仓库

3、数据库的特点:

​ 1、持久化存储数据的,其实数据库就是一个文件系统

​ 2、方便存储和管理数据

​ 3、使用了统一的方式操作数据库

4、常见的数据库软件

​ 1、MYSQL:开源免费的数据库,小型数据库,已经被Oracle收购了,MYSQL6.0版本也开始收费了

​ 2、Oracle:收费的大型数据库,Oracle公司产品。Oracle公司收购了SUN公司,收购了MYSQL

​ 3、DB2:IBM公司的数据库产品,免费的。常应用在银行系统中

​ 4、SQLServer:Microsoft公司收费的中型的数据库。C#、.net等语言常使用

​ 5、SQLite:嵌入式的小型数据库,应用在手机端

5、mysql服务启动

​ 1、手动

​ 2、cmd–> Services.msc 打开服务窗口

​ 3、使用管理员打开cmd,输入net stop mysql 停止 net start mysql 启动

6、MySQL登录

​ 1、mysql -uroot -p密码

​ 2、mysql -hip -uroot -p连接目标的密码

​ 3、mysql --host=ip --user=root --password=连接目标的密码

7、MySQL退出

​ 1、exit

​ 2、quit

8、MySQL目录结构

​ 1、MySQL安装目录

​ 配置文件 my.ini

​ 2、MySQL数据目录

SQL

1、什么是 SQL?

​ Structured Query Language:结构化查询语言

​ 其实就是定义了操作所有关系型数据库的规则

2、SQL 通用语法

​ 1、SQL 语句可以单行或多行书写,以分号结尾

​ 2、可使用空格和缩进来增强语句的可读性

​ 3、MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写

​ 4、三种注释

​ 1.单行 注释:-- 注释内容 或 # 注释内容(MySQL特有)

​ 2.多行注释:/* 注释内容 */

3、SQL 分类

​ 1、DDL (Data Definition Language, DDL) 数据定义语言,

​ 用来定义数据库对象:数据库、表、列等,关键字:CREATE、ALTER、DROP等

​ 2、DML(Data Manipulation Language, DML)数据操纵语言,

​ 用来对数据库中表的数据进行增删改,关键字:insert、delete、update等

​ 3、DQL(Data Query Language, DQL) 数据查询语言 ,

​ 用来查询数据库中表的记录(数据),关键字:select、where等

​ 4、DCL(Data Control Language) 数据控制语言(了解即可),

​ 用来定义数据库的访问权限和安全级别,及创建用户,关键字:Grant、Revoke等

DDL:操作数据库、表
1、操作数据库:CRUD
1. C(Create):创建
	1. 创建数据库:create database 数据库名称;
    2. 创建数据库,并且判断名称是否存在:create database if not exists 数据库名称;
    3. 创建数据库,指定字符集:create database 数据库名称 character set 字符集名;
2. R(Retrieve):查询
    1. 查询所有数据库的名称:show databases;
    2. 查看某个数据库的字符集(创建语句):show create database 数据库名称;
	3. U(Update):修改
		1. 修改数据库字符集:alter database 数据库名称 character set 字符集名;
	4. D(Delete):删除
        1. 删除数据库:drop database 数据库名称;
        2. 判断数据库是否存在:drop database if exists 数据库名称;
	5. 使用数据库
        1. 查询正在使用的数据库名称:select database();
        2. 使用数据库:use 数据库名称;
2、创建表标准语句
CREATE TABLE IF NOT EXISTS `student`(
	`id` int(5) NOT NULL auto_increment COMMENT '学号',
	`name` varchar(20) not null DEFAULT '匿名' COMMENT '姓名',
	`pwd` varchar(20) not null DEFAULT '123456' COMMENT '密码',
	`sex` varchar(2) not null default '男' comment '性别',
	`birthday` datetime default null comment '出生年月',
	`address` varchar(50)  default null comment '住址',
	`email` varchar(20) default null comment '邮箱',
	primary key(`id`)
)engine=innodb default charset=utf8
3、操作表
  1. C(Create):创建
    1. 创建表:create table 表名(列名1 数据类型1,列名2 数据类型2…);
    2. 复制表:create table 表名 like 要复制的表名;
  2. R(Retrieve):查询
    1. 查询某个数据库中所有的表名称:show tables;
    2. 查询表结构:desc 表名;
  3. U(Update):修改
    1. 修改表名:alter table 表名 rename to 新的表名;
    2. 修改表的字符集:alter table 表名 character set 字符集名;
    3. 添加列:alter table 表名 add 列名 数据类型;
    4. 修改列名称和类型:alter table 表名 change 原来列名 新列名 新数据类型; change只能修改列名和字段类型
    5. 修改列名类型:alter table 表名 modify 列名 新数据类型; modify能修改字段的类型和约束
    6. 删除列: alter table 表名 drop 列名;
  4. D(Delete):删除
    1. 删除表:drop table 表名; 先判断在删除:drop table if exists表名;
DML:增删改表中数据
1、添加数据

​ 1.语法:insert into 表名(列名1, 列名2, …列名n) values(值1, 值2, …值n);

2、删除数据

​ 1.语法:delete from 表名 where 条件;如:delete from stu where id = 1;

​ 2.不加条件,会删除表中所有记录:

​ delete from 表名;(效率低,有多少条记录就会执行多少次删除操作)

​ TRUNCATE TABLE 表名;(效率高)先删除表,在创建一张一模一样的表

3、修改数据

​ 1.语法:update 表名 set 列名1 = 值1,列名2 = 值2…where 条件;

​ 2.不加条件,会删除表中所有记录:update 表名 set 列名1 = 值1,列名2 = 值2…;

DQL:查询

最基础查询语句:select * from 表名;

联表查询注意点:

  • 使用left join和right join 时,on和where的条件的区别如下
    • on条件是在生成临时表时使用的条件,不管on中的条件是否为真,都会返回左表中的记录。
    • where条件是在临时表生成好后,在对临时表进行过滤条件,条件不为真的就全部过滤。
  • 在使用inner join,on和where没有区别
操作描述
inner join只返回两个表中联结字段相等的行
left join返回左表中的所有记录 即使右表没有匹配
right join返回右表中的所有记录 即使左表没有匹配
1、语法
select
	字段列表
from
	表名列表
where
	条件列表
group by
	分组字段
having
	分组之后的条件
order by
	排序
limit
	分页限定
2、基础查询
-- 去除重复结果集 关键字DISTINCT
select DISTINCT address from student;

-- 计算 math + english 总和   空格或者as可以给字段取别名
select name, math, english, IFNULL(math,0) + IFNULL(english,0) 总分 from student;

-- ifnull(表达式1,表达式2) null参与的运算,计算结果都为null
	-- 表达式1 判断字段是否出现null
	-- 表达式2 替换null的值
3、条件查询
	1. where子句后跟条件
            		2. 运算符
   *  < 、 >、 <=、 >=、 =、<>
   * between...and
   * IN(集合)
   * LIKE ("-":单个任意字符;"%":多个任意字符)
   * IS NULL
   * and  或  &&
   * or  或  ||
   * not  或  !  
4、查询示例
-- 去除重复结果集
select DISTINCT address from student;

-- 计算 math + english 总和   空格或者as取别名
select name, math, english, IFNULL(math,0) + IFNULL(english,0) 总分 from student;

-- 查询年龄在20-40岁的,包含20和40
select name,age from student where age BETWEEN 20 and 40;
select name,age FROM student where age >= 20 && age <= 40; -- 方式2
select name,age FROM student where age >= 20 AND age <= 40; -- 方式3

-- 查询20岁、30岁、35岁的信息
select * FROM student where age = 20 or age = 30 or age = 35;
select * FROM student where age = 20 || age = 30 || age = 35;
select * FROM student where age in(20,30,35);

-- 查询英语成绩为null的学生
select * FROM student where english is null;

-- 查询英语成绩不为null的学生
select * FROM student where english is not null;

-- 查询姓马的学生
select * from student where name like '马%';

-- 查询第二个字是“云”的学生
select * from student where name like '_云%';

-- 查询名字是三个字的学生 三个下划线
select * from student where name like '___';

-- 查询名字包含“马”字的学生
select * frstudent where name like '%马%';

-- 给所有学生加 1 分
select id, result+1 from result

-- 查询版本号
select version()

--  ===============联表查询================
-- 查询 学生ID、学生姓名、科目ID、科目分数
select s.studentno,studentname,subjectno,studentresult
FROM student as s
inner join result as r
where s.studentno = r.studentno

-- 左连接查询
select s.studentno,studentname,subjectno,studentresult
FROM student as s
left join result as r
on s.studentno = r.studentno

-- 右连接查询
select s.studentno,studentname,subjectno,studentresult
from student as s
right join result as r
on s.studentno = r.studentno

-- 查询分数大于80 并且前五名 的学生(学号,姓名,科目名称,分数)
select s.studentno,studentname,studentresult,subjectname
from student as s
inner join result as r
on s.studentno = r.studentno
inner join `subject` sub
on sub.subjectno = r.subjectno
where r.studentresult > 80
order by studentresult desc
LIMIT 0,5

-- group by分租
select `subjectname`, sum(studentresult),avg(studentresult) as 平均分,max(studentresult),min(studentresult)
from result r
inner join `subject` sub
on r.subjectno = sub.subjectno
group by sub.subjectno
having...
5、常用函数
-- ============常用函数=============
-- 绝对值
select ABS(8)  -- 8
select ABS(-8)   -- 8

-- 向上取整
select ceiling(8.2)	-- 9
select ceiling(-8.2) -- -8

-- 向下取整
select floor(-8.3)  -- -9
select floor(8.3)	-- 8

-- 返回一个0~1之间随机数
select Rand()

-- 判断是正数还是负数 正数返回1  负数返回-1
select sign(-10) --  -1
select sign(10)	--  1

-- 返回字符串长度
select char_length('干得漂亮!')

-- 拼接字符串
select concat('学','习','My','Sql')

-- 将字符串所有字符转换为大写
select upper('TangDexin')

-- 将字符串所有字符转换为小写
select lower('TangDexin')

-- 还有替换、反转、返回指定字符

-- 时间、日期函数
select current_date()  -- 获取当前日期  或 select curdate()
select now() -- 获取当前时间 时分秒
select localtime() -- 获取本地时间 时分秒

-- 系统
select user() -- 获取当前登入用户
select version() -- 获取mysql版本
DQL查询语句

1、排序查询

​ 语法:order by 排序字段1 排序方式2, 排序字段2 排序方式2…;

​ ASC:升序,不指定排序方式默认为升序

​ DESC:降序

2、聚合函数

​ 将一列数据作为一个整体,进行纵向的计算;注意:聚合函数计算会排除null值

​ count:计算个数 SELECT COUNT(NAME) as 总人数 FROM student

​ concat:将多个字符串连接成一个字符串。 select CONCAT(‘姓名:’ , name) as 新名字 from student;

​ max:计算最大值

​ min:计算最小值

​ sum:计算和

​ avg:计算平均值

3、分组查询

​ 语法:group by 分组字段

​ 分组之后查询的字段只能是分组字段和聚合函数

​ where和having的区别:

​ where在分组前限定条件,having在查询分组后限定条件,不满足条件不会被查询出来

​ where 后面不可以跟聚合函数,having 可以进行聚合函数判断

4、分页查询

​ 语法:limit 开始的索引 每页的条数

​ 公式:开始的索引 = ( 要查询的页码 - 1 ) * 每页显示条数 第三页:(3-1)*3

约束

概念:对表中的数据进行限定,保证数据的准确性、有效性和完整性

分类:

​ 1、主键约束 patmary key

​ 2、非空约束 not null

​ 3、唯一约束 unique

​ 4、外键约束 foreign key

非空约束:not null
-- 添加非空约束
ALTER TABLE student MODIFY name VARCHAR(20) NOT NULL

-- 删除非空约束
ALTER TABLE student MODIFY name VARCHAR(20)
唯一约束:unique
-- 创建表时给字段添加唯一约束
create table stu{
	id int,
	phone_number varchar(20) unique
}

-- 添加唯一约束
ALTER TABLE student modify phone_number varchar(20) unique

-- 删除唯一约束
ALTER TABLE student DROP INDEX phone_number varchar(20)
主键约束 patmary key

主键约束:非空且唯一;一张表只能有一个字段为主键;主键就是表中记录的唯一标识

-- 添加主键
alter table student modify id int primary key

-- 删除主键
alter table student drop primary key

自动增长

-- 创建时 增加自动增长
create table stu{
	id int primary key auto_increment,
	name varchar(20)
}
-- 添加自动增长
alter table student modify id int auto_increment

-- 删除自动增长
alter table student modify id int
MD5加密

什么是MD5?

主要增强算法的复杂度和不可逆性;

MD5不可逆,具体的值的MD5是一样的

MD5破解网站的原理,背后有一个字典,MD5加密前的值和MD5加密后的值

-- 修改密码  并MD5()加密
update smbms_user set userPassword=md5('123456') where id = 1;
-- 添加数据 密码使用MD5加密
insert into student value(1,'tang',MD5('123456'),'男','2020-12-12','1','1')
事务

指一组sql语句,要么都执行成功,要么都执行失败

将一组sql语句放在一个批次中去执行

事务原则:ACID原则
  • 原子性:要么都成功,要么都失败
  • 一致性:事务前后的数据完整性要保持一致
  • 持久性:事务一旦提交则不可逆,被持久化到数据库中
  • 隔离性:多个用户访问数据库时,数据库为每一个用户开启的事务,不能被其它事务干扰,事务之间要相互隔离
隔离级别
  • 脏读(读取未提交内容):读取到了未提交的数据
  • 不可重复读(读取提交内容):不可重复读意味着我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果
  • 幻读、虚读(可重读):当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行;
  • 可串行化:这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题;简言之,它是在每个读的数据行上加上共享锁;
模拟事务(转账)
-- 事务
-- mysql默认是开启事务提交的
set autocommit = 0	-- 关闭
set autocommit = 1	-- 开启(默认的)

-- 事务使用流程
set autocommit = 0	-- 关闭自动提交
start transaction		-- 开启事务
...
...
commit	-- 提交
rollback	-- 回滚
set autocommit = 1	-- 事务结束,开启自动提交

-- 模拟事务
-- 创建数据库
create database shop character set utf8 collate utf8_general_ci 
use shop	-- 选中数据库
-- 创建表
create table `account`(
`id` int(3) not null auto_increment,
`name` varchar(10) not null,
`moeny` decimal(10,2) not null,
PRIMARY key (`id`)
)engine = innodb default charset=utf8

insert into `account`(`name`,`moeny`)
values("张三",1000.01),("李四",2000.20)

select * from `account`

set autocommit = 0;-- 关闭自动提交
start transaction;-- 开启事务
-- 该事务下的sql称为一组事务
update `account` set `moeny` = `moeny` - 500 where name = "张三"
update `account` set `moeny` = `moeny` + 500 where name = "李四"
commit; -- 提交
rollback; -- 回滚
set autocommit = 1 -- 开启自动提交
索引

MySQL官方对索引的定义为:索引 (Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本
质:索引是数据结构。

注意:索引在数据量小的时候,用处不大;但是在数据量很大的时候,区别十分明显。

1、索引的分类
  • 主键索引(primary key)
    • 唯一的标识,主键不可重复,只能有一个列做为主键
  • 唯一索引(unique key)
    • 避免重复的列出现,唯一索引可以重复,多个列都可以标识为 唯一索引
  • 常规索引(key / index)
    • 默认的,key、index关键字来设置
  • 全文索引(fullText)
    • 在特定的数据库引擎中才有
    • 快速定位数据
2、索引的使用
-- id_表名_字段名
-- create index 索引名 on 表名(字段)
create index id_student_name on student(name);	-- 增加一个常规索引

-- explain关键字,显示sql执行过程
explain select * from student where name = "张三";
3、索引原则
  • 索引不是越多越好
  • 不要对经常变动的数据添加索引
  • 小数据量无需增加索引
  • 索引一般添加在常用于查询的字段
权限管理、备份
1、权限管理
-- 创建用户CREATE USER用户名IDENTIFIED BY '密码'
CREATE USER kuangshen IDENTIFIED BY '123456'

-- 修改密码(修改当前用户密码)
SET PASSwORD = PASSWORD('123456')

-- 修改密码(修改指定用户密码)
SET PASSWORD FOR kuangshen = PASSWORD('123456')

-- 重命名RENAME USER原来名字To新的名字
RENAME USER kuangshen To kuangshen2

-- 用户授权 ALL PRIVILEGES全部的权限,库.表
-- ALL PRIVILEGES 除了给别人授权,其他都能够干
GRANT ALL PRIVILEGES ON *.*To kuangshen2

--查询权限
SHOW GRANTS FOR kuangshen2	-- 查看指定用户的权限
SHOw GRANTS FORroot@localhost

-- ROO0T用户权限:GRANT ALL PRIVILEGES ON *.*To 'root' @ 'localhost' WITH GRANT OPTION

-- 撤销权限REVOKE哪些权限,在哪个库撤销,给谁撤销
REVOKE ALL PRIVILEGES ON*.*FROM kuangshen2

-- 删除用户
DROP USER kuangshen
2、备份

备份的作用:

  • 保证重要的数据不丢失
  • 数据迁移

mysql备份方式:

  • 直接拷贝物理文件

  • 在可视化工具中手动导出

  • 使用命令行导出 mysqldump

    • # 使用命令行导出  cmd
      # mysqldump -h主机 -u用户名 -p密码 数据库名称 表名 > 物理文件位置
      mysqldump -hlocalhost -uroot -p123456 school student > D:/a.sql
      
      # 导出多张表 空格隔开 命令行没有逗号
      mysqldump -hlocalhost -uroot -p123456 school 表1 表2 表3 > D:/a.sql
      
      # 导出数据库 空格隔开 命令行没有逗号
      mysqldump -hlocalhost -uroot -p123456 school > D:/a.sql
      
      # 导入 最好是登入情况下操作,切换到指定的数据库
      # source 备份文件
      source D:/a.sql;
      
规范数据库设计

设计数据库的作用:

  • 节省内存空间
  • 保证数据库的完整性
  • 方便开发
三大范式
  • 第一范式(1NF)
    • 原子性:保证每一列不可再分
  • 第二范式(2NF)
    • 满足第一范式;每张表只描述一件事情;需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关
  • 第三范式(3NF)
    • 满足第一、二范式;确保每一列的数据都和主键直接相关,而不能间接相关
JDBC
简介:

SUN公司为了简化开发人员的(对数据库的统一)操作,提供了一个(Java操作数据库的)规范,俗称JDBC这些规范的实现由具体的厂商去做
对于开发人员来说,我们只需要掌握JDBC接口的操作即可!|

使用

将jdbc连接数据库封装为工具类

db.properties

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/school?characterEncoding=utf8&useSSL=false&serverTimezone=UTC
username = root
password = 123456

JdbcUtils.java

package com.xin.jdbc.utils;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * @version 1.0
 * @ClassName JdbcUtils
 * @Description TODO
 * @Author TangDexin
 * @Date 2021/6/5 23:09
 **/

public class JdbcUtils {

    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;

    static {
        try {
            InputStream is = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(is);

            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }

    // 关闭资源
    public static void close(Connection conn, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (st != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

mian测试:

import java.sql.Statement;

/**
 * @version 1.0
 * @ClassName TestJDBC
 * @Description TODO
 * @Author TangDexin
 * @Date 2021/6/5 22:56
 **/

public class TestJDBC {

    public static void main(String[] args) {
        TestInsert();
//        TestQuery();
    }
    public static void TestInsert(){
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();
            String sql = "insert into grade(`gradename`) values('研究生')";
            int i = st.executeUpdate(sql);
            if (i > 0) {
                System.out.println("添加成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn,st,rs);
        }
    }
    public static void TestQuery(){
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();
            String sql = "select * from grade";
            rs = st.executeQuery(sql);
            while (rs.next()) {
                System.out.println(rs.getObject("gradeid")+"+"+rs.getObject("gradename"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn,st,rs);
        }
    }
}
SQL注入
-- sql存在漏洞,会被非法攻击
select * from smbms_user where userCode = '' or 1=1 and userpassword = '111'
-- 通过 or 的拼接 不管传的账号密码是否正确,都能把所有记录查出来
select * from smbms_user where userCode = '' or 1=1 and userpassword = '' or 1=1
prepareStatement对象

使用预编译prepareStatement(),可以防止sql注入,效率更高

package com.xin.jdbc;

import com.xin.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @version 1.0
 * @ClassName TestJDBC02
 * @Description TODO
 * @Author TangDexin
 * @Date 2021/6/6 14:52
 **/

public class TestJDBC02 {

    public static void main(String[] args) {
        TestInsert();
        TestUpdate();
    }

    public static void TestInsert() {
        Connection conn = null;
        PreparedStatement st = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into grade(`gradename`) values(?)";
            st = conn.prepareStatement(sql);
            st.setString(1, "博士");
            int i = st.executeUpdate();
            if (i > 0) {
                System.out.println("添加成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void TestUpdate() {
        Connection conn = null;
        PreparedStatement st = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "update grade set gradeid = ? where gradeid = ?";
            st = conn.prepareStatement(sql);
            st.setInt(1, 6);
            st.setInt(2, 10);
            int i = st.executeUpdate();
            if (i > 0) {
                System.out.println("修改成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
Java代码实现事务(模拟转账)
package com.xin.jdbc;

import com.xin.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @version 1.0
 * @ClassName TestJDBC03
 * @Description TODO
 * @Author TangDexin
 * @Date 2021/6/6 16:04
 **/

public class TestJDBC03 {

    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        try {
            conn = JdbcUtils.getConnection();// 获取连接

            conn.setAutoCommit(false);//关闭自动提交,默认开启事务

            String sql = "update account set money = money-100 where name = '张三'";
            st = conn.prepareStatement(sql);
            st.executeUpdate();
//            int i = 1/0;  //手动设置错误
            String sql2 = "update account set money = money+100 where name = '李四'";
            st = conn.prepareStatement(sql2);
            st.executeUpdate();

            conn.commit();//业务完毕,提交事务
            System.out.println("成功");

        } catch (SQLException e) {
            try {
                conn.rollback();// 失败,回滚
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}
数据库连接池

使用c3p0连接池

导入jar包 commons-pool-1.6 commons-dbcp-1.4

配置类c3p0-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<c3p0-config>
    <!--
        如果ComboPooledDataSource ds = new ComboPooLedDataSource();”这样写就表示使用的是C3PO的缺省(默认)
        如果ComboPooledDataSource ds = new ComboPooLedDataSource(MySQL);”这样写就表示使用的是第二个
     -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/school?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    <named-config name="MySQL">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/school?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>

</c3p0-config>

工具类

package com.xin.connection.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.*;

/**
 * @version 1.0
 * @ClassName JdbcUtils
 * @Description TODO
 * @Author TangDexin
 * @Date 2021/6/5 23:09
 **/

public class JdbcUtils {
    private static ComboPooledDataSource dataSource = null;

    static {
        try {
            // 创建数据源 工厂模式-->创建
            dataSource = new ComboPooledDataSource("MySQL");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    // 关闭资源
    public static void close(Connection conn, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (st != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

测试类

package com.xin.connection;

import com.xin.connection.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @version 1.0
 * @ClassName TestC3p0
 * @Description TODO
 * @Author TangDexin
 * @Date 2021/6/6 23:05
 **/

public class TestC3p0 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();
            String sql = "insert into grade(`gradename`) values('研究生')";
            int i = st.executeUpdate(sql);
            if (i > 0) {
                System.out.println("添加成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn,st,null);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值