数据库的学习以及JDBC的基础知识

数据库的学习以及JDBC的基础知识

主要用到MySQL、sqlyog图形化工具、idae、以及一些jar包,初步了解了MySQL的增删改查(CRUD)等。

数据库的学习

一. 数据库的基本概念
  1. 1 数据库的英文单词:Database 简称:DB

    1.2 什么是数据库?

    • 用于存储和管理数据库的仓库。

    1.3 数据库的特点:

    • 持久化存储数据的。其实数据库就是一个文件系统
    • 方便存储和管理数据
    • 使用了统一的方式操作数据库 —— SQL
二. MySQL数据库软件
  1. 安装

  2. 卸载

      1. 去mysql的安装目录找到 my.ini 文件
      • 复制 datadir = “C:\ProgramData\MySQL\MySQL Server 5.5\data”
      1. 卸载MySQL
      1. 删除C:\ProgramData目录下的MySQL文件夹
    1. 配置

    ** MySQL服务启动

      1. 手动
      1. cmd --> services.msc 打开服务的窗口
      1. 使用管理员打开cmd
      • net start mysql : 启动MySQL的服务
      • net stop mysql : 关闭MySQL服务

    ** MySQL登录

      1. mysql -uroot -p 密码
      1. mysql -hip -uroot -p 连接目标的密码
      1. mysql --host=ip --user=root --passworld=连接目标的密码

    ** MySQL退出

      1. exit
      1. quit

    ** MySQL目录结构

      1. MySQL的安装目录
        • 配置文件 my.ini
      1. MySQL的数据目录

        几个概念:

        • 数据库:文件夹
        • 表:文件
        • 数据:数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87WLEI0p-1573824169845)(C:\Users\Think-Pad\Desktop\数据库\MySQL目录结构.jpg)]

SQL
2.1. 什么是SQL?

​ Structured Query Language : 结构化查询语言

​ 其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在币一样的地方,称为“方言”。

2.2. SQL通用语法
  1. SQL语句可以使用单行或多行书写,以分号结尾
  2. 可使用空格和缩进进行增强语句的可读性
  3. MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用小写
  4. 3 种注释
    • 单行注释:-- 注释内容 或 # 注释内容(MySQL 特有)
    • 多行注释:/* 注释 */
三. SQL分类

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

​ 用来定义数据库对象:数据库,表,列等。关键字:create,drop,alter等

​ 2) DML(Data Mainplution Language)数据库操作语言

​ 用来对数据库中的表的数据进行增删改。关键字:insert,delete,update等

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

​ 用来查询数据库中的表的记录(数据)。关键字:select,where等

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

​ 用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REMOVE等

3.1 DDL:操作数据库、表

一、 操作数据库

  1. C(Create):创建

    • 创建数据库:

      • create database 数据库名称;
    • 创建数据库,判断不存在,再创建:

      • create database if not exists 数据库名称;
    • 创建数据库,并指定字符集

      • create database 数据库名称 character set 字符集名;
    • 练习: 创建db4数据库,判断是否存在,并制定字符集为gbk

      • create database if not exists db4 character set gbk;
      1. R(Retrieve) : 查询
 * 查询所有数据库的名称:
   * show  databases;
 * 查询某个数据库的字符集:查询某个数据库的创建语句
   * show  create  database  数据库名称;
   
	3.   U(Update) : 修改
 * 修改数据库的字符集
   * alter  database  数据库名称  character  set  字符集名称;
	4.   D(Delete):  删除
 * 删除数据库
   * drop  database  数据库名称;
 * 判断数据库存在,存在再删除
   * drop  database  if  exists  数据库名称;
	5.   使用数据库
 * 查询当前正在使用的数据库名称
   * select  database();
 * 使用数据库
   * use  数据库名称;

二、 操作表

  1. C(Create):创建

    1. 语法:

      create table 表名(

      列名1 数据类型1,

      列名2 数据类型2,

      。。。

      列名n 数据类型n

      );

      • 注意:最后一列,不需要加逗号(,)

      • 数据库类型:

        1. int :整数类型

          • age int,
        2. double : 小数类型

          • score double(5,2)
        3. date : 日期,只包含年月日,yyyy - MM -dd

        4. datatime : 日期,包含年月日时分秒 yyyy -MM -dd

        5. timestamp : 时间错类型 包含年月日时分秒 yyyy - MM - dd

          HH:mm:ss

          • 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值
        6. varchar : 字符串

          • name varchar(20) : 姓名最大20个字符
          • zhangsan 8个字符 张三 2个字符
      • 创建表

        • create table student(

          id int,

          name varchar(32),

          age int ,

          score double(4,1),

          birthday date,

          insert_time timestamp

          );

      • 复制表 :

        • create table 表名 like 被复制的表名;
  2. R(Retrieve) : 查询

    • 查询某个数据库中的所有的表的名称
      • show tables;
    • 查询表结构
      • desc 表名;
  3. U(Update) : 修改

    • 修改表名
      • alter table 表名 rename to 新的表名;
    • 修改表的字符集
      • alter table 表名 character set 字符集名称;
    • 添加一列
      • alter table 表名 add 列名 数据类型;
    • 修改列名称 类型
      • alter table 表名 change 列名 新列名 数据类型;
      • alter table 表名 modify 列名 新数据类型;
    • 删除列
      • alter table 表名 drop 列名;
  4. D(Delete): 删除

    • drop table 表名;
    • drop table if exists 表名;
