数据库基础
数据库作用
减少内存(掉电就丢失),存储数据,管理数据,增删改查,保存数据的容器DB:数据库
有组织的数据DBMS:数据库管理系统
数据库是通过DBMS创建和操作容器SQL:structured query language 结构化查询语言,定义了操作所有关系数据库得规则
与数据库通信的语言,几乎所有的DBMS都支持SQL数据库的特点:
数据->表->库
一个数据库可以有多个表,表名唯一
表具有特性,存储
表由列组成,也可以称为字段,所有的表由一个或多个列组成,每一列类似Java中的属性
行组成产品特点
成本低,开源代码,免费
性能高
简单DBMS分两类
基于文件共享的
基于客户机-服务器的DBMS启动和停止mysql
使用cmd(管理员),net stop/start mysql
mysql自带的客户端:不方便
windows客户端**P:端口号
h:主机
p:密码
mysql -h localhost -P 3306 -u root -p
mysql -h localhost -P 3306 -u root -p1234
**
退出:exit/ctrl+c
常见命令
show databases; 展示数据库
只有test库可以动
打开库:use +库名称;
查看在哪个库,select database();
创建表:mysql> create table biaoming(
-> id int,
-> name varchar(20));
查看表的结构:desc biaoming;
查看服务器版本:登录mysql服务端 select version()
没有登录:mysql --version
- mysql的语法规范:
1 不区分大小写,但建议关键字大写,表名列名小写
2 每条命令最好用分号结尾
3 每条命令根据需要,可以进行缩进或者换行
4 注释
单行:#注释文字
单行:-- 注释文字,注意两个-后面有空格空格
多行:/注释/
- SQL分类:
DDL:操作数据库、表,关键字:create,drop,alter等
DQL:查寻表中得数据, 关键字:select,where
DML:增删改表中得数据,关键字:insert, delete, updata
DCL:授权,关键字:grant,revoke

