数据库学习笔记

1. SQL

1.1什么是SQL?

  • Structurd Query Language:结构化查询语言

  • 定义了操作所有关系型数据库的规则

1.2 SQL通用语法

  • 单行或多行书写,以分号结尾

  • 可使用空格和缩进增强可读性

  • 不区分大小写,关键字建议使用大写

1.3 SQL的分类

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

​ 【操作数据库、表】

(2)DML(Data Manipulation Language)数据操作语言

​ 【增删改表中的数据】

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

​ 【查询表的数据】

(4)DCL(Data Control Language)数据控制语言

​ 【授权、定义数据库访问权限和安全级别】

2. 数据类型

  • 【data】:日期,只包含年月日,yyyy-MM-dd

  • 【datetime】:日期,包含年月日时秒分 yyyy-MM-dd HH:mm:ss

  • 【timestamp】:时间戳类型,包含年月日时秒分 yyyy-MM-dd HH:mm:ss

    ​ (如果将来不给这个字段赋值,或赋值为null,则默认使用当前系统时间,进行自动复制)

  • 【int】

  • 【double】:double(5,2)最多5位,取小数点后2位

  • 【varchar】:字符串

3. DDL

CRUD

  • C(Create):创建
  • R(Retrieve):查询
  • U(Upadate):修改
  • D(Delete):删除
  • 使用数据库

3.1 C(Create)创建

/*================数据库================*/
-- 创建数据库
CREATE DATABASE name;

-- 创建数据库之前进行判断
CREATE DATABASE if not exists name;

-- 指定字符集
CREATE DATABASE if not exists name CHARACTER SET gbk;


/*================表================*/
-- 创建表 
CREATE TABLE name(
	列名1 数据类型1,
    ...
    id INT,
    name VARCHAR(32),
    insert_time timestamp
);

-- 复制表
CREATE TABLE 表名 LIKE 被复制的表名;

3.2 R(Retrieve)查询

/*================数据库================*/
-- 查询数据库
SHOW DATABASES;

-- 查询创建数据库的语句
SHOW CREATE DATABASE demo;


/*================表================*/
-- 查询所有的表
SHOW TABLES;

-- 查询表结构
DESC name;

-- 查看创建表的语句
SHOW CREATE TABLE name;

3.3 U(Upadate)修改

/*================数据库================*/
-- 修改数据库的字符集
ALTER DATABASE name CHARACTER SET utf8;


/*================表================*/
-- 修改表名
ALTER TABLE 表名 RENAME TO 新的表名;

-- 修改表的字符集
ALTER TABLE 表名 CHARACTER SET 字符集名称;

-- 添加一列
ALTER TABLE 表名 ADD 列名 数据类型;

-- 修改列名称 类型
ALTER TABLE 表名 CHANGE 列名字 新列名字 新数据类型;

-- 删除列
ALTER TABLE 表名 DROP 列名

3.4 D(Delete)删除

/*================数据库================*/
-- 删除数据库(删除之前判断)
DROP DATABASE IF EXISTS name;


/*================表================*/
-- 删除表
DROP TABLE IF EXISTS name;

3.5 使用数据库

/*================数据库================*/
-- 查询当前使用的数据库名称
SELECT DATABASE();

-- 使用数据库
USE name;

4. DML

4.1 添加数据

-- 插入数据
INSERT INTO 表名(1,2,...,列n) VALUES(1,2,...,值n);
/*
	1.列名和值一一对应
	2.如果表名不定义列名,代表所有列
	3.除了数字类型,其他类型需要用引号(单双都可以)引起来
*/
INSERT INTO stu VALUES(2,'阿爷',"2000-12-04"); 

4.2 删除数据

-- 删除数据
DELETE FROM 表名 WHERE 条件
/*
	1.如果不加where删除表中所有数据
*/

-- 删除所有数据 建议 truncate(截断)
TRUNCATE TABLE 表名
/*
	1.DELETE TEBALE 表名 有多少记录就会执行多少次,效率低
	2.先删除表,然后创建一张一样的空表
*/

4.3 修改数据

UPDATE 表名 SET 列名1=1,列名2=2..... WHERE 条件

5. DQL

