JDBC笔记较少,故全整理在此处
本质
JDBC:JavaDataBase Connectivity(Java数据库连接)
本质上是一个接口,SUN公司编写制定。
由Oracle,MySQL等编写实现此接口的类,即为驱动。
Java程序员面向接口编程。
编程六步
1、注册驱动
2、获取连接
3、获取数据库对象
4、执行sql语句
5、对操作结果处理
6、关闭资源。
具体实现代码
1、注册驱动
Driver driver = DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//一般不采用上面的,而是用下面的
Class.forName(com.mysql.jdbc.Driver);
2、获取连接
Connection conn = DriverManager.getConnection(url,user,password);
3、获取数据库对象
Statement stmt = conn.createStatement();
4、执行sql语句
String loginName = userLoginInfo.get("loginName");
String loginPwd = userLoginInfo.get("loginPwd");
String sql ="select * from t_user where loginName='"+loginName+"' and loginPwd='"+loginPwd+"'";
//使用上面的语句。
//会有SQL注入问题(不安全,用户输入的内容拼接在sql语句中
//能改变sql语句)。所以去掉第三步,使用下面的。
String sql ="select * from t_user where loginName = ? and loginPwd = ?";//使用?进行占位。
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,loginName);
ps.setString(2,loginPwd);
5、操作处理对象
ResultSet res = stmt.executeQuery(sql);
//返回ResultSet类型,表示查找的集
//stmt.executeUpdate(insert/delete/update);
//返回int类型,表示对几条数据进行了处理
6、关闭资源
需要在finally中进行由小到大进行关闭。
finally{
//释放资源
if(stmt != null)
try{
stmt.close();
}catch(Exception e){
e.printStackTrace();
}
if(conn != null)
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
完整代码
Connection conn = null;
Statement stmt = null;
try{
//注册驱动
Diver diver = DriverManager.registerDriver(new com.bjpowernode.jdbc.Driver());
//获取连接
Connection conn = DriverManager.getConnection(url,user,password);
//获取数据库操作对象
Statement stmt = conn.createStatement();
//执行sql语句
String sql = "";
}catch(SQLException e){
e.printStackTrace();
}finally{
//释放资源
if(stmt != null)
try{
stmt.close();
}catch(Exception e){
e.printStackTrace();
}
if(conn != null)
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
对获取的数据集进行处理
通过stmt.executeQuery(sql);返回ResultSet类型.
ResultSet res = stmt.executeQuery(sql);
ResultSet中有next方法,返回boolean类型。表示当前行是否存在!
while(res.next()){
//数字123是列的下标
String empno = res.getString(1);
String ename = res.getString(2);
String sal = res.getString(3);
//也可以这样写(recommend)
//注意:括号里面的是返回数据集(res)中的名字。
String empno = res.getString("empno");
String ename = res.getString("ename");
String sal = res.getString("sal");
//除了String类型,也可以以特定类型取出,比如int、double等
Double sal = res.getDouble("sal");
}
并非Statement不可用,在需要SQL注入时可用。各有各的用途。
封装JDBC工具类
package com.bjpowernode.jdbc.util;
import java.sql.*;
public class DBUtil {
private DBUtil(){}
/**
* 工具类中的构造方法都是私有的
* 因为工具类的方法都是静态的,不需要new对象。
*/
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//static静态代码块在类加载时可执行,执行一次。
//注册驱动只需要注册一次即可
public static Connection getConnection () throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","200203300922CJY.");
}
//因为在调用时会catch SQLException错误,所以现在上抛错误即可
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();
}
}
}
}
行级锁(悲观锁)
在事务未结束之前,select语句后加 for updata。会自动锁定查询的数据。别线程访问不到。
例如:
String sql = “ select loginName from t_user where loginName = “abc” for updata”;
乐观锁:支持并发,事务也需要排队,只不过需要一个版本号。
事务1—读取到版本号1.1
事务2–读取到版本号1.1
事务一先修改了,并将版本号改为1.2
事务2后修改的,准备提交时,发现版本号是1.2,和最初版本不一致,回滚。在进行读取
遇到的错误
1、Unable to load authentication plugin ‘caching_sha2_password’
原因:mysql-connector-java版本的问题。下载8.0以上版本,重新将其导入IEDA即可。
下载链接mysql-connector-java.
步骤:
- 点击Connector/J.
- 选择Platform Independent。
- 下载 Platform
Independent(Architecture Independent), ZIP Archive
2、NullPointerException
有多种原因可以造成这种结果:
- sql语句中的空格,标红处应当注意。
- 检查六步是否有问题,笔者忘记获取数据库对象,故出现了此问题。