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
字段列表
FROM
表1
LEFT [OUTER] JOIN
表2
ON
条件
-- 右外连接 【查询右表所有数据和交集部分】
SELECT
字段列表
FROM
表1
RIGHT JOIN
表2
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);
-