SELECT 字段列表
FROM 表名
WHERE 条件列表
GROUP BY 分组字段
HAVING 分组之后的条件
ORDER BY 排序
LIMIT 分页限定

5.1 基础查询

-- 去除重复的结果集
SELECT DISTINCT address FROM student;

-- 计算
SELECT math + english FROM student;
/*
	如果有null参与计算,计算结果都为null
	解决方法:IFNULL(列,替换的值)
*/
SELECT math + IFNULL(english,0) FROM student;

-- 起别名
SELECT math + IFNULL(english,0) AS 总分 FROM student;

5.2 条件查询

-- 查询年龄 大于/等于/不等于 20岁
SELECT * FROM student WHERE age > 20;
SELECT * FROM student WHERE age = 20;
SELECT * FROM student WHERE age != 20;

-- 查询年龄大于20小于30岁
SELECT * FROM student WHERE age >= 20 AND age <= 30;
SELECT * FROM student WHERE age BETWEEN 20 AND 30;

-- 查询年龄22,18,25岁
SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25;
SELECT * FROM student WHERE age IN(22,18,25);

-- 查询英语成绩 为/不为 null(NULL 不能使用 = 判断)
SELECT * FROM student WHERE english IS NULL;
SELECT * FROM student WHERE english IS NOT NULL;

5.3 模糊查询

SELECT * FROM student WHERE name LIKE '_马%'
/*
	'_' 单个】 字符
	'%' 0或多个 字符
*/

5.4 排序查询

-- 语法
ORDER BY 排序字段1 排序方式1,排序字段2 排序方式2
/*
	默认为升序
	升序:ASC
	降序:DESC
*/
-- 按照数学成绩排序,如果数学成绩一样,按照英语成绩排序
SELECT * FROM student RODER BY math ASC,english DESC;
/*
	如果有多个排序条件
	当前面的排序条件一样时
	才会判断下一个条件
*/

5.5 聚合函数

  • 将一列数据作为一个整体,进行纵向的计算(例:计算平均分)
  • 排除null值
    • 选择不包含非空的列进行计算(选择主键)
    • IFNULL函数
/*
    COUNT():计算个数
    MAX():计算最大值
    MIN():计算最小值
    SUM():计算和
    AVG():计算平均值
*/

5.6 分组查询

  • 分组之后查询的字段:分组字段、聚合函数
  • where和having的区别
    • where在分组之前限定,不可以跟聚合函数
    • having在分组之后限定,可以聚合函数的判断
-- 语法
GROUP BY 分组字段
-- 按照性别,查询男、女的人数,平均分
SELECT sex,COUNT(id),AVG(math) 
FROM student 
GROUP BY sex;

-- 分数低于70的不参与分组
SELECT sex,COUNT(id),AVG(math) 
FROM student 
WHERE math > 70 
GROUP BY sex;

-- 分组之后人数大于2
SELECT sex,COUNT(id),AVG(math)
FROM student 
WHERE math > 70 
GROUP BY sex
HAVING COUNT(id)>2;

5.7 分页查询

-- 语法
LIMIT 开始的索引,每页查询的条数
/*
	开始的索引 = (页码 - 1 ) *  每页查询的条数
*/

6. 约束

概念:

​ 对表中的数据进行限定,保证数据的正确性、有效性。

-- 主键
PRIMARY KEY
/*
	1.非空且唯一
	2.一张表只能有一个字段为主键
	3.主键就是表中记录的唯一标识
*/

-- 非空
NOT NULL

-- 唯一约束
UNIQUE

-- 外键
FOREIGN KEY
/*
	让表与表产生关系,保证数据的正确性
*/

6.1 主键约束

-- 删除主键
ALTER TABLE stu DROP PRIMARY KEY;

-- 创建完后添加主键
ALTER TABLE stu MODIFY id INT PRIMARY KEY;

-- 自动增长
/*
	1.字段是数值型的
	2.根据上一条记录的值进行增长
*/
CREATE TABLE stu(
    id int PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20)
);

6.2 非空约束

-- 删除name的非空约束
ALTER TABLE stu MODIFY name VARCHAR(20);

-- 创建表完后添加约束
ALTER TABLE stu MODIFY name VARCHAR(20) NOT NULL;

6.3 唯一约束