客户端图形化工具:SQLYog
3.2 DML:增删改表中数据
  1. 添加数据:

    • 语法:

      • insert into 表名(列名1,列名2,…列名n) values (值1,值2,…值n);
    • 注意:

      • 列名和值要一一对应。

      • 如果列名后,不定义列名,则默认给所有列添加值

        insert into 表名 values(值1,值2,…值n);

      • 除了数字类型,其他类型需要使用引号(单双都可以)引起来

    • 删除数据:

      • 语法:
        • delete from 表名 [where 条件]
      • 注意:
        • 如果不加条件,则删除表中所有记录。
        • 如果要删除所有记录
          1. deletet from 表名; – 不推荐使用。有多少条记录就会执行多少次删除操作
          2. truncate table 表名; – 推荐使用,效率更高 先删除表,然后再创建一张一样的表。
    • 修改数据:

      • 语法:
        • update 表名 set 列名1 = 值1,列名2 = 值2, … [where 条件];
      • 注意:
        1. 如果不加任何条件,则会将表中所有记录全部修改。
3.3 DQL : 查询表中的记录(查询语句)
  • select * from 表名;

  • 语法:

    • select

      字段列表

      from

      ​ 表名列表

      where

      ​ 条件列表

      group by

      ​ 分组字段

      having

      ​ 分组之后的条件

      order by

      ​ 排序

      limit

      ​ 分页限定

  • 基础查询

    • 多个字段的查询

      select 字段名1,字段名2…from 表名;

      ​ 注意:

      ​ 如果查询所有字段,则可以使用 * 来代字段列表。

    • 去除重复:

      ​ distinct

      ​ – select distinct 列名 from 表名;

    • 计算列

      一般可以使用四则运算计算一些列的值。(一般只会进行值型的计算)

      ​ ifnull (表达式1,表达式2) :null 参与的运算,计算结果都为null

      ​ 表达式1 :哪个字段需要判断是否为null

      ​ 表达式2 :如果该字段为null后的替换值

    • 起别名:

      ​  as : as 也可以省略

      • select 列名1,列名2 +ifnull(列名,0) as 总分 from 表名;
    1. 排序查询
    • 语法: order by 子句
      • order by 排序字段1 排序方式1, 排序字段2 排序方式2…
    • 排序方式:
      • ASC : 升序,默认的
      • DESC : 降序
    • 注意 :
      • 如果有多个排序条件,则当前边的条件值一样时,才会判断第二种条件
  • select * from 表名 order by 列名 ASC;

  1. 聚合函数 :将一列数据作为一个整体,进行纵向的计算。
  2. count : 计算个数
    1. 一般选择非空的列 :主键
  3. max : 计算最大值
  4. min :计算最小值
  5. sum : 计算和
  6. avg : 计算平均值
  • select count(列名) from 表名;

  • 注意:聚合函数的计算,排除null值

    ​ 解决方案:

    1. 选择非空的列进行计算
    2. IFNULL函数
  1. 分组查询

    1. 语法 : group by 分组字段;
    2. 注意:
      1. 分组之后查询的字段:分组字段 、聚合函数
      2. where 和 having 的区别?
        • where 在分组之前进行限定,如果不满足条件,则不参与分组。having 在分组之后进行限定,如果不满足结果,则不会被查询出来。
        • where 后不可能跟聚合函数,having 可以进行聚合函数的判断。
    • select 分组列名, AVG(列名) from 表名 group by 分组列名;
  2. 分页查询

    1. 语法:limit 开始的索引,每页查询的条数;
    2. 公式:开始的索引 = (当前的页码 - 1 )* 每页显示的条数
    • 每页显示3条记录
      • select * from 表名 limit 0,3; --第1页
      • select * from 表名 limit 3,3; --第2页
      • select * from 表名 limit 6,3; --第3页
    1. limit 是一个MySQL“方言”

    5. 条件查询

    1. where子句后跟条件
    2. 运算符
      • < 、>、<= 、>= 、= 、<>
      • between…and
      • in(集合)
      • like :模糊查询
        • 占位符:
          • _ : 单个任意字符
          • % :多个任意字符
      • is null
      • and 或 &&
      • or 或 ||
      • not 或 !
    • – 查询年龄大于20岁

      ​ select * from student where age > 20;

    • – 查询年龄不大于20岁

      ​ select * from student where age != 20;

      ​ select * from student where age <> 20;

    • – 查询年龄大于等于20岁 小于等于30

      ​ select * from student where age >= 20 && age <= 30;

      ​ select * from student where age >= 20 and age <= 30;

      ​ select * from student where 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,15);

    • – 查询英语成绩为null

      ​ select * from student where english = null; – 不对的。

      ​ null 不能使用 = (!=) 判断

      ​ select * from student where english is null;

      – 查询英语成绩不为null

      ​ select * from student where english is not null;

      – 查询姓马的有哪些? like

      ​ select * from student where name like ‘马%’;

      – 查询第二个字是化的人

      ​ select * from student where name like ‘_化%’;

      – 查询姓名是3个字的人

      ​ select * from student where name like ‘___’;

      – 查询姓名中包含德的人

      ​ select * from student where name like ‘%德%’;

      3.4 DCL :管理用户,授权
      • DBA:数据库管理员

      • DCL:管理用户,授权

        1. 添加用户:

          • 语法:creat user ‘用户名’@‘主机名’ indentified by ‘密码’;
        2. 删除用户:

          • 语法:drop user ‘用户名’@‘主机名’;
        3. 修改用户密码:

          update user set password = password(‘新密码’) where user = (‘用户名’);

          set password for ‘用户名’@‘主机名’ = password(‘新密码’);

          • mysql 中忘记了root用户的密码?
            1. cmd --> net stop mysql 停止MySQL服务
              • 需要管理员运行该cmd
            2. 使用无验证方式启动MySQL服务:MySQL --skip-grant-tables
            3. 打开新的cmd窗口,直接输入MySQL命令,敲回车键。就可以登录成功
            4. use mysql;
            5. update user set password = (‘你的新密码’) where user = ‘root’;
            6. 关闭两个窗口
            7. 打开任务管理器,手动结束mysql.exe 的进程
            8. 启动MySQL服务
            9. 使用新密码登录
        4. 查询用户:

          – 1. 切换到MySQL数据库

          use mysql;.

          – 2. 查询user表

          select * from user;

      • 权限管理:

        • 通配符:% 表示可以在任意主机使用用户登录
        1. 查询权限:

          – 查询权限:

          show grants for ‘用户名’@‘主机名’;

        2. 授予权限:

          – 授予权限

          grant 权限列表 on 数据库名,表名 to ‘用户名’@‘主机名’;

          – 给张三用户授予所有权限,在任意数据库任意表上

          grant all on * . * to ‘zhangsan’@‘localhost’;

        3. 撤销权限:

          – 撤销权限:

          revoke 权限列表 on 数据库名,表名 from ‘用户名’@‘主机名’;

      四、约束
      4.1 概念:对表中的数据进行限定,保证数据的正确性、有效性和完整性。
      4.2 分类:
      • 主键约束:primary ley
      • 非空约束: not null
      • 唯一约束: unique
      • 外键约束: foreign key
      4.3 非空约束: not null
      • 创建表时添加约束

        creat table stu(

        ​ id int,

        ​ name varchar(20) not null ; – name为非空

        );

      • 创建表完后,添加非空约束

        alter table stu modify name varchar(20) not null;

      • 删除name的非空约束

        alter table stu modify name varchar(20);

      4.4 唯一约束: unique,值不能重复
      • CREATE TABLE stu(
        id INT,
        phone_number VARCHAR(20) UNIQUE – 添加了唯一约束
        );
        – 注意MySQL中,唯一约束限定的列的值可以有多个null

      • – 删除唯一约束
        ALTER TABLE stu MODIFY phone_number VARCHAR(20);

      • – 在创建表后,添加唯一约束

        alter table stu modify phone_number varchar(20) unique;

      4.5 主键约束 : primary key
      • 注意:

        1. 含义:非空且唯一
        2. 一张表只能有一个字段为主键
          3. 主键就是表中记录的唯一标识
      • 在创建表时,添加主键约束

        CREATE TABLE stu(
        id INT PRIMARY KEY, – 给id添加主键约束
        NAME VARCHAR(20)
        );

        – 删除主键
        – 错误 alter table stu modify id int;
        ALTER TABLE stu DROP PRIMARY KEY;

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

      • 主键约束——自动增长

        CREATE TABLE stu (
        id INT PRIMARY KEY AUTO_INCREMENT, – 给id添加主键约束
        NAME VARCHAR(20)
        );

        INSERT INTO stu VALUES(NULL,‘fff’);

        – 删除自动增长
        ALTER TABLE stu MODIFY id INT;
        – 添加自动增长
        ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;

        4.6 外键约束:foreign key ,让表与表产生关系,从而保证数据的正确性。
        • 在创建表时,可以添加外键

          ​ 语法:

          create table 表名(

          ​ …

          外键列

          constraint 外键名称 foreign key(外键列名称) references 主表名称(主表列名称)

          );

        • 删除外键

          alter table 表名 drop foreign key 外键名称;

        • 创建表之后,添加外键

          alter table 表名 add constraint 外键名称 foreign key(外键列名称) references 主表名称(主表列名称);

        • 级联操作

          1. 添加级联操作

            语法:

            alter table 表名 add constraint 外键名称 foreign key(外键字段名称) references 主表名称(主列表名称) on update on delete cascade;

          2. 分类:

            级联更新:on update cascade

            级联删除:on delete cascade

