java篇-数据库MySQL

数据库基础

  • 数据库作用
    减少内存(掉电就丢失),存储数据,管理数据,增删改查,保存数据的容器

  • 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,顺序:ASCLIMIT
			分页限定

基础的查询
多个字段的查询: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 查询的字段列表 from1 left [outer] join2 on 条件-- outer 可以省略
  • 右外链接
    查询的是右表所有数据以及其交集部分
语法 select 查询的字段列表 from1 right [outer] join2 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. 事务四大特征(面试)

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

3. 事务的隔离级别

多个事务之间相互独立,如果多个事务操作同一批数据会出现一些问题,设置不同的隔离级别就可以解决这些问题

  1. 存在问题:
    • 脏读:一个事务读取到另一个事务中没有提交的数据
    • 不可重复读:在同一个事务中,两次读取的数据不一样
    • 幻读:一个事务(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改
  2. 隔离级别:
    • read uncommitted: 读未提交
      产生的问题:脏读、不可重读、幻读
    • read committed:读以提交
      产生的问题:不可重读、幻读
    • repeatable read:可重复度
      产生的问题:幻读
    • serializable:串行化
      可以解决所有的问题
      注意隔离级别从小到大安全性越高,但是效率越低
    • 数据库设置隔离级别
      set global transaction isolation level 级别字符串;
    • 读取数据库隔离级别
      select @@tx_isolation;
      在这里插入图片描述

DCL:

DDL:操作数据库和表
DML:增删改表中的数据
DQL:查询表中数据
DCL:管理用户和授权

DBA:数据库管理员

  1. 管理用户:
-- 切换到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
-- 
  1. 权限管理
    • 查询权限-- 查询权限 SHOW GRANTS FOR '用户名'@'主机名';
    • 授予权限-- 授予权限 grant 权限列表 on 数据库名.表名 to '用户名'@ '表名'
    • 撤销权限

JDBC

  1. 概念:Java database connectivity Java ,Java数据库连接
    定义了一套操作所有关系型数据库的规则(接口)
    JDBC本质:其实是官方公司定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动JAR包,我们可以使这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

  2. 快速入门:
    步骤:导入驱动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();
  1. 各个对象

    • DriverManager:驱动管理对象
      功能:

      1. 注册驱动 :告诉程序使用哪个类驱动。通过查看源码发现在com.mysql.cj.jdbc.Driver类中存在静态代码块
      2. 获取数据库连接:
        Connection getConnection (String url, String user, String password) 通过连接字符串,用户名,密码来得到数据库的连接对象
        在这里插入图片描述
    • Connection :数据库连接对象

      1. 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();
				}
			}
		}
		
		
		
	}

}

  1. 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,接收返回的结果
      处理结果
      释放资源
  2. 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);
				
			}
		}
		
		
		
	}







数据库连接池

  1. 数据库连接池

    • 概念:其实就是一个容器,存放数据库连接的容器。当系统初始化好后,会在容器中申请一些连接对象,当用户来访问数据库时,从容器里获取连接对象,用户访问完后,会将连接归还给容器
    • 优点:访问高效,节约资源
    • 实现
      • 标准接口:DataSource Java.sql包下
        • 方法:getConnection(),如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了而是归还连接
      • 一般我们不去实现它,由数据库厂商去实现
        1. C3P0:数据库连接池技术
        2. Druid:数据库连接池实现技术,由阿里巴巴提供的
    • C3P0:数据库连接池技术
      1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,

        • 不要忘记导入数据库驱动jar包
      2. 定义配置文件:

        • 名称: c3p0.properties 或者 c3p0-config.xml
        • 路径:直接将文件放在src目录下即可。
      3. 创建核心对象 数据库连接池对象 ComboPooledDataSource

      4. 获取连接: getConnection

  2. spring JDBC
    * Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发

  • 步骤:
    1. 导入jar包

    2. 创建JdbcTemplate对象。依赖于数据源DataSource

      • JdbcTemplate template = new JdbcTemplate(ds);
    3. 调用JdbcTemplate的方法来完成CRUD的操作

      • update():执行DML语句。增、删、改语句
      • queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
        • 注意:这个方法查询的结果集长度只能是1
      • queryForList():查询结果将结果集封装为list集合
        • 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
      • query():查询结果,将结果封装为JavaBean对象
        • query的参数:RowMapper
          • 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
          • new BeanPropertyRowMapper<类型>(类型.class)
      • queryForObject:查询结果,将结果封装为对象
        • 一般用于聚合函数的查询

版权声明:本文为MGfanfan原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。