MySQL

控制台操作数据库

mysql -u 账号 -p 密码 --连接数据库
-------------------------------
进入mysql>之后所有的语句都要以;结尾

--sql单行注释

/*
  sql多行注释
*/

update mysql.user set authentication_string=password('123456') 
	where user='root' and Host='localhost'; --修改用户密码

show databases; --查看所有的数据库

use 数据库名; --切换数据库

show tables; --查看数据库中所有表

describe 表名; --查看表中的所有数据

create database 数据库名; --创建数据库

exit; --退出连接

1. 数据库语句(创库,创表,创约束,修改表)

所有的创建和删除操作都尽量加上判断

删除有外键关系的表时,必须要先删除应用别人的表(从表),再删除被引用的表(主表)

if not exists 如果不存在

if exists 如果存在

创建数据库
create database if not exists 数据库名;

删除数据库
drop database if exists 数据库名;

查看创建数据库的语句
show create database 数据库名

查看创建表的语句
show create table 表名

删除表		
DROP TABLE IF EXISTS student

显示表的结构
desc 表名

----------------------------------------------------------------
--表名称和字段最好用``括起来,所有的字符串都使用''单引号括起来
--每个字段创建的最后都要加逗号,  最后结束的字段不需要加逗号
--not null=不能为空,auto_increment=自增,comment('')=给字段取注释
--主键写在最后,primary key(`id`)
--default charset=utf-8,改变默认编码格式
--ENGINE=innodb 表引擎
/*innodb安全性高,支持事务的处理,多表多用户操作
	myisam节约空间,速度较快*/