五、 数据库的设计
5.1 多表之间的关系
  • 分类:

    1. 一对一(了解):

      • 如:人和身份证
      • 分析:一个人只有一个身份证,一个身份证只能对应一个人
      1. 一对多(多对一):
    • 如:部门和员工
    • 分析:一个部门有多个员工,一个员工只能对应一个部门
      3. 多对多:
    • 如:学生和课程
    • 分析:一个学生可以选择很多门课程,一个课程也可以被很多学生选择
  • 实现关系:

    1. 一对多(多对一):
      • 如:部门和员工
      • 实现方式:在多的一方建立外键,指向一的一方的主键。
    2. 多对多:
      • 如:学生和课程
      • 实现方式:多对多关系需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键。
    3. 一对一(了解):
      • 如:人和身份证
      • 实现方式:一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键。
5.2 数据库设计的范式
  • 概念:设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求。

    • 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式,数据库冗余越小。
    • 目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称为完美范式)。
  • 分类:

    • 第一范式(1NF):每一列都是不可分割的原子数据项

    • 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

      • 几个概念:

        1. 函数依赖:A–> B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A

          例如:学号–>姓名。(学号,课程名称)–>分数

        2. 完全函数依赖:A–>B,如果A是一个属性组,则B属性值的确认需要依赖于A属性组中所有的属性值。

          例如:(学号,课程名称)–>分数

        3. 部分函数依赖:A–>B,如果A是一个属性组,则B属性值的确认只需要依赖于A属性组中某一些值即可。

          例如:(学号,课程名称)–>姓名

        4. 传递函数依赖:A–>B,B–>C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性值)的值可以确定唯一C属性的值,则称C传递函数依赖以A

          例如:学号–>系名,系名–>系主任

        5. 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则这个属性(属性组)为该表的码。

          例如:该表中码为:(学号,课程名称)

          • 主属性:码属性组中的所有属性
          • 非主属性:除过马属性组的属性
    • 第三范式(3NF):在2NF基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)

5.3 数据库的备份与还原
  • 语法:
    • 备份:mysqldump -u用户名 -p密码 > 保存的路径
    • 还原:
      1. 登录数据库
      2. 创建数据库
      3. 使用数据库
      4. 执行文件。source文件路径