-- 删除唯一约束
ALTER TABLE stu DROP INDEX phone_number

-- 创建完后添加约束
ALTER TABLE stu MODIFY name VARCHAR(20) UNIQUE;

6.4 外键约束

-- 语法
CREATE TABLE 表名(
    ...
    外键列
    CONSTRAINT 外键名称 FOREIGN KEY 外键列名称 REFERENCES 主表名称(主表列名称)
);
/*
	外键名称常用:表1_表2_字段名
*/

-- 删除外键
ALTER TABLE employee DROP FOREIGN KEY 外键名称

-- 添加外键
ALTER TABLE employee ADD CONSTRAINT 外键名称 FOREIGN KEY 外键列名称 REFERENCES 主表名称(主表列名称)

级联操作

  • 修改外键数据的时候,相关联的表的数据也会更新
  • 使用谨慎,因为很影响效率

【软件的架构设计器可以查看表的结构】

-- 设置级联更新/级联删除
CREATE TABLE 表名(
    ...
    外键列
    CONSTRAINT 外键名称 FOREIGN KEY 外键列名称 REFERENCES 主表名称(主表列名称) 
    ON UPDATE CASCADE	-- 更新
    ON DELETE CASCADE	-- 删除
);

7. 多表

关系

  • 一对一:人和身份证
    • 【实现】在任意一方添加外键指向另一方的主键
    • 让外键唯一
  • 一对多(多对一):部门和员工
    • 【实现】在多的一方建立外键,指向一的主键
  • 多对多:学生和课程
    • 【实现】新建第三章中间表,至少包含了两个字段,第三张表的外键分别指向两张表的主键
    • 联合主键(不会出现重复的内容,(学生1,课程1))
-- 联合主键
PRIMARY KEY(字段1,字段2,...,字段n)
/*
	作用:(字段1,字段2,...,字段n)不会重复出现
*/

8.范式

概念

  • 设计数据库所需要遵循的一些规范
  • 遵循不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为范式
  • 越高的范式数据库冗余越小
  • 1NF、2NF、3NF、BCNF、4NF、5NF(完美范式)
  • 一般只学习前三种

8.1 第一范式(1NF)

  • 每一列都是不可分割的原子数据项

在这里插入图片描述
在这里插入图片描述

【存在的问题】

  • 存在非常严重的数据冗余(重复):姓名、系名、系主任

  • 数据添加存在问题:比如添加新开设的系和系主任,数据不合法(没有其他字段的内容)

  • 数据删除存在问题:删除张无忌,连系的数据也一起删除

8.2 第二范式(2NF)

  • 在1NF的基础上,消除非主属性对主码的部分函数依赖

  • 非码属性必须完全依赖于码

在这里插入图片描述

【一些概念】

  • 【函数依赖】:A --> B 通过A属性能确定唯一的B属性,称B依赖于A

    • (学号 --> 姓名)
    • (学号,课程名称)–> 分数
  • 【完全函数依赖】:A --> B,A是一个属性组,则B属性值需要依赖于A属性组的所有属性值

    • (学号,课程名称)–> 分数
  • 【部分函数依赖】:A --> B,A是一个属性组,则B属性值需要依赖于A属性组的部分属性值

    • (学号,课程名称)–> 姓名(学号就能确定姓名)
  • 【传递函数依赖】:A–> B , B --> C ,C传递依赖于A

  • 【码】:通过码(属性或属性组)确定唯一的数据项

  • 【主属性】:码中的所有属性

  • 【非主属性】:除码属性组的属性:

【存在的问题】

  • 数据添加存在问题:比如添加新开设的系和系主任,数据不合法(没有其他字段的内容)
  • 数据删除存在问题:删除张无忌,连系的数据也一起删除

8.3 第三范式(3NF)

  • 在2NF的基础上,消除传递依赖

【问题】(学号,姓名)–> (系名) ,(系名)–> (系主任),存在传递依赖

【解决】

在这里插入图片描述

9.数据库的备份和还原

9.1 命令行方式

-- 备份
mysqldump -u用户名 -p密码 数据库名称 > 保存的路径

-- 还原
1.登陆数据库
2.创建数据库
3.使用数据库
4.执行文件。source 文件路径

9.2 图形化工具

