目录
改进二:使用PreparedStatement解决SQL注入问题:
1.JDBC的本质:
Java DataBase Connection(java语言连接数据库)
一个由SUN公司定制的,各大数据库厂商负责实现的一套接口;
接口都有调用者和实现者, 面向接口调用、面向接口写实现类,这都属于面向接口编程。
为什么要面向接口编程? 解耦合:降低程序的耦合度,提高程序的扩展力。 多态机制就是非常典型的:面向抽象编程。(不要面向具体编程)
JDBC的出现极大地降低了连接数据库的成本,程序员们通过JDBC进行数据库连接的时候不再需要考虑到各数据库的不同,直接使用相同的语法进行连接操作即可;
JDBC本质上是一套接口;


2. JDBC语法(编程六部曲)
Connection conn=null;
Statement stmt=null;
Resultset rs=null;
try{
//第一步 注册驱动
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver())
//----------------------------------------
Class.forName(“com.mysql.cj.jdbc.Driver”);
//第二步:获取数据库连接 通过url user password进行数据的连接
String url="jdbc:mysql://localhost:3306/wangye"(你需要连接的数据库名);
String user="root";
String password="123456";
conn=DriverManager.getConnection(url,user,password);
//3.第三步 获取数据库操作对象
stmt=conn.createStatement();
//4.执行SQL语句
String sql="SQL语句"
//SQL语句不同,执行语句不同
int count=stmt.executeUpdate(sql);
rs=stmt.executeUpdate(sql);
//5.处理查询结果集(如果第四步为Select,需要使用这一步进行处理)
while(rs.next( )){
String xx=rs.getString("");
String XX=rs.getString(" ");
}
}catch(SQLException e){
抛出注册驱动时的异常
e.printStackTrace();
}finally{
//6.释放资源
//因为JDBC服从于main方法,所以我们在java编写jdbc会自动关闭;
//但是如果我们在服务器中进行编写的话,就需要主动释放资源了,
//我们先释放ResultSet、再释放Statement,最后关闭Connection;
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
改进一:通过IO流获取配置文件信息,进行数据库的连接:
读取属性配置文件:
在配置文件中直接书写键值对的格式即可;
driver url use password
![]()
// 属性资源文件绑定
private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");
// 根据属性配置文件key获取value
private static String driver = bundle.getString("driver");
private static String url = bundle.getString("url");
private static String user = bundle.getString("user");
private static String password = bundle.getString("password");
改进二:使用PreparedStatement解决SQL注入问题:
SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法
如何解决SQL注入,用户提供的信息,不参与SQL语句的编译即可;
SQL注入过程变现为:先进行字符串的拼接,然后再进行编译;
java.sql.Statement接口的特点:先拼接后编译
-
优点:使用Statement可以进行sql语句的拼接
-
缺点:因为拼接的存在,导致SQL注入
java.sql.PrepareStatement接口的特点是先编译后进行是sql语句的传值。
-
优点:避免的SQL注入
-
缺点:没有办法进行sql语句的拼接,只能给sql语句传值;
Statement与PrepareStatement并不存在好坏之分,他们两个有各自的应用场景;
一般我们选择PrepareStatement 因为它解决了SQL注入的问题;编译一次执行N次,效率较高;在编译阶段会进行安全检查,会报错;
在需要进行SQL拼接的时候,我们使用Statement,例如进行升序和降序的排列,如果此时使用PreparedStatement,那么我们的SQL语句往往是错误的,带着引号的;
使用PreparedStatement,传统的3,4步骤改变
//第三步:获取预编译数据库操作对象
String sql="select account,password from log where account=?and password=?";
ps = conn.prepareStatement(sql);
//记住,JDBC中所有的下标都是从1开始的
ps.setString(1,value);
ps.setString(2,value);
//先进行sql语句的编写,再进行预编译,之后对 占位符 进行传参
//第四步:执行预编译对象,空参
rs=stmt.executeQuery();
-
我们先书写sql语句的大致框架,需要进行判断和数据处理的地方用?进行占位
-
处理查询结果集 prepareStatement.executeQuery() 无须在括号中填写内容,否则会进行处理SQL语句的覆盖
改进三:编写JDBC的工具类 简化JDBC编程
1.注册驱动 静态代码块 只在类加载的时候加载
2.封装获取连接
3.释放资源
为什么类的方法一般都是静态化的?
构造方法静态化是为了防止new对象,为什么要防止new对象?
因为工具类中的方法都是静态的,不需要new对象,直接使用类名的方式调用,创建工具类就是为了方便使用,能少写代码就少写代码
以下为工具类中的Java代码
package DBunit;
import java.sql.*;
import java.util.ResourceBundle;
public class jdbc {
private static ResourceBundle bundle = ResourceBundle.getBundle("resource.jdbc");
private static String driver = bundle.getString("driver");
private static String url = bundle.getString("url");
private static String user = bundle.getString("user");
private static String password = bundle.getString("password");
//构造方法私有化,防止new对象
private jdbc() {
};
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection connection() throws Exception {
return DriverManager.getConnection(url, user, password);
}
public static void close(Connection conn, Statement ps, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
以下为使用IO流读取配置文件和使用工具类编写的JDBC,代码及其简洁
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//1.注册驱动
//2.获取数据库连接
conn=connection();
//3.获取数据库操作对象
stmt = conn.createStatement();
//4.编写SQL执行SQL
String sql ="select * from student";
rs=stmt.executeQuery(sql);
//5.处理查询结果集
while (rs.next()){
String name=rs.getString("name");
String age=rs.getString("age");
System.out.println(name+" "+age);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//6.释放资源
close(conn,stmt,rs);
}
3.事务
JDBC默认事务是自动提交,执行任意一条SQL语句,就会更改数据库中的数据
而我们在实际开发中,通常都是多条DML语句共同联合才算完成,必须保证他们同时成功或者同时失败;
因此,如果我们要想实现事务,就需要关闭默认提交机制。而我们在实际开发中也必须将自动提交机制关闭掉,改成手动提交,当一个完整的事务结束之后,再提交;
修改自动提交的方法:
开启事务:Connecton.setAutoCommit(false);
提交事务:Connecton.commit();
回滚事务:Connection.rollback();写到catch{}中,表示遇到异常就进行回滚;

4. 悲观锁or乐观锁:
本质上就是sql语法,在select语句后面加上for update;
表示所查询的数据被锁住了,在当前事务还没结束的时候,不能对已经锁定的行进行操作;
乐观锁:多线程,都可以进行修改,但是有版本号记录,可以进行回滚;

5.补充:什么是统一资源定位符 URL
URL是用表示资源所在的唯一位置
组成:通信协议+IP地址+端口号port+资源名
其中:通信协议包含很多,不仅仅是http,https,还包括一些数据库连接规范,是一系列数据交互的协议
IP地址,用来定位某台计算机,相当于服务器/计算机的身份证
端口号:用来标识服务器上该服务所在位置
资源名:资源的唯一位置
如果我们连接的是orcle数据库的话:
oracle:jdbc:thin:@localhost:1521:bjpowernode oracle:jdbc:thin:@ 这是oracle和java的通信协议
文章介绍了JDBC的本质,即一套由SUN定制的数据库连接接口,强调了面向接口编程的优势。详细阐述了JDBC编程六部曲,并提出了三个改进点:通过IO流读取配置文件,使用PreparedStatement防止SQL注入,以及编写JDBC工具类简化编程。此外,还讨论了事务管理和悲观锁与乐观锁的概念。
3913

被折叠的 条评论
为什么被折叠?