六、 多表查询:
6.1 查询语法:

select

	列名列表

	from

	表名列表

	where...
6.2 笛卡尔积:
  • 有两个集合A,B 取这两个集合的所有组成情况。
  • 要完成多表查询,需要消除无用的数据
6.3 多表查询的分类
  1. 内连接查询:

    • 隐式内连接:使用where条件消除无用数据

      例子:

      – 查询所有员工信息和对应的部门信息

      select * from emp,dept where emp.‘dept_id’ = dept.‘id’;

    • 显示内连接:

      语法:select 字段列表 from 表名1 [inner] join 表名2 on 条件

      select * from emp inner join dept on emp.‘dept_id’ = dept.‘id’;

      select * from emp join dept on emp.‘dept_id’ = dept.‘id’;

  2. 外连接查询:

    1. 左外连接:
      • 语法: select 字段列表 from 表1 left [outer] join 表2 on 条件;
      • 查询的是左表所有数据以及其交集部分。
    2. 右外连接:
      • 语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;
      • 查询的是右表所有数据以及其交集部分。
  3. 子查询:

    • 概念:查询中嵌套查询,称嵌套查询为子查询。

      – 查询工资最高的员工信息
      – 1. 查询最高的工资是多少? 9000
      select max(salary) from emp;

      – 2. 查询员工信息,并且工资等于9000的
      select * from emp where emp.salary = 9000;

      – 一条SQL就完成这个操作。子查询
      select * from emp where emp.salary = (select max(salary) from emp);

    • 子查询不同情况

      1. 子查询的结果是单行单列的:

        • 子查询可以作为条件,使用运算符去判断。运算符: > >= < <= =
        • – 查询员工工资小于平均工资的人
          select * from emp where emp.salary < (select avg(salary) from emp);
      2. 子查询的结果是多行单列的:

        • 子查询可以作为条件,使用运算符in来判断

        • – 查询‘财务部’和‘市场部’所有的员工信息
          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(SELECT id FROM dept WHERE NAME = ‘财务部’ OR NAME = ‘市场部’);

      3. 子查询的结果是多行多列的:

        • 子查询可以作为一张虚拟表参与查询

          – 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
          – 子查询
          SELECT * FROM dept t1,(SELECT * FROM emp WHERE emp.join_date > ‘2011-11-11’)
          t2 WHERE t1.id = t2.id;

          – 普通内连接
          SELECT * FROM emp t1,dept t2 WHERE t1.dept_id = t2.id AND t1.join_date > ‘2011-11-11’;

七、 事务
7.1. 事务的基本介绍:
  • 概念:

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

    1. 开启事务:start transaction;

    2. 回滚:rollback;

    3. 提交:commit;

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

      • 事务提交的两种方式:

        • 自动提交:

          • MySQL就是自动提交的
          • 一条DML(增删改)语句会自动提交一次事务。
        • 手动提交:

          • Oracle 数据库默认是手动提交事务
          • 需要先开启事务,再提交
        • 修改事务的默认提交方式:

          • 查看事务的默认提交方式:

            select @@autocommit; – 1 代表自动提交, 0 代表手动提交

          • 修改默认提交方式:set @@autocommit = 0;

7.2 事务的四大特征:
  1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
  2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
  3. 隔离性:多个事务之间,相互独立
  4. 一致性:当事务操作前后,数据总量不变
7.3 事务的隔离级别(了解)
  • 概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。

  • 存在问题:

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

    1. read uncommitted : 读未提交
      • 产生问题:脏读、不可重复读、幻读
    2. read committed: 读已提交(Oracle)
      • 产生的问题:不可重复读、幻读
    3. repeatable read : 可重复读(MySQL默认)
      • 产生的问题:幻读
    4. serializable : 串行化
      • 可以解决所有的问题
    • 注意: 隔离级别从小到大安全性越来越高,但是效率越来越低
    • 数据库查询隔离级别:
      • Select @@tx_isolation;
    • 数据库设置隔离级别:
      • set global transaction isolation leve 级别字符串;
八、 JDBC
8.1 JDBC的基本概念
  • 概念:Java databases connectivity Java 数据库连接,Java语言操作数据库
  • JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动 jar 包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动 jar 包中的实现类。
8.2 jdbc的分包、分层

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CthKIR9w-1573824169888)(C:\Users\Think-Pad\Desktop\JDBC的学习\jdbc的分层.jpg)]

分层、分包:(MVC三层架构)

View(视图层)

Control(控制层)

Model(模型层)

DB(数据库)

  • view层作用:视图层,即项目中的界面
  • controller层作用:控制层,获取界面上的数据,为界面设置数据;将要实现的功能交给业务层处理
  • service层作用:业务层,功能的实现,与controller控制层和数据访问层DAO交互,将对数据库的操作交给DAO数据访问层处理
  • dao层作用:数据访问层,用来操作数据库表的数据
  • db数据库:这里指MySQL
  • domain 实体包:存放 JavaBean
  • tools 工具包:存放项目中使用到的工具类
  • test 测试包:存放项目功能测试的代码
