JDBC
1. JDBC的概述
JDBC: Java DataBase Connectity(Java数据库连接),是一种专门用于执行SQL语句的Java API,可以为多种关系数据库提供统一的访问,它由一组用Java语言编写的接口组成。
2. JDBC的理解
JDBC规范定义接口,具体的实现由各大数据库厂商来实现,JDBC是Java访问数据库的标准规范。真正怎么操作数据库还需要具体的实现类,也就是数据库驱动(第三方JAR包)。每个数据库厂商根据自家数据库方式编写好自己数据库的驱动。所以我们只需要会调用JDBC接口中的方法即可。数据库驱动由数据库厂商提供。
我们在用java代码操作数据库时只需要会使用JDBC接口中的方法即可,使用简单。
3. JDBC的API解析
DriverManager:类
1 加载驱动 (用反射代替了)
2 获取数据库连接的对象
方法作用:
① 加载驱动
static void registerDriver(Driver driver) 实际开发中不会选择 ,因为加载了2次驱动。
Class.forName(Driver的全限定名) 反射方式,加载一次驱动 ,适用开发。
② 获取数据库连接的对象
static Connection getConnection(String url, String user, String password);
Url:数据库的地址 固定格式:jdbc:要连的数据库://数据库地址:端口号/哪个数据库
user:数据库的用户名
Password:数据库的密码
如果数据出现乱码需要加上参数: ?characterEncoding=utf8,表示让数据库以UTF-8编码来处理数据。 如:
jdbc:要连的数据库://数据库地址:端口号/哪个数据库?characterEncoding=utf8
Connection:接口
1 可以获取执行SQL语句的对象(语句执行者)
2 可以做事务
方法作用:
① 可以获取执行SQL语句的对象(语句执行者)
Statement createStatement();获取语句的执行者
② 操作事务
void setAutoCommit(boolean autoCommit) ; --start transaction;
false:开启事务, ture:关闭事务(默认)
void commit(); —commit;
提交事务
void rollback(); —rollback;
回滚事务
Statement:接口
执行sql语句
方法作用:
① 执行sql语句
executeUpdate() 执行的是增删改语句
返回值是int类型 代表受影响的行数
executeQuery() 执行的是查询语句
返回的值是ResultSet类型对象 称为:结果集对象
Resultset:接口
方法作用:
1 封装查询语句的结果集,我们不能一次性取出所有的数据,需要一行一行的取出。
next() 可以让指针向下移动一行,默认在第一行之前,返回值是boolean
true:代表有数据 false: 代表没数据
2 获取结果集中每一行的数据
get类型(int 列的位置)
get类型(String 列名)
4. JDBC操作事务
Connection:
void setAutoCommit(boolean autoCommit) ;
false:开启事务 ture:关闭事务(默认的)
void commit();
提交事务
void rollback();
回滚事务
ps:在使用手动事务时,必须要抓取异常,在catch块中进行回滚事务,
只要有事务,就必须try catch捕捉处理,查询有没有事务都行。
try{
1. 代码第一行开启事务 connection.setAutocommit( false )
2. 代码最后一行提交事务 connection.commit()
}catch(Exception e ){
3. 发生异常回滚事务 connection.rollback()
5. PreparedStatement 预编译对象
PreparedStatement 是 Statement的子接口,也是用来执行sql语句的。
我们写的SQL语句让数据库执行,数据库不是直接执行SQL语句字符串。和Java一样,数据库需要执行编译后的SQL语句(类似Java编译后的字节码文件)。preparedStatement预编译对象是先将sql格式传递给数据库做预编译。
6. PreparedStatement预编译对象的语法格式
Statement编译对象: select * from 表 where 字段1=值1 and 字段2=值2;
preparedStatement预编译对象:select * from 表 where name=? and password=?;
7. Statement和PreparedStatement的区别
Statement编译对象是有什么样的sql就执行什么样的sql语句,每次执行任何一条sql语句都得让数据库去编译执行,如果执行一万条同样的查询语句,数据库要编译一万次,效率低。
preparedStatement预编译对象是先将sql格式传递给数据库做预编译 ,可以多次传入不同的参数给 PreparedStatement 对象并执行,相当于调用方法多次传入不同的参数,执行一万条同样的查询语句 数据库只编译一次,根据不同的参数做不同的执行。
8. PreparedStatement预编译的好处
① 只需要编译一次,效率高
② 能让数据库提前知晓要执行的sql语句格式,只负责给数据库传参即可,没有SQL注入的隐患,安全性更高
9. preparedStatement对象操作数据库的增删改查
① 编写sql
String sql = "insert into user values(null,?,?..) ";
② 创建预编译对象–提前编译sql语句
PreparedStatement pst = conn.preparedStatement(sql);
③ 设置具体的参数
pst.set字段类型(int a,值);
a: 第几个 ? (占位符) 默认从左向右第1个开始
④ 执行sql即可
ResultSet rs = pst.executeQuery(); // 执行查询,返回 resultSet
int i = pst.executeUpdate(); // 执行 增 删 改,返回的是影响的行数
连接池
1. 连接池的概述
连接池:存放数据库连接的容器(集合)
2. 连接池出现的目的
之前在使用jdbc操作数据库数据的时候,有一个步骤是获取连接(创建连接)
连接用完,还需要释放连接(销毁连接),这2个步骤太消耗资源了
创建连接=0.1
销毁连接=0.1
10000000*0.2=2000000
连接池就可以帮助我们解决创建连接和销毁连接带来的资源消耗问题
连接池就是用来优化jdbc的2个步骤的
① 优化的是jdbc的创建连接部分
② 优化的是jdbc的销毁连接部分
3. 连接池的使用
前提:导入Druid连接池的jar包
@Test
public void test() throws Exception {
// 创建一个配置文件对象
Properties properties = new Properties();
// 获取文件流 DruidTest.class.getResourceAsStream获取的是classess文件的路径 返回流
InputStream is = DruidTest.class.getResourceAsStream("/druid.properties");
// 配置文件对象加载配置文件
properties.load(is);
// 创建druid的连接
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
// 获取连接
Connection connection = ds.getConnection();
String sql="select * from user";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String password = resultSet.getString("password");
System.out.println(id+":"+name+":"+password);
}
// 归还连接
JDBCUtils.close(resultSet,preparedStatement,connection);
}
4. 连接池优化原理
在连接池一初始化的时候,就在容器中创建一定量的连接
当用户要连数据库的时候,就从容器中拿一个连接使用
使用完毕之后,不再是销毁,而是把使用后的连接还放回容器,供下一个用户去循环使用