​ 导出 / 导入 sql文件

10. 多表查询

10.1 内连接

-- 标准写法
/*
	1.关键字一段
	2.每个字段、表、条件一段
*/
-- 隐式内连接
SELECT 
	t1.name,
	t1.gender,
	t2.name
FROM 
	emp t1,
	dept t2
WHERE
	t1.dept_id = t2.id;
-- 显示内连接 语法
/*
	INNER 可选
*/
SELECT 
	字段列表
FROM 
	表名1
[INNER] JOIN 
	表名2
ON 
	条件

10.2 外连接

-- 左外连接 【查询左表所有数据和交集部分】
/*
	OUTER 可选
*/
SELECT 
	字段列表
FROM1
LEFT [OUTER] JOIN2
ON
	条件
-- 右外连接 【查询右表所有数据和交集部分】
SELECT 
	字段列表
FROM1
RIGHT JOIN2
ON
	条件

10.2 子查询(嵌套查询)

/*
	子查询的结果分三种:
	1.单行单列
	2.多行单列
	3.多行多列
*/

-- 单行单列:用运算符
#查询工资最高的员工信息
SELECT 
	* 
FROM 
	emp
WHERE 
	emp.salary = (
    	SELECT MAX(salary)
        FROM emp
    );
   
-- 多行单列:用IN
#查询财务部或市场部所有的员工信息
SELECT 
	*
FROM 
	emp
WHERE
	dept_id IN(
    	SELECT 
        	id
        FROM 
        	dept
        WHERE
        	NAME = '财务部' OR
        	NAME = '市场部'
    );
    
 -- 多行多列:把子查询出来的当做一个虚拟表
 SELECT 
 	*
 FROM
 	dept t1,
 	(SELECT 
     	* 
     FROM 
     	emp
     WHERE
     	emp.join_date > '2011-11-11') t2
 WHERE
 	t1.id = t2.dept_id

10.3 自连接

SELECT
	t1.ename,
	t2.mgr,
	t2.id,
	t2.ename
FROM
	emp t1,
	emp t2
W

11. 事务

概念:如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败

操作:

-- 开始事务
START TRANSACTION;

-- 回滚
ROLLBACK;

-- 提交
COMMIT;

MySQL数据库中事务默认自动提交

  • 自动提交:一条DML语句会自动提交一次事务
  • 手动提交:先开启事务,再提交
  • 修改事务的默认方式
-- 查看提交方式  1自动提交,0手动提交
SELECT @@autocommit;

-- 修改提交方式
SET @@autocommit = 0;

11.1 四大特征

  • 原子性:不可分割的最小操作单位,要么同时成功,要么同时失败
  • 持久性:当事务提交或回滚时,数据库会持久化保存数据
  • 隔离性:多个事务之间,相互独立
  • 一致性:事务操作前后数据总量不变

11.2 事务的隔离级别(了解)

概念:多个事务之间,是相互独立的。但是如果多个事务操作同一批数据,则会引发问题,设置不同的

隔离级别就可以解决这些问题。

存在的问题:

  • 脏读:一个事务读取到另一个事务中没有提交的数据
  • 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样
  • 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改

隔离级别:

  • read uncommitted:读未提交【产生脏读、不可重复读、幻读问题】
  • read committed:读已提交【参数不可重复读、幻读问题】(Oracle默认)
  • repeatable:可重复读【产生幻读问题】(MySQL默认)
  • serializable:串行话(加锁)【解决所有问题】

【注意】隔离级别从小到大安全性越来越高,但是效率越来越低

-- 查询
SELECT @@tx_isolation;

-- 设置隔离级别
SET global transaction isolation level 级别字符串;

12. DCL

管理用户,授权

由DBA(数据库管理员)写的

12.1 管理用户

-- 切换到mysql数据库
USE mysql;

-- 查询user表
SELECT * FROM USER;

-- 通配符 % 表示可以在任意主机使用用户登陆数据库

-- 创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

-- 删除用户
DROP USER '用户名'@'主机名';

-- 修改用户密码
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名'