8.3 快速入门
  • 步骤:

    1. 导入驱动jar包,mysql-connector-java-8.0.13.jar
      1. 复制mysql-connector-java-8.0.13.jar到项目的libs目录下
      2. 右键 --> Add As Library
    2. 注册驱动
    3. 获取数据库连接对象 Connection
    4. 定义SQL
    5. 获取执行SQL语句的对象 Statement
    6. 执行SQL,接受返回结果
    7. 处理结果
    8. 释放资源
  • package cn.cehcloud;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.Statement;
    
    /*
        JDBC快速入门
     */
    public class JdbcDemo01 {
        public static void main(String[] args) throws Exception {
            //  1. 导入驱动jar包
            //  2. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //  3. 获取数据库连接对象
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
            //  4. 定义sql语句
            String sql = "update zlp set phone = '13838895935' where name = 'lisi'";
            //  5. 获取执行SQL的对象 Statement
            Statement stmt = conn.createStatement();
            //  6. 执行SQL
            long count = stmt.executeLargeUpdate(sql);
            //  7. 处理结果
            System.out.println(count);
            //  8. 释放资源
            stmt.close();
            conn.close();
        }
    }
    
8.4 详解各个对象
  1. DriverManager : 驱动管理对象

    • 功能:

      1. 注册驱动:告诉程序该使用哪一个数据库驱动jar

        static void registerDriver(Driver driver) : 注册与给定的驱动程序 DriverManager

        写代码使用:Class.forName(“com.mysql.jdbc.Driver”);

        通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块

        注意:MySQL5之后的驱动jar包可以省略注册驱动的步骤。

      2. 获取数据库连接:

      • 方法: static Connection getConnection(String url,String user, String password)
      • 参数:
        • url:指定连接的路径
          • 语法: jdbc:mysql://ip地址(域名):端口号/数据库名称
          • 例子:jdbc:mysql://localhost:3306/db3
          • 细节:如果连接的是本机MySQL服务器,并且MySQL服务器默认端口是3306,则url可以简写为: jdbc:mysql:///数据库名称
        • user:用户名
        • password:密码
    1. Connection : 数据库连接对象

      1. 功能:
      2. 获取执行SQL的对象
        • Statement createStatement()
        • PreparedStatement prepareStatement(String sql)
      3. 管理事务:
        • 开启事务:setAutocommit(boolean autoCommit) : 调用该方法设置参数为false,即开启事务
        • 提交事务: commit()
        • 回滚事务: rollback()
    2. Statement : 执行SQL的对象

      1. 执行SQL
        1. boolean execute(String sql) :可以执行任意的SQL 了解
          2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
      • 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功,返回值 >0 的则执行成功,反之,则失效。
        3. ResultSet executeQuery(String sql) : 执行DQL(select)语句
      1. ​ 案例:
      package cn.cehcloud.Jdbc;
      
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.SQLException;
      import java.sql.Statement;
      
      /*
          zlp表添加一条记录 insert 语句
       */
      public class JdbcDemo02 {
          public static void main(String[] args) {
              Statement stmt = null;
              Connection conn = null;
                  // 1.注册驱动
              try {
                  Class.forName("com.mysql.jdbc.Driver");
                  // 2.定义SQL
                  String sql = "insert into zlp values('wangwu','15090163395','2000-05-14')";
                  // 3.获取Connection 对象
                  conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
                  // 4.获取执行SQL的对象 Statement
                  stmt = conn.createStatement();
                  // 5.执行SQL
                  int count = stmt.executeUpdate(sql);// 影响的行数
                  // 6.处理结果
                  System.out.println(count);
                  if (count > 0){
                          System.out.println("添加成功!");
                  }
                  else{
                      System.out.println("添加成功!");
                  }
              }catch (ClassNotFoundException | SQLException e) {
                  e.printStackTrace();
              }finally {
                  // 7.释放资源
                  // 避免空指针异常
                  if (stmt != null){
                      try {
                          stmt.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                  }
      
                  if (conn != null){
                      try {
                          conn.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
      
    3. ResultSet : 结果集对象,封装查询结果

      1. next() : 游标向下移动一行
      • boolean next() : 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true

        • getXxx(参数):获取数据
      • Xxx :代表数据类型 如: int getInt() , String getSteing()

      • 参数:

        1. int :代表列的编号,从1开始 如:getString(1)
        2. String:代表列名称。如: getDouble(“name”)
        • 案例:
      package cn.cehcloud.Jdbc;
      
      import java.sql.*;
      
      public class JdbcDemo03 {
          public static void main(String[] args) {
              Statement stmt = null;
              Connection conn = null;
              ResultSet rs = null;
              try {
                  // 1.注册驱动
                  Class.forName("com.mysql.jdbc.Driver");
                  // 2.定义SQL
                  String sql = "select * from zlp";
                  // 3.获取Connection 对象
                  conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
                  // 4.获取执行SQL的对象 Statement
                  stmt = conn.createStatement();
                  // 5.执行SQL
                  rs = stmt.executeQuery(sql);
                  // 6.处理结果
                  // 6.1 让游标向下移动一行
                  rs.next();
                  rs.next();
                  rs.next();
                  // 6.2 获取数据
                  String name = rs.getString("name");
                  String phone = rs.getString("phone");
                  Date birthday = rs.getDate("birthday");
      
                  System.out.println(name + "-----" + phone + "-----" + birthday);
      
              }catch (ClassNotFoundException | SQLException e) {
                  e.printStackTrace();
              }finally {
                  // 7.释放资源
                  // 避免空指针异常
                  if (stmt != null){
                      try {
                          stmt.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                  }
      
                  if (conn != null){
                      try {
                          conn.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                  }
      
                  if (rs != null){
                      try {
                          rs.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
      
      
    • 注意:

      • 使用步骤:

        1. 游标向下移动一行
        2. 判断是否有数据
        3. 获取数据
    • // 循环判断游标是否是最后一行
      while(rs.next()){
          // 6.2 获取数据
          String name = rs.getString("name");
          String phone = rs.getString("phone");
          Date birthday = rs.getDate("birthday");
      
          System.out.println(name + "-----" + phone + "-----" + birthday);
      
      }
      

      练习:

      package cn.cehcloud.Jdbc;
      
      import java.util.Date;
      
      /*
          封装Zlp表数据的JavaBean
       */
      public class Zlp {
          private String name;
          private String phone;
          private Date birthday;
      
          public String getName(String name) {
              return this.name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public String getPhone() {
              return phone;
          }
      
          public void setPhone(String phone) {
              this.phone = phone;
          }
      
          public Date getBirthday() {
              return birthday;
          }
      
          public void setBirthday(Date birthday) {
              this.birthday = birthday;
          }
      
          @Override
          public String toString() {
              return "Zlp{" +
                      "name='" + name + '\'' +
                      ", phone='" + phone + '\'' +
                      ", birthday=" + birthday +
                      '}';
          }
      }
      
    package cn.cehcloud.Jdbc;
    
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.List;
    
    /*
        定义一个方法,查询Zlp表的数据将其封装为对象,然后装载集合,返回。
     */
    public class JdbcDemo04 {
        public static void main(String[] args) {
            List<Zlp> list = new JdbcDemo04().findAll();
            /*for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }*/
            System.out.println(list);
        }
    
        /*
            查询所有Zlp对象
         */
    
        public List<Zlp> findAll(){
            Statement stmt = null;
            ResultSet rs = null;
            Connection conn = null;
            List<Zlp> list = null;
    
            try {
                // 1.注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 2.获取连接
                conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
                // 3.定义SQL
                String sql = "select * from zlp";
                // 4.获取执行SQL的对象
                stmt = conn.createStatement();
                // 5.执行SQL
                rs = stmt.executeQuery(sql);
                // 6.遍历结果,封装对象,装载集合
                Zlp zlp = null;
                list = new ArrayList<Zlp>();
    
                while(rs.next()){
                    // 获取数据
                    String name = rs.getString("name");
                    String phone = rs.getString("phone");
                    Date birthday = rs.getDate("birthday");
    
                    zlp = new Zlp();
                    zlp.setName(name);
                    zlp.setPhone(phone);
                    zlp.setBirthday(birthday);
    
                    // 装载集合
                    list.add(zlp);
                }
            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
            }finally {
                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();
                    }
                    }
                }
            }
    
            return list;
        }
    }
    

    5.PreparedStatement : 执行SQL的对象

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

      1. 输入用户随便,输入密码:a’ or ‘a’ = 'a

      2. sql : select * from user where username = ‘hgsi’ and password = ‘a’ or ‘a’ = ‘a’

      3. 解决SQL注入问题:使用preparedStatement对象来解决

      4. 预编译的SQL:参数使用?作为站位符

      5. 步骤:

      6. 导入驱动jar包 mysql-connector-java-8.0.13.jar
        2. 注册驱动
        3. 获取数据库连接对象 Connection
        4. 定义SQL

      • 注意:SQL的参数使用?作为占位符。如:Select * from user where username = ? and password = ?;
      1. 获取执行SQL语句的对象 preparedStatement Connection.prepareStament(String sql)
        6. 给?赋值
      • 方法:setXxx(参数1,参数2)
        • 参数1 :?的位置编号 从1开始
        • 参数2 :?的值
      1. 执行SQL,接受返回结果,不需要传递SQL语句
      2. 处理结果
      3. 释放资源
      4. 注意:后期会使用PreparedStatement来完成增删改查的所有操作。
      5. 可以防止SQL注入
      6. 效率更高
    • package cn.cehcloud.Jdbc;
      
      import Utils.JdbcUtils;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.util.Scanner;
      
      /*
          登录方法
          需求:
              1. 通过键盘录入用户名和密码
              2. 判断用户是否登录成功
       */
      public class JdbcDemo05 {
          public static void main(String[] args) {
              // 1.键盘录入,接受用户名和密码
              Scanner sc = new Scanner(System.in);
              System.out.println("请输入用户名:");
              String username = sc.next();
              System.out.println("请输入密码:");
              String password = sc.next();
              // 2.调用方法
              boolean flag = new JdbcDemo05().login2(username, password);
              // 3.判断结果,输出不同语句
              if (flag){
                  // 登录成功
                  System.out.println("登录成功!");
              }else {
                  System.out.println("用户名或密码错误!");
              }
          }
      
          public boolean login2(String username,String password){
              if (username == null || password == null){
                  return false;
              }
              // 连接数据库判断是否登录成功
              Connection conn = null;
              ResultSet rs =null;
              PreparedStatement pstmt =null;
              // 1.获取连接
              try {
                  conn = JdbcUtils.getConnection();
                  // 2.定义SQL
                  String sql = "select * from user where username = ? and password = ?";
                  // 3.获取执行SQL的对象
                  pstmt = conn.prepareStatement(sql);
                  // 给?赋值
                  pstmt.setString(1,username);
                  pstmt.setString(2,password);
                  // 4.执行查询,不需要传递SQL
                  rs = pstmt.executeQuery();
                  // 5.判断
                  return rs.next(); // 如果有下一行,则返回true
      
              } catch (Exception e) {
                  e.printStackTrace();
              }finally {
                  JdbcUtils.close(rs,pstmt,conn);
              }
              return false;
          }
      }
      
      
8.5 抽取JDBC工具类 :JDBCUtils
  • 目的:简化书写

  • 分析:

    1. 注册驱动也抽取

    2. 抽取一个方法获取连接对象

      • 需求:不想传递参数(麻烦),还得保证工具类的通用性。

      • 解决:配置文件

        ​ jdbc.properties

        ​ url =

        ​ user =

        ​ password =

        • url = jdbc:mysql://localhost:3306/test?characterEncoding = utf8 & useSSL = false & serverTimezone = UTC & rewriteBatchedStatements = true
          user = root
          password = 123456
          driver = com.mysql.jdbc.Driver
          
          
    package Utils;
    
    import com.mysql.cj.protocol.Resultset;
    
    import javax.xml.transform.Result;
    import java.io.FileReader;
    import java.io.IOException;
    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 {
            // 1.创建Properties集合类
            Properties pro = new Properties();
            // 获取src路径下的文件的方式--> ClassLoader 类加载器
            ClassLoader classLoader = JdbcUtils.class.getClassLoader();
            URL res = classLoader.getResource("jdbc.zlp.properties");
            String path = res.getPath();
            System.out.println(path);
            // 2.加载文件
            try {
                pro.load(new FileReader(path));
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 3.获取数据,赋值
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            // 4.注册驱动
            try {
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
        /*
            获取连接
         */
        public static Connection getConnection() throws Exception {
            return DriverManager.getConnection(url, user, password);
        }
    
        /*
            释放资源
         */
        public static void close(ResultSet rs, 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();
                    }
                }
            }
        }
    }
    
  • package cn.cehcloud.Jdbc;
    
    import Utils.JdbcUtils;
    import com.mysql.cj.protocol.Resultset;
    
    import javax.xml.transform.Result;
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.List;
    
    /*
        演示JDBC工具类
     */
    public class JdbcDemo04 {
        public static void main(String[] args) {
            List<Zlp> list = new JdbcDemo04().findAll2();
            /*for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }*/
            System.out.println(list);
        }
    
        /*
            查询所有Zlp对象
         */
    
        public List<Zlp> findAll2(){
            Statement stmt = null;
            ResultSet rs = null;
            Connection conn = null;
            List<Zlp> list = null;
    
            try {
    //            // 1.注册驱动
    //            Class.forName("com.mysql.jdbc.Driver");
    //            // 2.获取连接
    //            conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
                conn = JdbcUtils.getConnection();
                // 3.定义SQL
                String sql = "select * from zlp";
                // 4.获取执行SQL的对象
                stmt = conn.createStatement();
                // 5.执行SQL
                rs = stmt.executeQuery(sql);
                // 6.遍历结果,封装对象,装载集合
                Zlp zlp = null;
                list = new ArrayList<Zlp>();
    
                while(rs.next()){
                    // 获取数据
                    String name = rs.getString("name");
                    String phone = rs.getString("phone");
                    Date birthday = rs.getDate("birthday");
    
                    zlp = new Zlp();
                    zlp.setName(name);
                    zlp.setPhone(phone);
                    zlp.setBirthday(birthday);
    
                    // 装载集合
                    list.add(zlp);
                }
            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } /*finally {
                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();
                    }
                    }
                }
            }*/
            JdbcUtils.close(rs,stmt,conn);
            return list;
        }
    }
    
  • 练习:

    • 需求:
          1. 通过键盘录入用户名和密码
          2. 判断用户是否登录成功
          * select * from user where username = '" + username + "'and password = '"+ password+"';
          * 如果这个是SQL有查询结果,则成功,反之,则失败
      
  • 步骤:

    1. 创建数据库表 user

      create table user(id int primary key auto_increment,username varchar(32),password varchar(32));

      insert into user values(null,‘zhangsan’,‘123’);

      insert into user values(null,‘lisi’,‘456’);

url = jdbc:mysql:///test
user = root
password = 123456
driver = com.mysql.jdbc.Driver

package cn.cehcloud.Jdbc;

import Utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

/*
    登录方法
    需求:
        1. 通过键盘录入用户名和密码
        2. 判断用户是否登录成功
 */
public class JdbcDemo05 {
    public static void main(String[] args) {
        // 1.键盘录入,接受用户名和密码
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = sc.next();
        System.out.println("请输入密码:");
        String password = sc.next();
        // 2.调用方法
        boolean flag = new JdbcDemo05().login(username, password);
        // 3.判断结果,输出不同语句
        if (flag){
            // 登录成功
            System.out.println("登录成功!");
        }else {
            System.out.println("用户名或密码错误!");
        }
    }

    public boolean login(String username,String password){
        if (username == null || password == null){
            return false;
        }
        // 连接数据库判断是否登录成功
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs =null;
        // 1.获取连接
        try {
            conn = JdbcUtils.getConnection();
            // 2.定义SQL
            String sql = "select * from user where username = '" + username + "'and password = '"+ password+"'";
            // 3.获取执行SQL的对象
            stmt = conn.createStatement();
            // 4.执行查询
            rs = stmt.executeQuery(sql);
            // 5.判断
            return rs.next(); // 如果有下一行,则返回true
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(rs,stmt,conn);
        }
        return false;
    }
}

8.6 JDBC控制事务
  1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
  2. 操作:
    1. 开启事务
      2. 提交事务
      3. 回滚事务
    2. 使用Connection对象来管理事务
* 开启事务:setAutoCommit(boolean autoCommit) : 调用该方法设置参数为false,即开启事务
  * 在执行SQL之前开启事务
* 提交事务:commit()
  * 当所有SQL都执行完提交事务
* 回滚事务:rollback()
  * 在catch中回滚事务

8.7 数据库连接池
  1. 概念:其实就是一个容器(集合),存放数据库连接的容器。

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

  2. 好处:

    1. 节约资源
    2. 用户访问高效
  3. 实现:

    1. 标准接口:DataSource javax.sql包下的
      1. 方法:
        • 获取连接:getConnection()
        • 归还连接:Connection.close() 如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
    2. 一般我们不去实现它,有数据库厂商来实现
      1. C3P0 : 数据库连接池技术
      2. Druid : 数据库连接池实现技术,由阿里巴巴提供的
  4. 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
  1. c3p0配置的演示

    <?xml version="1.0" encoding="utf-8"?>
    <c3p0-config>
    <!--  使用默认的配置读取连接池对象  -->
      <default-config>
    <!--    连接参数  -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?characterEncoding = utf8&amp;useSSL = false&amp;serverTimezone = UTC&amp;rewriteBatchedStatements = true</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>
    
      <named-config name="otherc3p0"> 
      </named-config>
    </c3p0-config>
    
    
    package cn.cehcloud.Jdbc;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    
    /*
        c3p0的演示
     */
    public class C3P0Demo01 {
        public static void main(String[] args) throws Exception {
            // 1.创建数据库连接池对象,获取DataSource,使用默认配置
            DataSource ds = new ComboPooledDataSource();
                    for (int i = 0; i < 11; i++) {
                        // 2.获取连接
                        Connection conn = ds.getConnection();
                        // 3.打印
                        System.out.println(i + ":" + conn);
                        if (i == 5){
                            conn.close();
                        }
            }
        }
    }
    
    
  2. Druid :数据库连接池实现技术,由阿里巴巴提供的

    • 步骤:

      1. 导入jar包 druid-1.0.9.jar

      2. 定义配置文件:

        • 是properties 形式的
        • 可以叫任意名称,可以放在任意目录下
      3. 获取数据库连接池对象:通过工厂来获取 DruidDataSourceFactory

      4. 获取连接 : getConnection

        driverClassName=com.mysql.cj.jdbc.Driver
        url=jdbc:mysql://localhost:3306/test?characterEncoding = utf8 & useSSL = false & serverTimezone = UTC & rewriteBatchedStatements = true
        username=root
        password=123456
        # 初始化连接数量
        initialSize=5
        # 最大连接数
        maxActive=10
        # 最长等待时间
        maxWait=3000
        maxIdle=8
        minIdle=3
        
        
        package cn.cehcloud.Jdbc;
        
        import com.alibaba.druid.pool.DruidDataSourceFactory;
        
        import javax.sql.DataSource;
        import java.io.IOException;
        import java.io.InputStream;
        import java.sql.Connection;
        import java.util.Properties;
        
        /*
            Druid演示
         */
        public class DruidDemo01 {
            public static void main(String[] args) throws Exception {
                // 1.导入jar包
                // 2.定义配置文件
                // 3.加载配置文件
                Properties pro = new Properties();
                InputStream is = DruidDemo01.class.getClassLoader().getResourceAsStream("druid.properties");
                pro.load(is);
                // 4.获取连接池对象
                DataSource ds = DruidDataSourceFactory.createDataSource(pro);
                // 5.获取连接
                Connection conn = ds.getConnection();
                System.out.println(conn);
            }
        }
        
        
  • 定义工具类:

    1. 定义一个类 JDBCUtils
    2. 提供静态代码块加载配置文件,初始化连接池对象
    3. 提供方法:
      1. 获取连接方法: 通过数据库连接池获取连接
      2. 释放资源
      3. 获取连接池的方法
  • package Utils;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    /*
        Druid连接池的工具类
     */
    public class JDBCUtil {
        // 1.定义成员变量  DataSource
        private static DataSource ds;
    
        static {
            try {
                // 1.加载配置文件
                Properties pro = new Properties();
                pro.load(JDBCUtil.class.getClassLoader().getResourceAsStream("druid.properties"));
                // 2.获取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();
                }
            }*/
            close(null,stmt,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();
                }
            }
        }
    
        /*
            获取连接池的方法
         */
        public static DataSource getDatabaSource(){
            return ds;
        }
    }
    
    
    package cn.cehcloud.Jdbc;
    
    import Utils.JDBCUtil;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    /*
        使用新的工具类
     */
    public class DruidDemo02 {
        public static void main(String[] args) {
            /*
                完成添加操作,给stu表添加一条记录
             */
            Connection conn = null;
            PreparedStatement pstmt = null;
            try {
                // 1.获取连接
                conn = JDBCUtil.getConnection();
                // 2.定义SQL
                String sql = "insert into stu values(null,?,?)";
                // 3.获取pstmt对象
                pstmt = conn.prepareStatement(sql);
                // 4.给?赋值
                pstmt.setString(1,"刘七");
                pstmt.setString(2,"2000-01-01 00:00:00");
                // 5.执行SQL
                int i = pstmt.executeUpdate();
                System.out.println(i);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 6.释放资源
                JDBCUtil.close(pstmt,conn);
            }
        }
    }
    
    
8.8 Spring JDBC
  • Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发

  • 步骤:

    1. 导入jar包
    2. 创建JDBCTemplate对象,依赖于数据源DataSource
      • JdbcTemple temple = new JdbcTemple(ds);
    3. 调用JDBCTemplate的方法来完成CRUD的操作
      • update() : 执行DML语句。增、删、改语句
      • queryForMap() : 查询结果将结果封装为Map集合,将列名作为key,将值作为values 将这条记录封装为一个map集合
        • 注意: 这个方法查询的结果集长度只能是1
      • queryForList() : 查询结果,将结果封装为 list集合
        • 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
      • query() : 查询结果,将结果封装为 JavaBean对象
        • query的参数:RowMapper
          • 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到 JavaBean 的自动封装
          • new BeanPropertyRowMapper<类型>(类型.class)
      • queryForObject : 查询结果,将结果封装为对象
        • 一般用于聚合函数的查询
  • package cn.cehcloud.Jdbc;
    
    
    import Utils.JDBCUtil;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    /*
        JdbcTemplate入门
     */
    public class JdbcTemplateDemo01 {
        public static void main(String[] args) {
            // 1.导入jar包
            // 2.创建JDBCTemplate对象
            JdbcTemplate template = new JdbcTemplate(JDBCUtil.getDatabaSource());
            // 3.调用方法
            String sql = "update stu set name = ? where id = ?";
            int count = template.update(sql,"王一" ,3);
            System.out.println(count);
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值