一、JDBC概述:
(一)概念:
- JDBC是利用java语言/程序连接并访问数据库的一门技术。
(二)开发步骤:
第一步:导入驱动包。
第二步:开发并实现JDBC
(1)注册驱动:
- 方法:显示加载com.mysql.jdbc.Driver类。导致该类的static代码块被执行,从而创建一个Driver对象,并使用该对象完成驱动注册。
- 语法:Class.forName("com.mysql.jdbc.Driver");
- 说明:
- Class.forName(String className);作用:返回与带有给定字符串名的类或接口相关联的 Class 对象。主要效果与new className();类似,都是加载的类的。只不过new className()是一个隐式加载,而该函数则是显式加载。
(2)获取连接器,与数据库建立连接:
- 方法:
- 通过调用DriverManager类的静态方法getConnection(String url, String user, String password)返回一个连接器。
- 语法:
- Connection oCnName = DriverManager.getConnection(url, userName, password);
- 说明:
- 参数url:指定数据库路径。使用默认安装mysql的本机地址:"jdbc.mysql://[localhost:3306]/dbName?characterEncoding=utf8"。固定格式,只有dbName自定义,localhost:3306可省略,其它不可改动。
- 参数userName:指定mysql的用户名。
- 参数password:指定该用户的密码。
- 返回值:返回一个Connection对象(连接器对象),主要是从该对象中获取与mysql传输sql语句的传输器。
(3)获取传输器:向mysql管理的数据库发送sql语句,并获取数据库执行的结果。
方法:通过调用连接器oCnName的createStatement()方法获取一个Statement对象。
语法:Statement oStName = oCnName.createStatment();
(4)通过传输向数据发送sql语句,并接收返回结果。
增、删、改通过oStName.executeUpdate(sqlStatement);方法完成,返回一个int值,表示影响的行数。
查通过oStName.executeQuery(sqlStatement);方法完成,返回一个ResultSet对象oRs,保存数据查询到的结果。
(5)结果处理
增,删,改代码自定义。
查:通过while循环,获取数据库处理的结果。
语法:while(oRs.next()){statement}
(6)释放资源
原则:后获取先释放,先获取后释放。
需释放的资源:结果集对象oRs,传输器对象oStName,连接器对象oCnName.
方法:通过此三对象所属的类的close()方法完成。
(7)示例:
二、使用安全的传输器
(一)statement传输器存在的隐患
1.存在的隐患的现象:通过拼接特殊字符改变传送的sql语句的语义改变。
2.隐患存在的原因:传输的sql语句是通过第三方输入拼接而成的。在接收第三方输入时,输入中可能存在sql关键字(比如or)或者特殊符号(#、-- 、' 等),就可能会导致SQL语句语义的变化,从而执行一些意外的操作(用户名或密码不正确也能登录成功)!
(二)解决方案:
1.通过正则表达式,程序员首先处理第三方输入,然后通过处理后的结果拼接传输sql语句。
(1)缺点:处理第三方输入代码需自定义。
(2)优点:一个传输器能够传输各类所需的sql语句。
2.通过PreparedStatement对象代替statement对象。
(1)解决方式:
使用PreparedStatement对象是先将SQL语句的骨架发送给服务器编译并确定下来,编译之后,SQL语句的骨架和语义就不会再被改变了,再将SQL语句中的参数发送给服务器,即使参数中再包含SQL关键字或者特殊符号,也不会导致SQL语句的骨架或语义被改变,只会被当作普通的文本来处理.
(2)解决步骤:
第一步:使用PreparedStatement对象代替Statement对象传输sql语句骨架,并返回一个PreparedStatement对象。
语法:
PreparedStatement oPs = oCn.preparedStatement(sql);
说明:
- 一个sql语句骨架指的是使用?(占位符)代替自定义变量后的sql语句
示例:select ?,? from tbName where name = ? and password = ?;
该方法使用一个PreparedStatement对象关联一个sql语句骨架。
也就是说同一时间内PreparedStatement对象只对应一条sql语句骨架,要想使用其它sql语句骨架就得重新创建一个该类的对象。
第二步:使用PreparedStatement的类方法setBaseType(占位符序号,变量名);构造实参,填充占位符。
说明:
sql骨架中有多少个?,就得使用该类方法构造多少个实参。
该类方法第一个实参指的是占位符的序号,序号是从1开始的,区别与下标。
构造的实参必须与占位符的序号一一对应。
方法名中的BaseType指的是不同类型的数据要使用对应类型的set方法,如类型int数据,则使用setInt方法构造实参。
第三步:将填充完的sql语句传输给数据库。
语法:oPs.executeQurery()或oPs.executeUpdate()方法传输构造好的sql语句。
(3)优缺点:
优点:
-
- 使用PreparedStatement对象可以防止SQL注入攻击
- 而且通过方法设置参数更加的方便且不易出错!
- 还可以从某些方面提高程序执行的效率!
- 缺点:自认为:就是说同一时间内PreparedStatement对象只对应一条sql语句骨架,要想使用其它sql语句骨架就得重新创建一个该类的对象。
三、使用连接池
(一)连接池概念:
1.池: 指内存中的一片空间(容器,比如数组、集合)。
2.连接池:就是将连接存放在容器中,供整个程序共享,可以实现连接利用,减少连接创建和关闭的次数,从而提高程序执行的效率。
(二)传统连接与连接池的工作方式:
1.传统连接:
- 在传统方式中,每次用户需要连接访问数据库时,都是创建一个连接对象,基于这个连接对象访问数据库,用完连接后,会将a连接关闭由于每次创建连接和关闭连接非常的耗时间而且耗资源,因此会导致程序执行的效率低下。
2.连接池连接:
- 可以在程序一启动时,就创建一批连接放在一个连接池中(容器),当用户需要连接时,就从连接池中获取一个连接对象,用完连接后,不要关闭,而是将连接再还回连接池中,这样一来,用来用去都是池中的这一批连接,实现了连接的复用,减少了连接创建和关闭的次数,从而提高了程序执行的效率!
(三)使用c3p0连接池:
- 第一步:导入jar包。
- 第二步:配置连接数据库信息
- 方法一:将连接参数提取到properties文件中,该文件名必须是c3p0.properties的file类型文件。
- 配置方法:
- c3p0.driverClass = com.mysql.jdbc.Driver
- c3p0.jdbcUrl = jdbc:mysql:///dbName?characterEncoding=utf8
- c3p0.user = userName
- c3p0.password = passWord
- 配置方法:
- 方法二:将连接参数提取到在c3p0-config.xml文件中。该文件名必须是c3p0-config.xml。
- 配置方法:
- 方法一:将连接参数提取到properties文件中,该文件名必须是c3p0.properties的file类型文件。
<c3p0-config>
<default-config>
<property name="driverClass">
com.mysql.jdbc.Driver
</property>
<property name="jdbcUrl">
jdbc:mysql:///jt_db?characterEncoding=utf-8
</property>
<property name="user">
root
</property>
<property name="password">
root
</property>
</default-config>
</c3p0-config>
-
-
- 第三步:处理数据等价于开发jdbc中的第四、五步。
- 第四步:释放资源。规则与语法与开发jdbc中的第六步一致。
四、关于结果集处理