1.什么是JDBC
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
JDBC提供的主要功能是:1)同一个数据库建立连接;2)向数据库发送SQL语句;3)处理数据库返回的结果。
Java应用程序通过JDBC API(java.sql)与数据库连接,而实际的动作则是由JDBC驱动程序管理器(DriverManager)通过JDBC驱动程序与数据库系统进行连接。也就是说,真正提供存取数据库功能的是JDBC驱动程序,用户如果想要存取某一种具体的数据库系统中存储的数据,就必须要拥有对应于该数据库系统的驱动程序。
JDBC优缺点:
1)优点:简单易学,上手快,非常灵活构建SQL,效率高
2)缺点:代码繁琐,难以写出高质量的代码(例如:资源的释放,SQL注入安全性等)开发者既要写业务逻辑,又要写对象的创建和销毁,必须管底层具体数据库的语法(例如:分页)。
3)适合于超大批量数据的操作,速度快
jdbc的主要工作原理:
1、加载驱动程序 Class.forName(driver);JDBC只定义接口,具体实现由各个数据库厂商负责。程序员使用时只需要调用接口,实际调用的是底层数据库厂商的实现部分
2、获取数据库连接,getconnection()调用driver的connect()方法 返回一个实现了Connection接口的对象
3、创建语句对象,利用connection创建的statement执行sql语句。
Statement PreparedStatement CallableStatement
4、提交执行语句对象获取返回的结果集
5、遍历访问结果集
6、关闭
2.数据库驱动
安装好数据库之后应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数据库打交道。其实也就是数据库厂商的JDBC接口实现,即对Connection等接口的实现类的jar文件。
3、JDBC
JDBC对Java程序员来说是API,对实现与数据库连接的服务提供商来说是接口模型。它为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。应用程序与数据库交换数据时,通过使用Java.Sql包应用程序使用JDBC API。Java.Sql包的接口由JDBC驱动程序厂商实现,它为一个或多个数据库管理系统接口提供基于Java的包容器
3.1.Driver接口
Driver接口由数据库厂家提供,作为java开发人员,只需要使用Driver接口就可以了。在编程中要连接数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法。如:
装载MySql驱动:Class.forName("com.mysql.jdbc.Driver"); 参数为连接串,实际上是一个具体的驱动类的全名 new A() --Class.forName(“com.yan.A”).newInstance()
装载Oracle驱动:Class.forName("oracle.jdbc.driver.OracleDriver");
JDBC的Driver可分为以下4中类型:JDBC-ODBC Bridge和ODBC Driver、Native-API partly-Java Driver、JDBC-Net All-Java Driver、Native-protocol All-Java Driver
3.2.Connection接口
Connection与特定数据库的连接(会话),在连接上下文中执行sql语句并返回结果。DriverManager.getConnection(url,user, password)方法建立在JDBC URL中定义的数据库Connection连接上。
连接MySql数据库:Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database","user", "password");
连接Oracle数据库:Connection conn =DriverManager.getConnection("jdbc:oracle:thin:@host:port:database","user", "password");
常用方法:
createStatement():创建向数据库发送sql的statement对象。一般用于传递静态SQL语句---固定的SQL语句,没有参数
prepareStatement(sql):创建向数据库发送预编译sql的PrepareSatement对象。推荐使用(静态或者动态)
prepareCall(sql):创建执行存储过程的callableStatement对象。
setAutoCommit(booleanautoCommit):设置事务是否自动提交。JDBC中默认是单语句单事务。可以使用setAutoCommit(false)关闭自动提交
commit():在链接上提交事务。手动提交必须在前面设置了关闭自动提交
rollback():在此链接上回滚事务。手动回滚必须在前面设置了关闭自动提交
3.3.Statement接口
用于执行静态SQL语句并返回它所生成结果的对象。
三种Statement类:
Statement:由createStatement创建,用于发送简单的SQL语句(不带参数)。SQL语句的直接拼接可能会导致SQL注入漏洞
PreparedStatement:继承自Statement接口,由preparedStatement创建,用于发送含有一个或多个参数的SQL语句。PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入,所以我们一般都使用PreparedStatement。
优势: 1、支持预编译 2、避免SQL注入漏洞 |
用户登录的SQL:
如果使用Statement则: String sql=”select * from t_users where username=’”+username+”’ and password=’”+password+”’”
这种方式的缺陷:如果用户输入口令是123’ or ‘1’=’1 如果使用?占位符的方式这个输入无效 |
CallableStatement:继承自PreparedStatement接口,由方法prepareCall创建,用于调用存储过程。
常用Statement方法:
execute(Stringsql):运行语句,返回是否有结果集
executeQuery(Stringsql):运行select语句,返回ResultSet结果集。
executeUpdate(Stringsql):运行insert/update/delete操作,返回更新的行数。
addBatch(Stringsql) :把多条sql语句放到一个批处理中。
executeBatch():向数据库发送一批sql语句执行。
sql注入
客户端利用jdbc-Statement的缺点,传入非法参数,从而让jdbc返回不合法的值,我们利用这种情况,通称为sql注入.
现在项目中不直接使用Statement,使用PreparedStatement,PreparedStatement它除了具有Statement是所有功能外,还有动态sql处理能力,包括:程序执行时动态为?符设置值,安全检查,避免sql注入问题,预处理能力
?表示占位符,只能出现在字段值的位置,不能替代表名,不能替代列名;
Statement和PreparedStatement的区别:
Statement只能处理静态SQL;
PreparedStatement既能处理静态sql也能处理动态sql,它继承了Statement的特点
站在预处理角度:
PreparedStatement适合做连续多次结构相同的sql语句,有优势.
Statement适合做连续多次不同结构的sql语句,有优势.
项目中,我们都用子接口的原因
1、支持动态sql,也支持静态sql
2、预处理
3、静态sql也可以用PreparedStatement
适合:
静态sql—优先Statement;
动态sql—优先PreparedStatement
强烈推荐使用PreparedStatement
3.4.ResultSet接口
ResultSet提供检索不同类型字段的方法,常用的有:
getString(intindex)、getString(StringcolumnName):获得在数据库里是varchar、char等类型的数据对象。
getFloat(intindex)、getFloat(StringcolumnName):获得在数据库里是Float类型的数据对象。
getDate(intindex)、getDate(StringcolumnName):获得在数据库里是Date类型的数据。
getBoolean(intindex)、getBoolean(StringcolumnName):获得在数据库里是Boolean类型的数据。
getObject(intindex)、getObject(StringcolumnName):获取在数据库里任意类型的数据。
ResultSet还提供了对结果集进行滚动的方法:
next():移动到下一行
previous():移动到前一行
absolute(introw):移动到指定行
beforeFirst():移动resultSet的最前面。
afterLast():移动到resultSet的最后面。
使用后依次关闭对象及连接:ResultSet → Statement → Connection
:Calibri;mso-hansi-font-family:Calibri'>包括:程序执行时动态为?符设置值,安全检查,避免sql注入问题,预处理能力?表示占位符,只能出现在字段值的位置,不能替代表名,不能替代列名;