JDBC知识汇总

JDBC是什么

1.JDBC,java database coonection,java语言连接数据库,本质是SUN公司指定的一套接口,各个数据库公司去实现接口,java程序员去调用接口,目的是为了降低程序耦合度,提高程序的扩展性;java中多态机制也是为了提高程序的扩展性、降低程序的耦合度,让程序更灵活;JDBC驱动:所有的数据库驱动都是以jar包的形式,在各个数据库官网下载,后将其配置到IDEA的lib目录下或者.classpath的环境变量中,里面有大量的.class文件,是JDBC接口的实现类;

JDBC如何编程实现

实现步骤

2.JDBC编程六部:(1)注册驱动,目的是告诉JVM,连接到哪个数据库
(2)获取连接,JVM进程与数据库进程连接通道打开,使用之后一定要关闭
(3)获取数据库操作对象,用来专门处理SQL语句
(4)执行SQL语句
(5)如果是DQL语句,即查询语句,则进行查询结果处理
(6)释放资源,使用完毕之后关闭通道

java实例代码

import java.sql.*;
import java.util.ResourceBundle;
public class JDBCTest03 {
public static void main(String[] args) {
Statement statement=null;//数据库操作对象
Connection connection=null;//连接
ResultSet resultSet=null;//查询结果
ResourceBundle resourceBundle=ResourceBundle.getBundle(“jdbctest01”);//使用资源绑定器,将一些配置写到配置文件中,提高程序的灵活性
try {
//注册驱动
String driver=resourceBundle.getString(“Driver”);
Class.forName(driver);
//获取连接,MySQL的URL的格式:dbc:mysql://数据库ip地址(localhost):3306/数据库名
String url=resourceBundle.getString(“url”);//url为统一资源定位符,不同的数据统一资源定位符不同,可以网上搜索
String user=resourceBundle.getString(“user”);
String password=resourceBundle.getString(“password”);
connection= DriverManager.getConnection(url,user,password);
//获取数据库操作对象
statement=connection.createStatement();
//执行SQL语句
String sqlstring=resourceBundle.getString(“sqlstring”);
/**
* 如果是insert,delete,update操作,则使用executeUpdate方法,返回值是int类型数据记录变化条数
* 如果是select子句,则返回的是ResultSet的结果集,ResultSet类有.next()方法,返回是boolean类型,
* 如果指针指向的行有记录,则返回true,如果指向的没有记录,则返回false;ResultSet中的getString()
* 方法,无论数据是什么,以String的形式返回,getInt()类似,还有其他的返回类型值;参数可以传递
* 结果集中第几列(从1开始),也可以为结果集中的列名;
*/
resultSet=statement.executeQuery(sqlstring);//专门执行查询语句的方法
//处理结果集
while (resultSet.next()){
int string1=resultSet.getInt(1);
String string2=resultSet.getString(“studentName”);
String string3=resultSet.getString(“teacherName”);
System.out.println(string1+"\t"+","+string2+"\t"+","+string3);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {//释放资源,遵循从小到大的顺序关闭,先出现的后关闭,后出现使用的先关闭
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

SQL注入现象

3.SQL注入现象:用户输入的信息含有SQL语句的关键字,在进行编译时,破坏了SQL语句的原意,进而破坏SQL语句
如何解决SQL注入现象:保证用户提供的信息不参与SQL语句的编译过程,这样即使用户的输入信息含有SQL关键字,但是不参与SQL语句的编译,不会破 SQL语句原意,使用PreparedStatement代替Statement,PreapredStatement为预编译的数据库操作对象,整体的JDBC编程不怎么变化,具体看java实例
ResourceBundle resourceBundle=ResourceBundle.getBundle(“jdbctest01”);//资源绑定器,绑定属性配置文件
// 使用预编译数据库操作对象解决SQL注入问题
Connection connection=null;
PreparedStatement preparedStatement=null;//这里使用预编译数据库操作对象
ResultSet resultSet=null;
try{
// (1)注册驱动
Class.forName(resourceBundle.getString(“Driver”));
// (2)获取连接
String url=resourceBundle.getString(“url”);
String username=resourceBundle.getString(“user”);
String password=resourceBundle.getString(“password”);
connection= DriverManager.getConnection(url,username,password);
// (3)获取预编译数据库操作对象
String sqlstring=“select * from t_user where loginName= ? and loginPassword= ?”;
// 先把SQL语句的框架搭建出来,其中的?为占位符,后给?传值进去,?不能用‘’修饰?,修饰的话会变成普通字符
// 传值的时候按照?出现的次序传值,从1开始,JDBC中所有的下标都是从1开始
preparedStatement=connection.prepareStatement(sqlstring);//对给的SQL框架先预编译
String user_name=userLoginInfor.get(“loginName”);
String pass_word=userLoginInfor.get(“loginPassword”);
preparedStatement.setString(1,user_name);//将user_name代表的字符串传值给第一个?,传值后会自动加上’’
preparedStatement.setString(2,pass_word);//传第二个值,也可以为setInt,这样传值就为int类型,不会加’’
// 执行SQL语句,预编译传值均完成,直接执行
resultSet=preparedStatement.executeQuery();
4.Statement和PreparedStatement区别:PreparedStatement解决了SQL注入的问题,并且执行效率更高,程序更灵活,sql语句编译执行,如果第二次sql语句一样,则不编译,直接执行;PreparedStatement有安全检查;PreparedStatement使用较多,只有极少数的情况下使用Statement,业务要求必须支持sql注入的时候、需要进行sql拼接的时候,使用Statement.
5.JDBC事务机制:(1)JDBC中事务是自动提交的,执行任意一条SQL语句,事务自动提交一次,这是JDBC默认是的事务行为,但是实际事务中是多条DML语句共同完成,必须保证这些DML语句同时成功或失败;(2)如何将自动提交机制改为手动提交:connection.setAutoCommit(false),此时就将自动提交机制改为了手动提交;(3)手动提交:connection.commit;(4)出现异常要回滚,connection.rollback();java实例如下: connection.setAutoCommit(false);//关闭事务自动提交机制;connection.commit();//手动提交事务 if (connection != null) {
try {
connection.rollback();//如果出现异常,事务回滚,可以添加一个savepoint,事务回滚到指定的savepoint点
} catch (SQLException ex) {
ex.printStackTrace();
}

JDBC实现代码的简化

5.Database工具类的封装,工具类的调用都是通过类名.的方式,工具类中的方法要为private和static,只能通过本类去调用,不需要new对象;具体的代码实现如下:
public class DBUtil {
// 静态代码块,在类加载的时候执行,并且只执行一次
// 注册驱动,仅执行一次,如果放在获取连接里面,系统可能会获取多次连接
// 但是注册驱动需要一次
static{
try {
Class.forName(“com.mysql.jdbc.Driver”);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private DBUtil(){}//无参数构造方法
/**
* 获取数据库连接对象
* @return 返回数据库连接对象
* @throws SQLException 抛给调用者去处理的异常
/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(“jdbc:mysql://localhost:3306/test”,“root”,password);
}
/
*
* 数据库使用完毕之后关闭资源
* 主程序处理异常也是catch,此处直接捕捉异常即可,不用抛给调用者
* @param statement 使用的数据库操作对象,因为PreparedStatement继承的Statement,关闭父类子类也关闭,程序的健壮性更好
* @param resultSet 查询数据库获得的结果集
* @param connection 数据库连接对象
*/
public static void close(Statement statement, ResultSet resultSet, Connection connection){
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
6.用JDBC实现模糊查询: String sqlstring=“select name from t_student where name like ?”;//用占位符代替整个模糊目标
preparedStatement=connection.prepareStatement(sqlstring);
preparedStatement.setString(1,"_e%");

行级锁

7.行级锁又称悲观锁,语法格式为select子句后加for update;select出来的行记录,在本事务没有完成之前,其他事务不能改变选出的行记录,事务必须排队执行,数据锁住,不能并发;
乐观锁:行记录有版本号,事务1和2都要对事务进行修改,刚开始读到版本号为1.0,事务1先提交执行,版本号为1.1,事务2提交时发现版本号 变成了1.1,事务2回滚,不提交,支持并发,事务不要排队,只是要版本号。

你可能感兴趣的:(知识汇总,编程工具相关,java,jdbc)