JDBC:Java DataBase Connectivity,是SUN公司推出的操作数据库的规范
JDBC和数据库驱动:规范和实现的关系
JDBC:JDK中,java.sql.* javax.sql.*
驱动:去数据库厂商的网站下载
JDBC的开发步骤
0、搭建开发环境:把数据库驱动的jar包加入到构建路径中
1、注册驱动
2、获取与数据库的链接
3、创建代表SQL语句的对象
4、执行SQL语句
5、如果是查询语句:返回结果集。
6、释放资源
JDBC规范中常用的接口或类
1.DriverManager
作用:
a、注册驱动
方式一:DriverManager.registerDriver(newcom.mysql.jdbc.Driver());
缺点:
1、严重依赖具体的数据库驱动
2、导致数据驱动注册2遍
方式二:(推荐)
Class.forName("com.mysql.jdbc.Driver");
b、获取与数据库的链接
Connection conn =
DriverManager.getConnection("jdbc:mysql://localhost:3306/day15",
"root","sorry");
String url:JDBC与数据库厂商的协议。具体参考数据库的文档。
Oracle:jdbc:oracle:thin:@localhost:1521:orcl瘦客户端链接方式
jdbc:oracle:client:@localhost:1521:orcl 客户端链接方式,高效
2.Connection作用:所有与数据库的交互都是基于链接的。
StatementcreateStatement():创建代表SQL语句的对象
3.Statement作用:代表SQL语句对象
常用方法:
l ResultSetexecuteQuery(String sql):执行查询,返回结果集。
l int executeUpdate(String sql):执行DML语句。返回的是SQL语句影响到的记录条数。
l boolean execute(String sql):执行任何的SQL语句。返回值不代表成功与否。如果执行的语句有结果集,返回true,否则返回false。
4.ResultSet
作用:封装了结果集。
数据库类型和Java类型的对应关系:
常用的方法:
boolean next():向下移动。返回有没有记录
boolean provious():向上移动。返回有没有记录
boolean absolute(int row):定位。返回有没有记录。看第2条,写2.
void beforeFirst():移动到第一条记录的前面。默认位置
void afterLast():移动到最后一条记录的后面。
5.释放资源
PreparedStatement接口
原则:能用PreparedStatement就不要使用Statement
优点:
参数使用占位符(?)替代
预编SQL语句,执行效率高
不存在SQL注入问题
大结果集的分页编码
1.数据的支持:MySQL
LIMIT M,N;
M:开始记录的索引。第一条记录的索引是0
N:每次查询出的记录条数
一次取10条:
第一页:SELECT *FROM customers LIMIT 0,10;
第二页:SELECT *FROM customers LIMIT 10,10;
第n页:SELECT * FROM customers LIMIT(n-1)*10,10;
总页数:
总页数=总记录条数%10==0?总记录条数/10:总记录条数/10+1;
2.设计Page类,封装所有与分页有关的信息
批处理
一次性向数据库发送多条SQL语句。降低了与数据库的交互次序,提升数据库层执行效率。
LOB(CLOB、BLOB)的存取
1、LOB:Large Object。
CLOB:character Large Object。大文本。
BLOB:Binary Large Object。图片、视频、声音等。
2、MySQL支持的LOB的类型。可变长度类型。
TINYBLOB, TINYTEXT 256B
BLOB, TEXT 64K
MEDIUMBLOB, MEDIUMTEXT16M
LONGBLOB, LONGTEXT 4G
事务
1.数据库的事务控制
start transaction:开启事务
rollback:回滚事务
commit:提交事务
2.事务的特性
原子性:指处于同一事务中的多条语句是不可分割的
一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。比如,转账,转账前两个账户余额之和为2k,转账之后也应该是2K
隔离性:指多线程环境下,一个线程中的事务不能被其他线程中的事务打扰
持久性:事务一旦提交,就应该被永久保存起来
3.事物的隔离性
脏读:指一个线程中的事务读取到了另外一个线程中未提交的数据
不可重复读:指一个线程中的事务读取到了另外一个线程中提交的update的数据。
虚读:指一个线程中的事务读取到了另外一个线程中提交的insert的数据
隔离级别:
1:READ UNCOMMITTED:脏读、不可重复读、虚读都有可能发生。
2:READ COMMITTED:防止脏读的发生,不可重复读、虚读都有可能发生
4:REPEATABLE READ:防止脏读、不可重复读的发生,虚读有可能发生
8:SERIALIZABLE:防止脏读、不可重复读、虚读的发生
级别越高,数据越安全,但性能越低
MySQL:
查看当前事务的隔离级别:SELECT @@tx_isolation;
更改事务的隔离级别:(注意:一定要在开启事务之前设定)
SET transaction isolation level 四个级别之一(单词);
JDBC中如何控制事务的隔离级别:
前提:在开启事务之前设置隔离级别。
设置事务的隔离级别:
Connection void setTransactionIsolation(int level);
数据库连接池
提高获取链接的效率
实现javax.sql.DataSource
难点:从池中获取一个链接后,用户用完调用conn.close()方法。应该达到不关闭,返还池中的效果。
解决方案:
继承:public class MyConnection extends com.mysql.jdbc.Connection{}写驱动
装饰(包装)设计模式:
1、编写一个类,实现与被装饰类相同的接口。目的使他们有相同的行为
2、定义一个实例变量,引用被装饰对象。目的和原来的老对象进行交接
3、定义构造方法,把被装饰对象注入进来。
4、对于不需要改写的方法,调用被装饰对象的。
5、对于要改写的方法,改写即可。
默认适配器代理模式(AOP编程技术实现):动态代理
基于接口的动态代理:
前提:被代理对象的类,实现了至少一个接口
基于子类的动态代理:
借助第三方:CGLIB
DBCP的使用
1.apache的开源组件,导入jar包。commons-dbcp.jar commons-pool.jar
2.添加配置文件,dbcpconfig.properties
3.编写工具类
public class DBCPUtil {
private static DataSource dataSource;
static{
try {
InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties props = new Properties();
props.load(in);
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource(){
return dataSource;
}
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException("获取数据库连接失败");
}
}
}
C3P0
1.开源的数据源。 c3p0-0.9.1.2.jar
2.编写配置文件
3.工具类
开源JDBC工具使用:DBUtils
apache推出的对JDBC编码进行了简单封装的一个框架
核心类:QueryRunner
结果处理器的使用:
ResultSetHandler的各个实现类:
ArrayHandler:把结果集中的第一行数据转成对象数组。
ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
ColumnListHandler:将结果集中某一列的数据存放到List中。
KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List<Map>),再把这些map再存到一个map里,其key为指定的列。
ScalarHandler:将结果集第一行的某一列放到某个对象中。
ThreadLocal是一个线程局部变量