-- 忘记root用户的密码
net stop myslq 
mysql --skip-grant-tables
/*
	1.停止mysql服务
	2.使用无验证方式启动mysql服务
	3.打开新的cmd窗口,直接输入mysql,回车,就可以登陆成功
	4.use mysql
	5.update user set password = password() where user = 'root'
	6.关闭两个窗口
	7.打开任务管理器,手动结束mysql.exe的进程
	8.启动mysql服务
	9.使用新密码登陆
*/

12.2 权限管理

-- 查询权限
SHOW GRANTS FOR '用户名'@'主机名';

-- 授予权限
GRANT 权限列表 ON 数据库.表 TO '用户名'@'主机名';

-- 所有权限所有表
GRANT ALL ON *.* TO '用户名'@'主机名';

-- 撤销权限
REVOKE 权限列表 ON 数据库.表 FROM '用户名'@'主机名';

13. JDBC

Java DataBase Connectivity(Java数据库连接、Java语言操作数据库)

本质:官方定义的一套操作所有关系型数据库的规则,即接口,然后各个数据库厂商去实现这套接口,提供数据库驱动jar包。

我们可以使用这套接口(JDBC)编程,真正执行的diamante是驱动jar宝中的实现类。

13.1步骤

  • 导入jar包
  • 注册驱动
  • 获取数据库连接对象 Connection
  • 定义sql
  • 获取执行sql语句的对象 Statement
  • 执行sql,接受返回结果
  • 处理结果
  • 释放资源
