JDBC
JDBC标准
JDBC是什么
- Java Database Connectivity:Java访问数据库的解决方案
- 希望用相同的方式访问不同的数据库,以实现与具体数据库无关的Java操作界面
- JDBC定义一套标准接口,即访问数据库的通用API,不同的数据库厂商根据各自数据库的特点去实现这些接口
JDBC接口及数据库厂商实现
- DriverManager 驱动管理
- Connection 连接接口
- DatebaseMetaData
- Statement 语句对象接口
- PreparedStatement
- CallableStatement
- ResuleSet 结果集接口
- ResultSetMetaData
JDBC工作原理
- JDBC定义接口
- 数据库厂商实现接口
- 程序员调用接口,实际调用的是底层数据库厂商的实现部分
JDBC工作过程:
- JDBC工作过程:
- 加载驱动,建立连接
- 创建语句对象
- 执行SQL语句
- 处理结果集
- 关闭连接
Driver接口及驱动类加载
- 驱动类加载方式(Oracle):
Class.forName("orcle.jdbc.driver.OracleDriver");
- 驱动类加载方式(Mysql):
Class.forName("com.mysql.jdbc.driver");
装载驱动类,驱动类通过static块实现在DriverManager中的“自动注册”
Connection接口
Class.forName("com.mysql.jdbc.driver")
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mysql",
"root","");
根据url连接参数找到与之匹配的Driver对象,调用其方法获取连接
NOTE:Connection只是接口!真正的实现是由数据库厂商提供的驱动包完成的
Statement接口
- Statement stme=conn.createStatement();
stmt
- boolean flag = stmt.execute(sql); DDL 数据库定义语言
- int falg = stmt.executeUpdate(sql); DML 数据更改语言
- ResuleSet rs = stmt.executeQuery(sql); DQL 数据查询语言
ResultSet接口
执行查询SQL语句后返回的结果集,由ResultSet接口接收
常用处理方式:遍历/判断是否由结果(登陆)
String sql = "select * from emp";
ResuleSet rs = stmt.executeQuery(sql);
while(rs.next()) {
System.out.println(rs.getInt("empno")+","+
rs.getString("ename"));
}
- 查询的结果存放在ResuleSet对象的一系列行中
- ResultSet对象的最初位置在行首
- Result.next()方法用来在行间移动
- Result.getXXX()方法用来取的字段的内容
数据库厂商实现
Oracle实现
下载对应数据库的驱动
ojdbc6.jar/ojdbc14.jar将驱动类加载到项目中
MyEclipse:Build Path加载驱动类
Class.forName("oracle.jdbc.OrcleDriver")
MySQL实现
下载对应数据库的驱动
mysql-connector-java-5.0.4-bin.jar将驱动类加载到项目中
MyEclipse: Build Path加载驱动类
Class.forName("com.mysql.jdbc.Driver");
连接管理
通过连接工具类获取连接
在工程中,编写一个访问数据库的工具类,此后所有访问数据库的操作,都从工具类中获取连接
-
两种方式:
- 直接把数据配置写在工具类中
- 把数据库配置写在一个properties属性文件里,工具类读取文件,逐行获取数据库参数
建议第二种
通过属性文件维护连接属性
#驱动类名
jdbc.driver=com.mysql.jdbc.Driver
#连接字符串
jdbc.url=jdbc:mysql://localhost:3306/tedustore
#访问数据库的用户名
jdbc.username=root
#访问数据库的密码
jdbc.password=
NOTE:在properties文件种,#符号表示注释
加载属性文件
Properties cfg = new Properties();
InputStream inStream = DBUtils.class.getClassLoader().getResourceAsStream("db.properties");
cfg.load(inStream);
加载指定属性文件
连接的关闭
在工具类中定义公共的关闭连接的方法
-
所有访问数据库的应用,共享此方法
public static void closeConnection(Connection con){ if(con != null){ try{ con.close(); }catch(){ e.printStackTrace(); } } }
连接池技术
为什么要使用连接池
数据库连接的建立及关闭资源消耗巨大
传统数据库访问方式:一次数据库访问对应一个物理连接,每次操作数据库都要打开、关闭该物理连接,系统性能受损
解决方案:数据库连接池(Connection Pool)
系统初始运行时,主动建立足够的连接,组成一个池。每次应用程序请求数据库连接时,无需重性打开连接,而是从池中取出已有的连接,使用完后,不在关闭,而是归还
- 连接池中连接的释放与使用原则
- 应用启动时,创建初始化数目的连接
- 当申请时无连接可用或者达到指定的最小连接数,按增量参数值创建新的连接
- 为确保连接池中最小的连接数的策略
- 动态检查:定时检查连接池,一旦发现数量小于最大连接数,则补充相应的新连接,保证连接池正常运转
- 静态检查:空闲连接不足时,系统才检测是否达到最小连接数
- 按需分配,用过归还,空闲超时释放,获取超时报错
- 连接池也只是接口,具体实现由厂商来完成
使用Apache DBCP连接池
- DBCP(DataBase connection pool):数据库连接池
- Apache的一个Java连接池开源项目,同时也是Tomcat使用的连接池组件
- 连接池是创建和管理连接的缓冲池技术,将连接准备好,被任何需要他们的应用使用
-
需要两个jar包文件
- conmmons-decp-1.4.jar 连接池的实现
- commons-pool-1.5.jar 连接池实现的依赖库
MyEclipse:Build Path
通过DataSource获取连接
通过属性文件获取连接池参数
-
加载这些参数,获得连接
private static BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(driverClassName); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); Connection conn = dataSource.getConnection();
连接池参数
-
常用参数有:
- 初始连接数
- 最大连接数
- 最小连接数
- 每次增加的连接数
- 超时时间
- 最大空闲连接
- 最小空闲连接
根据应用需要,设置合适的值
异常处理
SQLException简介
java.sql.SQLException是在处理JDBC时常见的exception对象
用来表示JDBC操作过程中发生的具体错误
一般的SQLException都是因为操作数据库时出错,比如Sql语句写错,或者数据库中的表或数据出错
-
常见异常:
- 登陆被拒绝
可能原因:程序里键值对信息时大小写和属性文件中不匹配 - 列名无效
可能原因:查找的表和查找的列不匹配 - 无效字符
可能原因:sql语句语法有错,比如语句结尾时不能有分号 - 无法转换为内部表示
可能原因:结果集取数据时注意数据类型 - 表或者视图不存在
检查SQL中的表名是否正确 - 不能将空值插入
检查执行insert操作时,是否表有NOT NULL约束,而没有给出数据 - 缺少表达式
检查SQL语句的语法 - SQL命令未正确结束
检查SQL语句的语法 - 无效数值
企图将字符串类型的值填入数字型而造成,检查SQL语句
- 登陆被拒绝
-
其他可能出现的异常
- 文件找不到
可能原因:db.properties文件路径不正确
- 文件找不到
SQLException 属于Checked Exception,必须使用try...catch或throws明确处理
public static syschronized Connection getConnection()throws SQLException{
//语句
}
try{
//语句
}catch(Exception e){
e.printStackTrace();//追踪处理
//throw new RuntimeException(e);//或者抛出
}