目录
JDBC概述
1.概念
独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口,定义了用来访问数据库的标准Java类库,使用这些类库可以以一种标准的方法、方便地访问数据库资源。
2.Java中的数据存储技术
- 数据库存取技术
- JDBC直接访问数据库
- 主要功能
- 建立与数据库或者其他数据源的链接
- 向数据库发送SQL命令
- 处理数据库的返回结果
- 主要功能
- JDO (Java Data Object )技术
- 第三方O/R工具
- Hibernate
- Mybatis
- JDBC直接访问数据库
3.数据的持久化
把数据保存到可掉电式存储设备中以供之后使用
4.JDBC体系结构
- 面向应用的API
- Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。
- 面向数据库的API
- Java Driver API,供开发商开发数据库驱动程序用。
- JDBC是sun公司提供一套用于数据库操作的接口,java程序员只需要面向这套接口编程即可。
- 不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。
获取数据库连接
- Driver接口介绍
- java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现。
- Oracle的驱动
- oracle.jdbc.driver.OracleDriver
- mySql的驱动
- com.mysql.jdbc.Driver
- 加载与注册JDBC驱动
- 加载驱动
- 加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名
- Class.forName(“com.mysql.jdbc.Driver”);
- 注册驱动
- DriverManager 类是驱动程序管理器类,负责管理驱动程序
- 使用DriverManager.registerDriver(com.mysql.jdbc.Driver)来注册驱动
- 加载驱动
- 要素二:URL
- JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
- JDBC URL的标准由三部分组成
- jdbc:子协议:子名称
- 协议
- JDBC URL中的协议总是jdbc
- 子协议
- 子协议用于标识一个数据库驱动程序
- 子名称
- 一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息。
- jdbc:mysql://localhost:3306/homework ?serverTimezone=UTC
- 协议
- jdbc:子协议:子名称
- 数据库连接方式最优版本
- 将文件声明在一个jdbc.properties下,而后用io流的方式读取信息,而后加载驱动并获取连接
- 使用配置文件的好处
- 实现了代码和数据的分离,如果需要修改配置信息,直接在配置文件中修改,不需要深入代码
- 如果修改了配置信息,省去重新编译的过程。
使用PreparedStatement实现CRUD操作
- 操作和访问数据库
- 使用Statement操作数据表的弊端
- 通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返回执行结果。
- 弊端
- 存在SQL注入问题
- 存在拼串操作,繁琐
- PreparedStatement的使用
- PreparedStatement介绍
- 可以通过调用 Connection 对象的preparedStatement(String sql)方法获取 PreparedStatement 对象
- PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句
- PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值
- 优点
- PreparedStatement 能最大可能提高性能
- PreparedStatement 可以防止 SQL 注入
- Java与SQL对应数据类型转换表
- ResultSet与ResultSetMetaData
- ResultSet
- 查询需要调用PreparedStatement 的 executeQuery() 方法,查询结果是一个ResultSet 对象
- ResultSetMetaData
- ResultSetMetaData meta = rs.getMetaData();
- getColumnName(int column):获取指定列的名称
- getColumnLabel(int column):获取指定列的别名
- getColumnCount():返回当前 ResultSet 对象中的列数。
- getColumnTypeName(int column):检索指定列的数据库特定的类型名称。
- getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。
- isNullable(int column):指示指定列中的值是否可以为 null。
- isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。
- getColumnName(int column):获取指定列的名称
- ResultSetMetaData meta = rs.getMetaData();
- ResultSet
操作BLOB类型字段
MySQL BLOB类型
MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接写的。
批量插入
- 批量执行SQL语句
- addBatch(String):添加需要批量处理的SQL语句或是参数;
- executeBatch():执行批量处理语句;
- clearBatch():清空缓存的数据
- 隔离级别
- 查看当前的隔离级别
- SELECT @@tx_isolation;
- 设置当前 mySQL 连接的隔离级别
- set transaction isolation level read committed;
- 设置数据库系统的全局的隔离级别
- set global transaction isolation level read committed;
- 创建mysql数据库用户
- create user tom identified by 'abc123';
- create user tom identified by 'abc123';
- 授予权限
- 授予通过网络方式登录的tom用户,对所有库所有表的全部权限,密码设为abc123.
- grant all privileges on *.* to tom@'%' identified by 'abc123';
- grant all privileges on *.* to tom@'%' identified by 'abc123';
- 给tom用户使用本地命令行方式,授予atguigudb这个库下的所有表的插删改查的权限。
- grant select,insert,delete,update on atguigudb.* to tom@localhost identified by 'abc123';
- 授予通过网络方式登录的tom用户,对所有库所有表的全部权限,密码设为abc123.
- 查看当前的隔离级别
DAO及相关实现类
概念
Data Access Object访问数据信息的类和接口,包括了对数据的CRUD(Create、Retrival、Update、Delete),而不包含任何业务相关的信息。有时也称作:BaseDAO
作用
为了实现功能的模块化,更有利于代码的维护和升级。
数据库连接池
- JDBC数据库连接池的必要性
- 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤
- 在主程序(如servlet、beans)中建立数据库连接
- 进行sql操作
- 断开数据库连接
- 劣势
- 对于每一次数据库连接,使用完后都得断开
- 这种开发不能控制被创建的连接对象数
- 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤
- 数据库连接池技术
- 数据库连接池的基本思想
- 就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。
- 数据库连接池
- 负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
- 数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
- 优点
- 资源重用
- 由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性。
- 更快的系统反应速度
- 数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间
- 新的资源分配手段
- 对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源
- 统一的连接管理,避免数据库连接泄漏
- 在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露
- 资源重用
- DBCP数据库连接池
- 数据库连接池的基本思想
多种开源的数据库连接池
- DBCP是Apache提供的数据库连接池。tomcat 服务器自带dbcp数据库连接池。速度相对c3p0较快,但因自身存在BUG,Hibernate3已不再提供支持。
- C3P0 是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以。hibernate官方推荐使用
- Proxool是sourceforge下的一个开源项目数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点
- BoneCP 是一个开源组织提供的数据库连接池,速度快
- Druid是阿里提供的数据库连接池,据说是集DBCP 、C3P0 、Proxool 优点于一身的数据库连接池,但是速度不确定是否有BoneCP快
- DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把 DataSource 称为连接池
- DataSource用来取代DriverManager来获取Connection,获取速度快,同时可以大幅度提高数据库访问速度。
- 特别注意
- 数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。
- 当数据库访问结束后,程序还是像以前一样关闭数据库连接:conn.close(); 但conn.close()并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。
Druid(德鲁伊)数据库连接池
ResultSetHandler接口及实现类
- ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)
- 接口的主要实现类:
- ArrayHandler:把结果集中的第一行数据转成对象数组。
- ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
- BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
- ColumnListHandler:将结果集中某一列的数据存放到List中。
- KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
- MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
- MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
- ScalarHandler:查询单个值对象