package JDBC;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcDemo2 {
    public static void main(String[] args) {
        Statement statement = null;

        Connection conn = null;
        try {
            //1.导入jar包,然后右键-->Add Libraries

            //2.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

            //3.定义sql语句
            String sql = "insert into data values(10,'grandpa',100)";

            //4.获取数据库连接对象
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123456");

            //5.定义sql对象
            statement = conn.createStatement();

            //执行sql
            int i = statement.executeUpdate(sql);

            //处理结果
            System.out.println(i);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //释放资源
            if(statement != null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


DriverManager(驱动管理对象)

  • 注册驱动
    • 在Driver类中存在静态代码块
    • 通过forname获取字节码文件,告诉程序使用哪个数据库驱动jar
  • 获取数据库连接
    • url:指定连接的路径jdbc:mysql://ip地址(域名):端口号/数据库名称
    • password:密码
    • user:用户名

Connection(数据库连接对象)

  • 获取执行sql的对象
    • statement
    • prepareStatement
  • 管理事务
    • 开启事务 setAutoCommit
    • 提交事务 commit
    • 回滚事务 rollback

Statement(执行sql的对象)

  • executeUpdate:执行DML(增、删、改)语句、DDL语句,返回影响的行数
  • eqecuteQuery:执行DQL(查)语句,返回结果集对象

ResultSet(结果集对象)

  • next:光标移动到下一行
  • getXxx(参数)
    • Xxx:数据类型
    • 参数:int值代表列的编号;String代表列的名称

PreparedStatement(预编译执行sql的对象)

  • sql注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题

    • 在后面加上or ‘a’ = 'a’就变成了恒等式
  • 预编译sql:参数使用?作为占位符

  • 给?赋值:setXxx(参数1,参数2)

    • 参数1:?的位置编号,从1开始
    • 参数2:?的值
  • 能够防止sql注入,而且效率更高

13.2 JDBC工具类

package JDBC;

import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.sql.*;
import java.util.Properties;


/**
 * JDBC工具类
 */
public  class JDBCUtils {

    private static String url;
    private static String user;
    private static String password;
    private static String driver;

    //读取资源文件,获取值,静态代码块只执行一次
    static {
        try{
            //1.创建Properties集合类
            Properties pro = new Properties();

            //加载jdbc.properties文件
            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
            InputStream is = classLoader.getResourceAsStream("properties/jdbc.properties");
            pro.load(is);

            //获取数据
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");

            //注册驱动
            Class.forName(driver);

        } catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

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

    /**
     * 释放资源
     * @param stmt
     * @param conn
     */
    public static void close(Statement stmt,Connection conn){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 释放资源
     * @param rs
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet rs,Statement stmt, Connection conn){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
url = jdbc:mysql://localhost:3306/test
user = root
password = 123456
driver = com.mysql.cj.jdbc.Driver

14.连接池(DataSource)

概念

  • 存放数据库连接的容器
  • 当系统初始化好后,容器被创建,容器中会申请一些连接对象
  • 当用户访问数据库时,从容器中获取连接对象
  • 当用户访问完后,会将连接对象归还给容器

好处

  • 节约资源
  • 用户访问高效

实现

  • 标准接口DataSource
  • 获取连接getConnection()
  • 如果Connection是从连接池中获取的,那么Connection.close()不会关闭连接,而是归还连接
  • 有数据库厂商来实现
  • C3P0、Druid

14.1C3P0

  • 导入maven依赖
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>
  • 创建配置文件cp30-config.xml
<?xml version="1.0" encoding="UTF-8"?>

<c3p0-config>
    <default-config>
        <!-- 配置JDBC 四个基本属性 -->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <!--连接池参数-->
        <!--初始化申请的连接数量-->
        <property name="initialPoolSize">5</property>
        <!--最大的连接数-->
        <property name="maxPoolSize">10</property>
        <!--超时时间-->
        <property name="checkoutTimeout">3000</property>
    </default-config>

</c3p0-config>
  • 创建连接池对象并获取连接
DataSource ds = new ComboPooledDataSource();
Connection connection = ds.getConnection();

15.2 Druid

  • 导入maven依赖
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.6</version>
 </dependency>
  • 编写配置文件
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=123456

maxActive=10
initialSize=5
maxWait=3000
  • 工具类
package druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DruidUtils {
    private static DataSource ds;

    static {
        try {
            //1.加载配置文件
            Properties pro = new Properties();
            InputStream is = Demo.class.getClassLoader().getResourceAsStream("properties/druid.properties");
            pro.load(is);

            //获取DataSource
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

    //关闭连接
    public static void close(Statement stmt,Connection conn){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(conn != null){
            try {
                conn.close();//归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //关闭连接
    public static void close(ResultSet rs,Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        close(stmt,conn);
    }

  	//获取连接池
    public static DataSource getDataSource(){
        return ds;
    }
}

15. Spring JDBC

**概念:**Spring框架对JDBC的简单封装提供了JDBCTemplate对象简化JDBC的开发

步骤

  • 导入Maven依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.0.9.RELEASE</version>
</dependency>
  • 创建JdbcTemplate对象。依赖于数据源DataSource
JdbcTemplate jb = new JdbcTemplate(DruidUtils.getDataSource());
  • 调用JdbcTemplate对象的方法进行CRUD操作

    • update():执行DML语句,增、删、改语句

      //执行DML语句
      JdbcTemplate jb = new JdbcTemplate(DruidUtils.getDataSource());
      
      String sql = "update data set score = 100 where id = ?";
      
      int count = jb.update(sql, 4);
      
      System.out.println(count);
      
    • qieryForMap():查询结果将结果集封装为Map集合

      JdbcTemplate jb = new JdbcTemplate(DruidUtils.getDataSource());
      
      String sql = "select * from data where id = ?";
      //查询的结果集长度只能为1
      Map<String, Object> map = jb.queryForMap(sql, 4);
      
      System.out.println(map);      
      
    • queryForList():查询结果将结果集封装为List集合

        JdbcTemplate jb = new JdbcTemplate(DruidUtils.getDataSource());
      
      String sql = "select * from data";
      
      //将每一条记录封装为map集合,然后合起来变成list集合
      List<Map<String, Object>> maps = jb.queryForList(sql);
      
      for (Map<String, Object> map : maps) {
          System.out.println(map);
      }
      
    • query():查询结果,将结果封装为JavaBean对象

      JdbcTemplate jb = new JdbcTemplate(DruidUtils.getDataSource());
      
      String sql = "select * from data";
      
      //new BeanPropertyRowMapper<data>(data.class)
      List<data> query = jb.query(sql, new BeanPropertyRowMapper<data>(data.class));
      
      for (data data : query) {
          System.out.println(data);
      }
      
    • queryForObject():查询结果,将结果封装为对象

      JdbcTemplate jb = new JdbcTemplate(DruidUtils.getDataSource());
      
      String sql = "select * from data";
      //常用来运行聚合函数
      Long aLong = jb.queryForObject(sql, Long.class);
      
      System.out.println(aLong);
      
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值