- DDL:操作数据库、表
1、操作数据库 CRUD
**C: create创建**
· 创建数据库:create database 数据库名称;
· 创建数据库判断是否存在:create database if not exists 数据库名称
· 创建数据库并指定字符集名称:create database 数据库名称 character set 字符集名称;
·创建一个数据库并判断是否存在,并制定字符集dbg;create database if not exists db4 character set gbk;
**R:retrieve:查询**
· 查询所有数据库得名称:show databases;
· 查看某个数据库得字符集:查询莫格数据库得创建语句:show create database mysql;
**U:update:修改**
· 修改数据库得字符集 alter database 数据库名称 character set 字符集名称
**D: delete 删除**
· 删除数据库: drop database 数据库名称;
· 判断数据库存在,存在删除: drop database if exists 数据库名称;
**使用数据库**
· 查询当前正在使用得数据库名称: select database();
· 使用数据库: use 数据库名称;
**2、操作表 CRUD**
**C: create创建**
·创建:create table 表名(
列名1 数据类型1,
列名2 数据类型2,
...
列名n 数据类型n
);
数据库类型:int :整数,double:小数类型(scroe double(5,2)),date:日期,只包含年月日(yyyy-MM-dd),datetime:日期,包含时分秒,timestamp:时间错类型:包含时分秒,如果将来不给这个字段赋值,或者为Null,则自动赋值,varchar:字符串类型,如name varchar(20),此处得20表述姓名最大20字符。
create table student(
id int,
name varchar(32),
age int,
score double(4,1),
birthday date,
inserttime timestamp
);
复制表
creat table 新建得表名 like 需要复制表得表名
**R:retrieve:查询**
· 查询某个数据库中所有得表名称 show tables;
· 查询表结构: desc 表名;
**U:update:修改**
·修改表名称: alter table 表名 rename to 新得表名
·修改表得字符集 :alter table 表名称 character set 字符集名称;
·添加列:alter table 表名 add 列名 数据类型;
·修改列类型,名称:alter table 表名 change gender 列名 新列名 新数据类型;或者alter table 表名 modify 列名 新数据类型;;
·删除列: alter 表名 stu drop 列名;
**D: delete 删除**
·drop table 表名;
·drop table if exists 表名;
客户端图形化工具:SQLYOG
DML:增删改表中得数据
1 添加数据
语法:insert into 表名(列名1,列名2,。。。列名n) values(值1,值2,。。值n);
**注意事项:**列名和值要一一对应
如果表名后不定义列名,则给所有列添加值
除了数字类型,其他类型需要使用引号引起来,单双都可以
2 删除数据
语法:delete from 表名 where 条件
注意:
如果不加条件,则删除所有的记录,一般都属不建议使用这个
如果要删除所有的记录: TRUNCATE TABLE 表名;-- 删除表,然后建立一个一摸一样的空表
3 修改数据
语法: update 表名 set 列名1 = 值1,列名 = 值2,。。。 where 条件
注意:
如果不加任何条件,就会修改所有的条件
DQL:查询表中的记录
select * from 表名
DQL:查寻表中得数据
- 查询语句
select * from 表名
语法:
select
列表字段
from
表名列表
where
条件列表
grop by
分组字段
having
分组之后的条件限定
order
排序(倒叙:DESC,顺序:ASC)
LIMIT
分页限定
基础的查询
多个字段的查询:select 字段名1,字段名2 from 表名
如果查询所有字段:可以使用*替代这个列表。
去除 重复的结果:delect distinct 列名 from 表名;
计算列:可以使用四则表达式计算一些列的表达式
条件查询
where子句后跟条件
运算符
like:
1 排序查询
语法:
order by 子句
order by 排序字段1,排序方式1, 排序字段2,排序方式2....
排序方式 :
ASC:升序,默认的
DESC:降序
注意:当有多个排序条件,只有当前面的值相等时,才会判断当前的排序语句
2 聚合函数:将一列数据作为整体,进行纵向计算
count:计算个数
一般选择非空的列:主键
count(*)
max:计算最大值
min:计算最小值
sum:求和
avg:平均值
注意:聚合函数的计算,会排除空的值
解决方案:选择不包含非空的列:主键
IFNULL函数
3 分组查询
语法:group by
- 按照年龄分组,
SELECT age ,AVG(score) FROM stu GROUP BY age;
-- 分数低于90分不参与分组
SELECT age ,AVG(score) FROM stu WHERE score>90 GROUP BY age;
-- 分数低于90分不参与分组,且分组人数大于1
SELECT age ,AVG(score) FROM stu WHERE score>90 GROUP BY age HAVING COUNT(id)>1;
注意:
分组之后查询的字段:分组字段和聚合函数
where和having的区别:where在分组之前就进行限定,不满足则不进行分组。having是在分组之后限定,如果不满足条件,不会显示出来
where 后不可以跟聚合函数,having可以跟
4 分页查询
语法: limit 开始的索引,每页查询的条数;
-- 每一页显示三条
SELECT * FROM stu LIMIT 0,3;-- 第一页
SELECT * FROM stu LIMIT 3,3;-- di二页
-- 公式,开始的索引 = (当前页码-1)*3;
分页操作是 一个“方言”limit只能在mysql中使用
- 约束:对表中的数据限定,保证数据的正确性,有效性和完整性
分类:
1 主键约束:primary key
、注意:含义:非空且唯一
一张表只能有一个字段为主键
主键就是表中记录的唯一标识
、在创建表时,添加主键约束
CREATE TABLE student(
id INT PRIMARY KEY,-- 给id 添加主键约束
phone_number VARCHAR(20)
);
、删除主键
ALTER TABLE student DROP PRIMARY KEY;
、创建完表后,添加主键
ALTER TABLE student MODIFY id INT PRIMARY KEY;
、自动增长:
- 如果一列数值类型,使用auto_increment可以完成值的自动增长
- 再创建表时,添加主键约束,并且完成自键自增长
create table student(
id int primary key auto_increment,-- 给id添加主键约束
name varchar(20)
) ;
- 删除自动增长
ALTER TABLE student MODIFY id INT;
- 添加自动增长
ALTER TABLE student MODIFY id INT AUTO_INCREMENT;
2 非空约束:not null
、在创建表时创建约束
CREATE TABLE STUDENT(
id INT,
NAME VARCHAR(20) NOT NULL-- name 非空
);
、创建表后添加非空约束
ALTER TABLE student MODIFY NAME VARCHAR(20) NOT NULL;
、删除非空约束
-- 删除name的非空约束
ALTER TABLE student MODIFY NAME VARCHAR(20);
3 唯一约束:unique,值不能重复
-- 创建表时添加唯一约束
CREATE TABLE student(
id INT,
phone_number VARCHAR(20) UNIQUE -- 添加唯一约束
);
-- 删除唯一约束
-- alter table student modify phone_number varchar(20);-- 删除不了,这是错误的
ALTER TABLE student DROP INDEX phone_number;
-- 创建表之后添加唯一约束
ALTER TABLE student MODIFY phone_number VARCHAR(20) UNIQUE;
注意唯一限定可以有多个null值
4 外键约束:foregin key
、在创建表时,可以添加外键
* 语法:
create table 表名(
....
外键列
constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称)
);
、删除外键:
ALTER TABLE employee DROP FOREIGN KEY emp_dep_fk;
、创建表后添加外键
ALTER TABLE employee ADD CONSTRAINT emp_dep_fk FOREIGN KEY
(dep_id) REFERENCES department(id);
、级联操作:在修改和删除主表的主键时,同时更新或删除副表的外键值,称为级联操作
- 添加删除级联操作
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称)
REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE;
- 分类
级联更新 ON UPDATE CASCADE
级联删除 ON DELETE CASCADE;
在实际的操作中,会非常谨慎使用
数据库的设计
- 多表之间的关系
、分类
1 一对一:如人和身份证
分析一个人只有一个身份证,一个身份证只能对应一个人
2一对多,多对一:
如部门和员工
3 多对多
如学生和课程
、实现关系
1一对多,多对一:
在 多的一方建立外键,指向一的一方的主键
2 多对多:
要借助中间表(在后面介绍)中间表至少包含两个字符,这两个字符作为第三张表的外键,分别指向两张表的主键
联合主键
- 范式:设计数据库时,所需要遵循的关系
分类:
- 1 第一范式(1NF):每一列都是不可分割的原子数据项
- 2 第二范式(2NF): 在1NF的基础上,非码属性必须依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
几个概念
函数依赖:A->B,如果可以通过A的值能够确定B的值,那可以说B依赖于A
完全函数依赖:A->B,如果A是一个属性组,则B的值是由A属性组所有的属性值所确定
部分函数依赖:A-》B,如果A是一个属性组则B的属性值的确认只需要A属性组的值
传递函数依赖A->B,B->C,则称C传递函数依赖于C
码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性值)为该表的码
主属性:码所有的属性
非主属性:除对码属性组的属性 - 3 第三范式(3NF):在2NF的基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)
数据库的备份和还原:
1 命令行
备份
mysqldump -u用户名 -p密码 >保存的路径
还原
登录数据库,创建数据库,使用数据库,执行文件,source
2 图形化工具
多表查询:
笛卡尔积:有两个集合A和B取这两个集合的组合情况
要完成多表查询,需要消除无用的数据
分类:
1 内连接查询:
- 隐式内链接:使用where条件消除无用得
-- 查询员工表得名称,性别,部门表得名称
SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id`=dept.`id`;
SELECT
t1.name,
t1.gender,
t2.name
FROM
emp t1,
dept t2
WHERE
t1.`dept_id`=t2.`id`;
- 显示内连接:
注意事项:
从那些表中查询数据
查询条件是什么
查询哪些字段
语法:select 字段列表 from 表名1 inner join 表名2 on 条件 -- inner可以省略
例如
SELECT *FROM emp INNER JOIN dept ON emp.`dept_id`=dept.`id`;
SELECT *FROM emp JOIN dept ON emp.`dept_id`=dept.`id`;
2 外连接查询
- 左外链接
查询的是左表所有数据以及其交集部分
语法 select 查询的字段列表 from 表1 left [outer] join 表2 on 条件-- outer 可以省略
- 右外链接
查询的是右表所有数据以及其交集部分
语法 select 查询的字段列表 from 表1 right [outer] join 表2 on 条件-- outer 可以省略
3 子查询
概念:查询中嵌套子查询,称嵌套的查询为子查询
例如
SELECT *FROM emp WHERE emp.`salary`=(SELECT MAX(salary) FROM emp);
子查询不同情况:
1单行单列:
子查询可以作为条件,使用运算符操作 > >= < <= =
2多行单列
子查询可以作为条件,查询的结果多行单列,使用in
-- cha财务部员工信息
SELECT id FROM dept WHERE NAME='财务部' OR NAME='市场部';
SELECT *FROM emp WHERE dept_id=3 OR dept_id=2;
SELECT *FROM emp WHERE dept_id IN (3,2);
SELECT *FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME='财务部' OR NAME='市场部');
3多行多列
子查询可以作为一张虚拟表
SELECT *FROM dept t1,(SELECT *FROM emp WHERE emp.`join_date`>'2011-11-11') t2
WHERE t1.`id`=t2.dept_id;
事务
1. 基本介绍:
- 基本概念: 如果一个包含多个步骤的业务操作被事务管理,那么这些操作同时成功,要么同时失败
- 操作:
开启事务 start transaction
回滚 rollback
提交 commit
MySQL中事务默认自动提交:事务提交的两种方式:自动提交,MySQL是自动提交的,一条DML(真删改)语句会自动提交一次事务
手动提交:需要先开启事务,在提交
修改事务的默认提交方式:
SELECT @@autocommit;-- 1 自动提交,0手动提交
SET @@autocommit=0;-- 修改
Oracle数据库是手动提交的,所以要神效要用commit语句
-- 创建数据表
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE
);
-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
SELECT *FROM account;
-- zhangsan给李四专账500
-- 开启事务
START TRANSACTION;
-- 张三账户减500`account`
UPDATE account SET balance=balance-500 WHERE NAME= 'zhangsan';
-- 李四账户加500
UPDATE account SET balance=balance+500 WHERE NAME= 'lisi';
-- 没有问题,提交事务
COMMIT;
ROLLBACK;
2. 事务四大特征(面试)
- 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败
- 持久性:如果事务一旦提交或回滚,数据库的数据会持久化的保存更数据
- 隔离性:多个事务之间相互独立
- 一致性:事务操作前后数据总量不变
3. 事务的隔离级别
多个事务之间相互独立,如果多个事务操作同一批数据会出现一些问题,设置不同的隔离级别就可以解决这些问题
- 存在问题:
- 脏读:一个事务读取到另一个事务中没有提交的数据
- 不可重复读:在同一个事务中,两次读取的数据不一样
- 幻读:一个事务(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改
- 隔离级别:
- read uncommitted: 读未提交
产生的问题:脏读、不可重读、幻读 - read committed:读以提交
产生的问题:不可重读、幻读 - repeatable read:可重复度
产生的问题:幻读 - serializable:串行化
可以解决所有的问题
注意隔离级别从小到大安全性越高,但是效率越低 - 数据库设置隔离级别
set global transaction isolation level 级别字符串; - 读取数据库隔离级别
select @@tx_isolation;
- read uncommitted: 读未提交
DCL:
DDL:操作数据库和表
DML:增删改表中的数据
DQL:查询表中数据
DCL:管理用户和授权
DBA:数据库管理员
- 管理用户:
-- 切换到MySQL数据库
USE mysql;
-- 查询user 表
SELECT * FROM USER;
-- 创建用户,使用
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
CREATE USER 'liyifeng'@'localhostli' IDENTIFIED BY '7777';
-- 删除
DROP USER '用户名'@'主机名';
DROP USER 'liyifeng'@'localhostli' ;
-- 修改liyifeng的密码
UPDATE USER SET PASSWORD=PASSWORD('新密码') WHERE USER='用户名';
UPDATE USER SET PASSWORD=PASSWORD('anc') WHERE USER='liyifeng';
-- 忘记密码怎么办
-- 1 cmd 停止MySQL,需要管理源运行
-- 2 启动MySQL,使用的是无验证的方式 mysql -- skip-grant-tables
--
- 权限管理
- 查询权限
-- 查询权限 SHOW GRANTS FOR '用户名'@'主机名'; - 授予权限
-- 授予权限 grant 权限列表 on 数据库名.表名 to '用户名'@ '表名' - 撤销权限
- 查询权限
JDBC
概念:Java database connectivity Java ,Java数据库连接
定义了一套操作所有关系型数据库的规则(接口)
JDBC本质:其实是官方公司定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动JAR包,我们可以使这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类快速入门:
步骤:导入驱动jar包: mysql-connector-java-5.1.37-bin.jar,复制这个包到项目某个目录下,右键–build path add jdbc
注册驱动:
获取数据库的连接对象 connection
定义sql 语句
获取执行sql 语句的对象 statement
执行sql,接收返回的结果
处理结果
释放资源
// 导入驱动jar包
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("数据库驱动加载成功");
//获取数据库的连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "1234");
//获取执行sql 语句的对象 statement
java.sql.Statement stat = conn.createStatement();
//定义sql 语句
String sql = "select * account where id =1";
//执行sql,接收返回的结果
int count=stat.executeUpdate(sql);
//处理结果
System.out.println(count);
//释放资源
stat.close();
conn.close();
各个对象
DriverManager:驱动管理对象
功能:- 注册驱动 :告诉程序使用哪个类驱动。通过查看源码发现在com.mysql.cj.jdbc.Driver类中存在静态代码块
- 获取数据库连接:
Connection getConnection (String url, String user, String password) 通过连接字符串,用户名,密码来得到数据库的连接对象
Connection :数据库连接对象
- Statement createStatement() 创建一条 SQL 语句对象
Statement :执行sql语句

ResultSet:结果集对象

如:getInt(参数);
参数:- int代表列的参数,从1开始 -string 代表列的名称
注意:
使用步骤
游标向下移动一行,判断是否有数据,再获取数据
抽取JDBC工具类
目的:简化
分析
注册驱动
抽取一个方法获取连接对接
不想传递参数,还得保证工具类的通用性
解决方案:配置文件
jdbc.properties
url=释放资源
while(rs.next()) {
//获取数据
int id = rs.getInt(1);
String name= rs.getNString(2);
double balance= rs.getDouble(3);
System.out.println("id:"+id+" name:"+name+" balance"+balance);
}
package database1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class shili {
public static void main(String[] args) {
// TODO Auto-generated method stub
//
Statement sta= null;
Connection con=null;
try {
Class.forName("com.mysql.jdbc.Driver");
//
String sql="insert into account values(null,'wanngwu',3000)";//insert语句
//获取connection对象
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "1234");
//hu执行sql对象 statement
sta=con.createStatement();
int m=sta.executeUpdate(sql);
System.out.println(m);
if(m>0) {
System.out.println("添加成功");
}else {
System.out.println("失败");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(sta!=null) {
try {
sta.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null) {
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
PreparedStatement:执行sql对象,后期都会用这个完成增删改查的所有操作,可以防止sql注入,效率更高
- sql注入问题:在拼接sql时,有一些特殊关键字参与拼接,会造成安全性问题
- 解决sql注入问题:使用PreparedStatement(STATEMENT的子接口)
- 预编译:
- 步骤:导入驱动jar包: mysql-connector-java-5.1.37-bin.jar,复制这个包到项目某个目录下,右键–build path add jdbc
注册驱动
获取数据库的连接对象 connection
定义sql 语句
- 注意: sql的参数使用?作为占位符
获取执行sql 语句的对象 PreparedStatement,需要传递进去Connection。prepareStatement(String sql);
给?赋值:
- 方法 setXxx(参数1 ,参数2);
参数1
参数2:?的值
执行sql,接收返回的结果
处理结果
释放资源
JDBC控制事务
- 事务:
- 操作
- 使用connection 对象管理事务
//优化
package util;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
public class JDBCutil {
/*
* 文件的读取只需要一次
* 可以使用静态代码块,随着类的执行而执行,且只执行一次
*/
//
private static String url;
private static String user;
private static String password;
private static String driver;
static {try {
//创建propertie集合类
Properties pro= new Properties();
//获取src路径下的文件方式--》classloader 类加载器
ClassLoader classloader = JDBCutil.class.getClassLoader();
URL res = classloader.getResource("jdbc.properties");
String path= res.getPath();
System.out.println(path);
//加载wenjian
// pro.load(new FileReader("src/jdbc.properties"));
pro.load(new FileReader(path));
//获取数据,赋值
url=pro.getProperty("url");
user=pro.getProperty("user");
password=pro.getProperty("password");
driver=pro.getProperty("driver");
//注册驱动
Class.forName(driver);
}catch(IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public static java.sql.Connection getConnection() throws SQLException {
/*
*
* 获取连接
* 返回连接对象
*/
return DriverManager.getConnection(url,user,password);
}
//释放资源
public static void close(java.sql.Statement stmt, java.sql.Connection conn) {
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//释放资源
public static void close(ResultSet rs, java.sql.Statement stmt, java.sql.Connection conn) {
// TODO Auto-generated method stub
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package database1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import util.JDBCutil;
public class JdbcTest1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//
Statement stmt= null;
Connection conn=null;
ResultSet rs=null;
try {
String sql="select *from account;";//insert语句
// //获取connection对象
conn=JDBCutil.getConnection();
stmt=conn.createStatement();
//执行结果
rs=stmt.executeQuery(sql);
//让光标在表中移动一行
while(rs.next()) {
//获取数据
int id = rs.getInt(1);
String name= rs.getNString(2);
double balance= rs.getDouble(3);
System.out.println("id:"+id+" name:"+name+" balance"+balance);
}
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//
JDBCutil.close(rs,stmt,conn);
}
}
}
数据库连接池
数据库连接池
- 概念:其实就是一个容器,存放数据库连接的容器。当系统初始化好后,会在容器中申请一些连接对象,当用户来访问数据库时,从容器里获取连接对象,用户访问完后,会将连接归还给容器
- 优点:访问高效,节约资源
- 实现
- 标准接口:DataSource Java.sql包下
- 方法:getConnection(),如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
- 一般我们不去实现它,由数据库厂商去实现
- C3P0:数据库连接池技术
- Druid:数据库连接池实现技术,由阿里巴巴提供的
- 标准接口:DataSource Java.sql包下
- C3P0:数据库连接池技术
导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
- 不要忘记导入数据库驱动jar包
定义配置文件:
- 名称: c3p0.properties 或者 c3p0-config.xml
- 路径:直接将文件放在src目录下即可。
创建核心对象 数据库连接池对象 ComboPooledDataSource
获取连接: getConnection
spring JDBC
* Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
- 步骤:
导入jar包
创建JdbcTemplate对象。依赖于数据源DataSource
- JdbcTemplate template = new JdbcTemplate(ds);
调用JdbcTemplate的方法来完成CRUD的操作
- update():执行DML语句。增、删、改语句
- queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
- 注意:这个方法查询的结果集长度只能是1
- queryForList():查询结果将结果集封装为list集合
- 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
- query():查询结果,将结果封装为JavaBean对象
- query的参数:RowMapper
- 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
- new BeanPropertyRowMapper<类型>(类型.class)
- query的参数:RowMapper
- queryForObject:查询结果,将结果封装为对象
- 一般用于聚合函数的查询