创建表
CREATE TABLE IF NOT EXISTS `student` (
	`id` INT(3) AUTO_INCREMENT NOT NULL COMMENT'学号',
	`name` VARCHAR(30) DEFAULT '匿名' COMMENT'名字',
	`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT'密码',
	`sex` VARCHAR(2) NOT NULL DEFAULT '男' COMMENT'性别',
	`birthday` DATETIME DEFAULT NULL COMMENT'出生日期',
	`address` VARCHAR(100) DEFAULT NULL COMMENT'家庭住址',
	`emall` VARCHAR(50) DEFAULT NULL COMMENT'邮箱',
	PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8

----------------------------------------------------------------
修改表(所有跟表有关的修改都用alter--修改表名,关键词 rename
ALTER TABLE 旧表名 RENAME AS 新表名

--增加表字段,关键词 ADD
ALTER TABLE student ADD age INT(3) DEFAULT NULL COMMENT '年龄' 

--修改表字段类型和约束,关键词modify(只能修改表字段的类型和约束)
ALTER TABLE student MODIFY age INT(5)

--修改表字段名和表字段的类型与约束,关键词change(可以同时修改字段名和字段的类型与约束)
--数据类型一定要一致才可以改名
ALTER TABLE student CHANGE age age1 INT(5)

--删除表字段,关键词 drop
ALTER TABLE student DROP age

--物理外键,不建议使用
--创建表的外键约束,constraint 创建什么约束,foreign key 跟什么外交,references 涉及到哪个表的那个字段
ALTER TABLE student 
	ADD CONSTRAINT `FK_gradeid` 
		FOREIGN KEY(`gradeid`) 
			REFERENCES `grade`(`gradeid`)



2. 数据库的数据类型

2.1 数值

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

2.2 字符串

  • char 固定大小的字符串 0~255

  • varchar 可变字符串 0~65535 (常用)

  • tinytext 微型文本 2^8 - 1

  • text 文本串 2^16 - 1

2.3 时间日期

  • date YYYY-MM-DD 日期格式
  • time HH:mm:ss 时间格式
  • datetime YYYY-MM-DD HH:mm:ss 最常用的时间格式 (常用)
  • timestamp 1970.1.1到现在的毫秒数 时间戳 (常用)
  • year 年份表示

3. 数据库的字段属性

unsigned:

  • 无符号的整数
  • 声明了该列不能为负数

zerofill:

  • 0填充
  • 不足的位数,使用0来填充,如:int(3), 5=005

自增:

  • 自动在上一条记录的基础上+1

  • 通常用来设计唯一的主键,必须是整数类型

  • 可以自定义设计主键自增的起始值和步长

非空:

  • 设置为not null,如果不给他赋值,就会报错

  • 不填写值,默认值就是null

默认:

  • 设置默认值
  • 比如sex,默认值为男

拓展:

/*每一个表都必须存在以下五个字段,阿里巴巴规范
id 主键
`version` 乐观锁
is_delete 伪删除
gmt_create 创建时间
gmt_update 修改时间
*/

4. 判断操作符

操作符含义范围结果
=等于1=1true
<>或!=不等于1<>2true
>大于2>1true
<小于1<2true
>=大于等于2>=2true
<=小于等于2<=2true
between … and …区间id between 1 and 5id为1-5之间的值
and跟java中的&&一样2>1 and 3>2true
or跟java中的||一样1>2 and 2>1true

5. 比较运算符(模糊查询)

运算符语法描述
is nulla is null如果操作符为null,true
is not nulla is not null如果操作符不为null,true
betweena between b and c若a在b和c之间,则结果为true
likea like ‘’,’‘中可以加入%表示后面的值随意,或者_有几个下划线就代表查询后面的字符有几个的值SQL匹配,如果a匹配到’'中的值,结果为ture
ina in (a1,a2,a3…)假设a在a1,a2,a3…某一个值中,结果为true

6. DML语言(增删改)

DML语言:数据库操作语言

6.1 insert -添加

  • 语法:insert into 表名(‘字段名’,‘字段名’) values (‘值1’,‘值2’),字段名和值一一对应
  • 字段名可以省略,但是值得跟表字段全部对应上
  • 可以一个字段插入多条值,但是每个值都得(‘值1’),(‘值2’)这样插入
INSERT INTO `student`(`name`,sex,birthday,address,email,gradeid) 
			VALUES 
					('张三','男',NOW(),'广东','',1),
					('李四','男',NOW(),'广东','',1)

6.2 update -修改

  • 语法:update 表名 set 字段名=‘修改的值’ where id=1
  • 修改后面如果不加条件,会修改数据库所有的数据!!!(重要)
  • 修改多个值时用逗号隔开
--只修改id=1的数据
UPDATE `student` SET `name`='王五',sex='女' WHERE id=1

--不加条件会修改所有数据
UPDATE `student` SET `name`='王五'

6.3 delete -删除

  • 删除语句一定加条件
DELETE FROM student WHERE id=1
  • truncate:清空数据库
TRUNCATE student
  • 相同点:都能删除数据,都不会删除表结构

  • 不同点:truncate,清空数据之后,表的自增列计数器会归零,不会影响事务

      	  delete,不会影响自增,如删除了id为1-5的数据,下次新增id依旧为6
    

7. DQL查询数据

7.1 select执行语句顺序

以下严格按照执行顺序写,比如order by 一定要在最后面等…

SELECT DISTINCT
table.*,查询字段 AS 别名
FROM 表名 AS 表别名
INNER JOIN 连接的表明 AS 连接表别名
ON 表别名.id=连接表别名.id
WHERE 指定结果需满足所需的条件
GROUP BY 指定哪几个字段进行分组
HAVING 过滤分组的记录必须满足的次要条件
ORDER BY 指定字段进行升序或降序排序
LIMIT 0,5 指定需要分页的记录从哪条开始,一页几条数据

7.2 普通查询语句

  •   --查询所有
      SELECT * FROM student
      
      --查询指定字段
      SELECT id FROM student
      
      --查询多个指定字段
      SELECT id,`name` FROM student
      
      --取别名
      SELECT id AS '学号' FROM student
    

7.3 去重复查询

  •   --查询成绩表中的学生学号,因为有多门课程所以一个学生会有多个成绩,用distinct去除重复学号
      SELECT DISTINCT studentNo FROM result
    

7.4 根据各种条件的查询where

  •   --用and查询区间
      SELECT id FROM result WHERE sturesult>=95 AND sturesult<=100
      
      --用&&查询区间
      SELECT id FROM result WHERE sturesult>=95 && sturesult<=100
      
      --用between and查询区间
      SELECT id FROM result WHERE sturesult BETWEEN 95 AND 100
      
      --用!=查询除了学号是10以外的学生
      SELECT * FROM student WHERE id != 10
      
      --用NOT查询除了学号是10以外的学生
      SELECT * FROM student WHERE NOT id = 10
    

7.5 模糊查询

  •   --查询姓刘的学生名字
      SELECT `name` FROM student WHERE `name` LIKE '刘%'
      
      --查询名字中间有佳字的学生名字
      SELECT `name` FROM student WHERE `name` LIKE '%佳%'
      
      --查询姓刘的,姓后面只有一个字的学生名字
      SELECT `name` FROM student WHERE `name` LIKE '刘_'
    

7.6 指定查询

  •   --查询学号为1,2,3的学生信息,指定查询
      SELECT * FROM student WHERE id IN(1,2,3)
    

7.7 空值,非空值查询

  •   --查询地址为''或者为null的学生信息
      SELECT * FROM student WHERE address='' OR IS NULL
      
      ----查询地址不为null的学生信息
      SELECT * FROM student WHERE address IS NOT NULL
    

7.8 多表联查

  • 思路:

    • 分析需求,分析查询的字段来自哪些表
    • 确定使用哪种连接方式
    • 确定表的交叉点(两张表哪些数据是相同的)
  •   --连接查询
      SELECT studentNo,studentName,SubjectNo,studentResult
      	FROM student AS s
      	INNER JOIN result AS r
      	ON s.studentNo=r.studentNo
      	
      --左连接查询,查询左表表的数据,即使有些数据在右表中没有,也可以查出来
      --比如查询出有一个学生,在右表的成绩表中没有成绩,也能查出来,只不过成绩表字段的值是null
      SELECT studentNo,studentName,SubjectNo,studentResult
      	FROM student AS s
      	LEFT JOIN result AS r
      	ON s.studentNo=r.studentNo
      
      --右连接查询,查询右表表的数据,即使有些数据在左表中没有,也可以查出来
      --跟左连接同一个查询,但是左连接查的出为null值的学生,在右连接中查不出来
      SELECT studentNo,studentName,SubjectNo,studentResult
      	FROM student AS s
      	RIGHT JOIN result AS r
      	ON s.studentNo=r.studentNo
      	
      --比方
      --查询缺考的学生
      --因为是左连接查询,查询的是学生表,学生表中有一个学生在成绩表中没有成绩
      SELECT studentNo,studentName,SubjectNo,studentResult
      	FROM student AS s
      	LEFT JOIN result AS r
      	ON s.studentNo=r.studentNo
      	WHERE studentResult IS NULL
      	
      --三表联查,查询有成绩的学生信息和科目信息
      SELECT studentNo,studentName,SubjectName,studentResult
      	FROM student AS s
      	RIGHT JOIN result AS r
      	ON s.studentNo=r.studentNo
      	INNER JOIN `subject` sb
      	ON r.SubjectNo = sb.SubjectNo
    
    操作描述
    inner join on如果表中至少有一个值匹配,就返回行
    left join on会从左表中返回所有的数据,即使在右表中没有
    right join on会从右表中返回所有的数据,即使在左表中没有

7.9 自连接

  • 把一张表想象拆成两张

  • 在一张表中存在两种id,和一个name,两种id的值是可以对应上的

  •   --catgory职业表,catgoryName字段 职业名称,catgoryid字段 父类id,pid字段 子类id
      --先用别名把同一张表拆成两个,然后用where把两个id连接在一起
      SELECT a.`catgoryName` AS '父栏目', b.`catgoryName` AS '子栏目' FROM catgory AS a ,`catgory` AS b WHERE a.`catgoryid` = b.pid
    

7.10 分页和排序

  •   --根据id从小到大升序排序
      SELECT * FROM student ORDER BY id asc
      --根据id从大到小降序排序
      SELECT * FROM student ORDER BY id desc
      
      --分页
      --0代表从第几条数据开始,5代表一页几行数据
      --第一页 limit 0,5   (1-1)*5
      --第二页 limit 5,5   (2-1)*5
      --第三页 limit 10,5   (3-1)*5
      --第N页 limit 0,5   (N-1)*pagesize
      --pagesize 一页几行
      --N 当前页数
      --数据总数/pagesize=总页数
      SELECT * FROM student LIMIT 0,5
    

7.11 子查询加分页

  •   SELECT studentNo,studentName,stuResult FROM student WHERE studentNo IN (
      	SELECT studentNo FROM result WHERE `subjectNo` = (
      		SELECT subjectNo FROM `subject` WHERE subjectName = 'C语言-1'
      	) 
      )ORDER BY studentNo DESC LIMIT 0,5
    

8. SQL函数

8.1 普通函数

函数语法作用
LOWER()LOWER(‘要改变的字符串’)转小写
UPPER()UPPER(‘要改变的字符串’)转大写
SUBSTR()SUBSTR(‘源字符串’,起始位置,截取数量)截取字符串
REPLACE()REPLACE(‘要替换的字符串’,‘替换字符串中的哪个字符’,‘替换成什么’)替换字符串
CURDATE()获取当前日期
NOW()获取当前日期加时间
YEAR()获取年
MONTH()获取月
DAY()获取日
HOUR()获取时
MINUTE()获取分
SECOND()获取秒

8.2 聚合函数

聚会函数不能用在where语句上,需要使用having!!!!

函数作用
AVG()取平均数
SUM()求和
COUNT()计数
MIN()最小值
MAX()最大值
--where后面不能加聚合函数,需要使用having
SELECT student_name 
	FROM student 
	WHERE class_number = '班级容编号' 
	GROUP BY student_name 
	HAVING COUNT(student_name) >= 2

9. 事务

9.1 ACID四大原则原则

  1. 原子性(Atomicity): 要么都成功,要么都失败
  2. 一致性(Consistency): 事务前后要保证数据的完整性一致
  3. 隔离性(Isolation): 数据库对每个用户提供单独的事务时,不能被互相干扰
  4. 持久性(Durability): 事务一旦持久化到数据库,就不可逆

隔离所导致的一些问题:

​ 脏读:指一个事务读取到了另外一个未提交事务的数据

​ 幻读:是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

​ 不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同。

9.2 事务的语法

-- 关闭事务的自动提交
SET autocommit =0

-- 开启事务
START TRANSACTION

-- 插入数据
UPDATE student SET money=money-500 WHERE `name`='张三' -- 张三转王五500
UPDATE student SET money=money+500 WHERE `name`='王五' -- 王五得到500

-- 提交事务
COMMIT
-- 回滚,如果提交成功的事务再回滚是没用的
ROLLBACK

-- 事务结束
SET autocommit =1

10. 索引

10.1 作用

索引(Index)是帮助MySQL高效获取数据的数据结构。

​ 提取句子主干,就可以得到索引的本质:索引是数据结构。

​ 相当于本来数据库是遍历查询的,索引给所有数据都变成了键值对,

​ 用key,value对应。

10.2 索引的原则

  • 索引不是越多越好

  • 不要对进程变动多的数据加索引

  • 小数据量不需要加索引

  • 索引一般加在常用来查询的字段上

10.3 四大索引(理论知识)

  • 主键索引 (PRIMARY KEY)

    • 唯一的标识,主键不可重复,只能有一个列作主键
  • 唯一索引 (UNIQUE KEY)

    • 避免重复的列数据出现,唯一索引可以重复,多个列都可以标注成唯一索引
  • 常规索引 (KEY/INDEX)

    默认的,可以用index或者key关键字来设置

  • 全文索引 (FullText)

    • 在特定的数据库引擎下才有
    • 快速定位数据

10.4 创建索引的基本语法

-- 显示这个表的所有索引
SHOW INDEX FROM student

-- (创建表之后添加)增加一个全文索引的 `索引名`(`列名`)
ALTER TABLE `school`.`student` ADD FULLTEXT INDEX `name`(`name`)

-- 创建一个索引,创建索引然后起索引名on哪张表的列
CREATE INDEX id_student_name ON `student`(`name`)

-- explain 分析sql的执行状况
EXPLAIN SELECT * FROM student 

索引的底层结构是B+Tree的形式


11. 数据库权限管理与备份

11.1 权限管理

创建用户:

-- user表是数据库自带的表
CREATE USER root IDENTIFIED BY '123456'

修改用户密码:

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

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

修改用户名:

-- 重命名用户
RENAME USER root TO  root1

给用户授权

-- 用户授权,ALL PRIVILEGES 全部权限 ,库.表
GRANT ALL PRIVILEGES ON *.* TO root

查询用户权限

-- 查询权限
SHOW GRANTS FOR root@localhost

撤销用户权限

-- 撤销权限,撤销谁的,那张个库的权限,*.*代表库名表名
REVOKE ALL PRIVILEGES ON *.*  FROM root

删除用户

-- 删除用户
DROP USER root

11.2 数据库备份

为什么要备份:

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

MySQL数据库备份的方式

  • 直接拷贝物理文件
  • 在Sqlyog这种可视化工具中手动导出
    • 在想要导出的表或库中右键,选择备份或导出
  • 使用命令行到处 关键词:mysqldump

11.3 备份导出

# mysqldump -h 主机,-u 用户,-p 密码 数据库名 表名 >物理磁盘位置/文件名
C:\Users\Ning>mysqldump -hlocalhost -uroot -proot school student >D:/a.sql

# 导出多个表 mysqldump -h 主机,-u 用户,-p 密码 数据库名 表名1 表名2 表名3 >物理磁盘位置/文件名
C:\Users\Ning>mysqldump -hlocalhost -uroot -proot school student id name >D:/a.sql

11.4 备份导入

#在控制台界面登录mysql的情况下,如果要导入一张表的话切换到指定的数据库,导入数据库则不用
C:\Users\Ning>source d:/a.sql

12. 数据库规范设计

12.1 为什么需要设计

**当数据库比较复杂的时候,我们就需要设计 **

数据库都使用下划线命名:student_id、student_name

糟糕的数据库设计:

  • 数据冗余,浪费空间
  • 数据库插入和删除都会麻烦、异常(避免使用物理外键)
  • 程序的性能差

良好的数据库设计:

  • 节省内存空间
  • 保证数据库的完整性
  • 方便开发系统

12.2 软件开发中,关于数据库的设计

  • 分析需求:分析业务和需要处理的数据库的需求
  • 概要设计:设计关系图E-R图

设计数据库的步骤(个人博客为例):

  • 收集信息,分析需求

    • 用户表(用户登录注销,用户的个人信息,写博客,创建分类)
    • 分类表(文章分类,谁创建的)
    • 文章表(文章的信息)
    • 友链表(友链信息)
    • 自定义表(系统信息,关键字,或者一些主字段)
  • 标识实体(把需求落地到每个字段)

  • 标识实体之间的关系

12.3 三大范式(理论知识)

为什么需要三大范式

  • 信息重复
  • 更新异常
  • 删除异常
    • 丢失有效信息
  • 插入异常
    • 无法正常显示信息

三大范式:

把表拆分成多个就行了!

  • 原子性,保证每一列都是不可再分的,把各类数据细化

  • 在第一范式的基础上,每张表只做一件事情

  • 在第一和第二范式的基础上,每张表的每一列数据都和主键相关,不能间接相关

image-20200428144226702

满足三大范式会导致一些性能和规范性的取舍问题:

按照阿里规范关联查询不得超过三张表

  • 拆出的表太多,导致关联查询的表增加
  • 考虑商业化需求的时候,优先考虑性能问题
  • 可以适当的在表中增加一些冗余字段,去除一些表(从多表变成单表)

13. JDBC

13.1 数据库驱动

程序通过驱动和数据库进行交互

13.2 jdbc连接数据库

SUN公司为了简化开发人员的(对不同数据库的统一)操作,提供了一个(JAVA操作数据库)的规范,俗称JDBC

这些规范由数据库厂商去做,对于开发人员来说,只需掌握JDBC即可

连接mysql获取数据

顺序:

  1. 获取驱动 Class.forName(“com.mysql.jdbc.Driver”);
  2. 获取数据库信息用 Connection connection= DriverManager.getConnection(url,username,password);
  3. 用Statement执行sql的对象 statement= connection.createStatement();
  4. 用statement.execute拿到返回的结果 resultSet= statement.executeQuery(sql);
    • statement.execute() 执行所有sql
    • statement.execute.query() 执行查询,返回结果集
    • statement.execute.update() 执行更新、修改、删除,返回受影响行数
  5. 用循环的方式获取数据,循环条件是 resultSet.next()
    • 在不知道类型的情况下,使用 resultSet.object()
    • 在知道类型的情况下可以使用resultSet.String()、resultSet.Int() 等
  6. 释放资源,一个获取结果集,一个获取sql语句,一个获取数据库连接的,都要关闭
public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //导入数据库驱动
        Class.forName("com.mysql.jdbc.Driver");
        //获取数据库信息、用户信息
        //useUnicode=true支持中文,characterEncoding=utf-8设置字符集,useSSL=true使用安全的连接,用?输入,用&隔开
        String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf-8&useSSL=true";
        String username="root";
        String password="root";
        //用connection拿到连接数据库,connection代表数据库
        Connection connection= DriverManager.getConnection(url,username,password);
        //用Statement执行sql的对象
        Statement statement= connection.createStatement();
        //编写数据库语句
        String sql="select * from student";
        //用statement.execute拿到返回的结果,resultset获取结果
        ResultSet resultSet= statement.executeQuery(sql);
        //用循环获取结果集里的对象数据,如果next()没有了,退出循环
        while (resultSet.next()){
            System.out.println(resultSet.getObject("id"));
            System.out.println(resultSet.getObject("name"));
        }
        //释放连接
        resultSet.close();
    	statement.close();
        connection.close();
    }

13.3 JdbcUtils(数据库连接模板)

db.properties

driver="com.mysql.jdbc.driver"
url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf-8&useSSL=true"
username="root"
password="root"

databese类,用静态代码块

public class DataBase {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
   
    static{
        try {
            //用流去获取db.properties文件
            InputStream inputStream = DataBase.class.getClassLoader().getResourceAsStream("db.properties");
            //new一个properties去接收文件
            Properties properties = new Properties();
            //用 properties.load()去加载
            properties.load(inputStream);
            //获取驱动的值
            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 connection,ResultSet resultSet,Statement statement) throws SQLException {
        if(resultSet!=null){
            resultSet.close();
        }
        if(statement!=null){
            statement.close();
        }
        if(connection!=null){
            connection.close();
        }

    }
}

测试类(用statement对象)

public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Connection connection = null;
        ResultSet resultSet=null;
        Statement statement=null;
        try {
            connection= DataBase.getConnection();
            String sql="select id from student";
            statement=connection.createStatement();
            resultSet=statement.executeQuery(sql);
            while (resultSet.next()){
                System.out.println(resultSet.getString("id"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DataBase.close(connection,resultSet,statement);
        }
    }

(预编译sql)preparestatement对象可以有效防止sql注入,并且效率更高

用preparestatement对象

public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Connection connection = null;
        ResultSet resultSet=null;
        PreparedStatement ps=null;
        int i;
        try {
            connection= DataBase.getConnection();
            String sql="insert student(`name`,`age`,`brithday` values (?,?,?))";
            //预编译
            ps = connection.prepareStatement(sql);
            //然后插入下表与值
            ps.setString(1,"张三");
            ps.setInt(2,16);
            ps.setDate(3,new java.sql.Date(new Date().getTime()));
            i=ps.executeUpdate();
           if (i>0){
               System.out.println("插入成功");
           }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DataBase.close(connection,resultSet,ps);
        }

13.4 jdbc操作事务

 public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Connection connection = null;
        ResultSet resultSet=null;
        PreparedStatement ps=null;
        try {
            connection= DataBase.getConnection();
            //关闭自动提交,并开启事务
            connection.setAutoCommit(false);
            String sql1="update student set money=money+100 where `name`='张三'";
            ps=connection.prepareStatement(sql1);
            String sql2="update student set money=money-100 where `name`='王五'";
            ps=connection.prepareStatement(sql2);
            ps.executeUpdate();
            //用connection.commit提交事务
            connection.commit();
        } catch (SQLException e) {
            //失败,则回滚
            connection.rollback();
            e.printStackTrace();
        } finally {
            DataBase.close(connection,resultSet,ps);
        }

.


14. 数据库连接池

没用连接池前(这种方式十分浪费系统资源):数据库连接---->执行完毕---->释放资源

用连接池:数据库连接---->执行完毕---->等待执行下一个

池化技术:准备一些预先准备的资源,当有需要用到时就连接准备的好的

  • 最小连接数

  • 最大连接数

  • 等待超时的时间

最常用的连接池:

  • DBCP
  • C3P0
  • Druid(阿里巴巴)

14.1 DBCP

需要的jar包 commons-dbcp-1.4、commons-pool-1.6

需要的dpcpConfig.preperties

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000

#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

JdbcUtils_dbcp:

public class DataBase {
    private static DataSource dataSource;
    static{

        try {
            //用流去获取db.properties文件
            InputStream inputStream = DataBase.class.getClassLoader().getResourceAsStream("db.properties");
            //new一个properties去接收文件
            Properties properties = new Properties();
            //用 properties.load()去加载
            properties.load(inputStream);
            //创建数据源--工厂模式创建,把创建加载驱动和创建数据源封装了
            dataSource=BasicDataSoureFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

    //释放资源
    public static void close(Connection connection,ResultSet resultSet,PreparedStatement ps) throws SQLException {
        if(resultSet!=null){
            resultSet.close();
        }
        if(ps!=null){
            ps.close();
        }
        if(connection!=null){
            connection.close();
        }
    }
}

14.2 C3P0

需要jar包:c3p0-09.5.5、mchange-commons-java-0.2.19

<c3p0-config>
    <!-- 使用默认的配置读取连接池对象-->
	<default-config>
        <!--  连接参数 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/web</property>
        <property name="user">root</property>
        <property name="password">ROOT</property>

        <!-- 连接池参数 -->
        <!-- 初始连接数 -->
        <property name="initialPoolSize">5</property>
        <!-- 最大连接数 -->
        <property name="maxPoolSize">10</property>
        <!-- 最大等待时间 -->
        <property name="checkoutTimeout">2000</property>
        <!-- 最大空闲回收时间 -->
        <property name="maxIdleTime">1000</property>
    </default-config>
</c3p0-config>

JdbcUtils_c3p0:

public class DataBase {
    private static ComboPooledDatasource dataSource;
    static{
        try {
            //创建数据源
            dataSource= new ComboPooledDatasource();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

    //释放资源
    public static void close(Connection connection,ResultSet resultSet,PreparedStatement ps) throws SQLException {
        if(resultSet!=null){
            resultSet.close();
        }
        if(ps!=null){
            ps.close();
        }
        if(connection!=null){
            connection.close();
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值