前言
本文展示如果快速入门JDBC
JDBC
概念:Java DataBase Connectivity 即,用java操作数据库。JDBC定义了操作所有关系型数据库的规则(接口)。真正执行的代码时驱动jar包中的实现类。
快速入门
步骤:1.导入驱动jar
包:一、复制mysql-connector-java-5.1.11-bin.jar
到libs
目录中 二、右键–>add as library
jar包版本需与mysql版本合适,太高或太低均会报错。
2.注册驱动
3.获取数据库连接对象Connection
4.定义sql
5.获取执行sql语句的对象Statement
6.执行sql,接受返回结果
7.处理结果
8.释放资源
public static void main(String[] args) throws Exception{
//1.导入jar包
//2.注册对象
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库连接对象Connection
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/crawler",
"root", "12345");
//4.定义sql
String sql = "update stu set pn = 12345";
//5.获取执行sql语句的对象Statement
Statement statement = connection.createStatement();
//6.执行sql,接受返回结果
int count = statement.executeUpdate(sql);
//7.处理结果
System.out.println(count);
//8.释放资源
statement.close();
connection.close();
}
详解各个对象
-
DriverManager
:驱动管理对象-
注册驱动:告诉程序该使用哪个jar数据库驱动jar包
static void registerDriver(Driver driver);//注册与给定的驱动程序 DriverManager. //写代码使用:Class.forName("com.mysql.jdbc.Driver"); //通过查看源代码发现:在com.mysql.jdbc.Driver类中存在静态代码块 static { try{ java.sql.DriverManager.registerDriver(new Driver()); } catch(Exception e) { } }
注意:
mysql5
之后的驱动jar
包可以省略注册驱动的步骤。 -
管理数据库连接
//方法 static Connection getConnection(String url, String user, String password) //参数 url:jdbc:mysql://ip地址:端口号/数据库名称//连接路径 //例如:jdbc:msyql://localhost:3306/crawler user:用户名 password:密码
细节:如果连接到的是本机mysql服务器,并且本机默认端口是3306,则url可以简写为:
jdbc:msyql///数据库名称
.
-
-
Connection
:数据库连接对象-
获取执行sql对象
Statement createStatement(); PrepareStatement prepareStatement(String sql);
-
管理事务
- 开启事务:
void setAutoCommit(boolean autoCommit)
:调用该方法设置参数为false
,即开启事务。 - 提交事务:
void commit()
- 回滚事务:
void rollback()
- 开启事务:
-
-
Statement
:执行sql的对象-
执行sql
-
bolean execute(String sql)
:可以执行任意sql,了解即可 -
int executeUpdate(String sql)
:执行DML(insert, update, delete)
语句、DDL(create, alter, drop)
语句返回值
:影响行数,可以通过影响的行数判断DML语句是否执行,如果返回值法院0,则实行成功;反之,则执行失败。 -
ResultSet executeQuery(String sql)
:执行DQL(select)
语句
-
-
-
ResultSet
:结果集对象-
boolean next()
:游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据)。如果是返回true
,否则返回false
。 -
getXxx(param)
:获取数据Xxx:代表数据类型 //int getInt() String getString(); param:int: 代表列的编号从1开始,//getString(1); String: 代表列的名称,//getDouble("balance");
游标:默认在表的第一行(即写有列名的行)。
resultSet = statement.executeQuery(sql); //游标先向下移动一行 resultSet.next(); int i = resultSet.getInt(1); String string = resultSet.getString(2); double d = resultSet.getDouble("balance");
遍历resultSet
while (resultSet.next()) { //循环判断是否是最后一号末尾 int i = resultSet.getInt(1); String string = resultSet.getString(2); double d = resultSet.getDouble("balance"); System.out.println(i + "---" + string + "---" + d); }
-
练习:定义一个方法,查询
account
表的数据将其封装为对象,然后转载集合,返回- 定义
account
类 - 定义方法:
public List<account> findAll() {}
- 实现方法:
select * from account;
/** * 查询所有account对象 * * @return */ public List<Account> findAll() { ResultSet resultSet = null; Statement statement = null; Connection connection = null; List<Account> list = new ArrayList<Account>(); try { //1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获取连接 connection = DriverManager.getConnection("jdbc:mysql:///crawler","root", "12345"); //3.获取执行sql的对象 statement = connection.createStatement(); //4.定义sql String sql = "select * from account"; //5.执行sql resultSet = statement.executeQuery(sql); //6.定义account对象为null Account account = new Account(); //7.遍历resultSet while (resultSet.next()) { //8.获取数据 int id = resultSet.getInt("id"); String name = resultSet.getString(2); double balance = resultSet.getDouble(3); Date date = resultSet.getDate(4); account.setId(id); account.setName(name); account.setBalance(balance); account.setCreated(date); //9.装载集合 list.add(account); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { if(resultSet != null) { try { resultSet.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if(statement != null) { try { statement.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if(connection != null) { try { connection.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } return list; }
- 定义
-
-
PrepareStatement
:执行sql的对象-
SQL
注入问题:在拼接sql时,有一些sql特殊关键字参与字符串的拼接。造成安全性问题。- 输入任意用户名,密码为
a' or 'a' = 'a'
sql
:select * from stu where username = ‘adfaf’ and password = ‘a’ or ‘a’=‘a’
- 输入任意用户名,密码为
-
解决:使用
PrepareStatement
对象 -
预编译sql:参数使用
?
作为占位符 -
步骤:
1.注册驱动
2.获取数据库连接对象Connection
3.定义sql
注意:sql参数使用
?
作为占位符。例如:select * from user where username = ? and password = ?;4.获取执行sql语句的对象
PrepareStatement PrepareStatement(String sql);
5.给
?
赋值:- 方法:setXxx(参数1, 参数2)
- 参数1:
?
的位置编号 - 参数2:
?
的值
- 参数1:
5.执行sql,接受返回结果,不需要传递sql语句
6.处理结果
7.释放资源
- 方法:setXxx(参数1, 参数2)
-
注意:后期均会使用PrepareStatement来完成增删改查的操作
1.可以防止sql注入;
2.效率更高。
抽取工具类
-
目的:简化书写步骤。
-
分析:
-
注册驱动也抽取
-
抽取一个方法获取连接对象
-
需求:不传递参数,且保证工具类的通用性。
-
解决:配置文件
url=jdbc:mysql:///crawler user=root password=12345 driver=com.mysql.jdbc.Driver
-
-
抽取一个方法释放资源
-
代码实现
package com.it.util;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
/**
* 只需要读取一次即可拿到这些值,使用静态代码块
* */
static {
//读取资源文件,获取值
try {
//1.创建Properties集合类
Properties pro = new Properties();
//获取src目录下文件的方式--->Classloader 类加载器
ClassLoader classLoader = JdbcUtils.class.getClassLoader();
URL res = classLoader.getResource("jdbc.properties");
String path = res.getPath();//自动获取路径,不必手动填写
//2.加载文件
pro.load(new FileReader(path));
//3.获取数据、赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4.注册驱动
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接
* @return 连接对象
* */
public static Connection getConnection() {
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
return null;
}
}
/**
* 释放资源
* */
public static void close(Statement statement, Connection connection) {
if(statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 方法重载
* */
public static void close(ResultSet resultSet, Statement statement, Connection connection) {
if(resultSet != null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
调用utils包
import com.it.domain.Account;
import com.it.util.JdbcUtils;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class JdbcDemo08 {
public static void main(String[] args) {
JdbcDemo07 j = new JdbcDemo07();
List<Account> list = j.findAll();
System.out.println(list);
}
/**
* 查询所有account对象
*
* @return
*/
public List<Account> findAll() {
ResultSet resultSet = null;
Statement statement = null;
Connection connection = null;
List<Account> list = new ArrayList<Account>();
try {
connection = JdbcUtils.getConnection();//静态方法调用
//3.获取执行sql的对象b
statement = connection.createStatement();
//4.定义sql
String sql = "select * from account";
//5.执行sql
resultSet = statement.executeQuery(sql);
//6.定义account对象为null
Account account = new Account();
//7.遍历resultSet
while (resultSet.next()) {
//8.获取数据
int id = resultSet.getInt("id");
String name = resultSet.getString(2);
double balance = resultSet.getDouble(3);
Date date = resultSet.getDate(4);
account.setId(id);
account.setName(name);
account.setBalance(balance);
account.setCreated(date);
//9.装载集合
list.add(account);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.close(resultSet, statement, connection);
}
return list;
}
}
练习
需求:
- 通过键盘录入用户名和密码
- 判断用户是否登录成功
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 使用createdStatement()方法
* */
public class Login {
public boolean login(String username, String password) {
//如果有任意为空,就返回false
if(username == null && password == null) return false;
ResultSet resultSet = null;
Statement statement = null;
Connection connection = null;
try {
connection = JdbcUtils.getConnection();
statement = connection.createStatement();
String sql = "select * from stu where user='"
+ username + "' and password='" + password + "'";
resultSet = statement.executeQuery(sql);
return resultSet.next();//如果有下一行则返回true
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.close(resultSet, statement, connection);
}
return false;
}
}
import java.sql.*;
/**
* 使用PrepareStatement(String sql)
* */
public class Login_Pro {
public boolean login(String username, String password) {
if(username == null && password == null) return false;
ResultSet resultSet = null;
PreparedStatement ps = null;
Connection connection = null;
try {
connection = JdbcUtils.getConnection();
String sql = "select * from stu where user=? and password=?";
ps = connection.prepareStatement(sql);
//给?赋值
ps.setString(1, username);
ps.setString(2, password);
resultSet = ps.executeQuery();//不传参
return resultSet.next();//如果有下一行则返回true
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.close(resultSet, ps, connection);
}
return false;
}
}
JDBC管理事务
事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
操作:
- 开启事务
- 提交事务
- 回滚事务
使用Connection对象来管理事务:
-
开启事务:
void setAutoCommit(boolean autoCommit)
:调用该方法设置参数为false
,即开启事务。在执行sql前开启事务
-
提交事务:
void commit()
在执行完毕所有sql提交事务
-
回滚事务:
void rollback()
在catch中回滚事务
总结
以上就是今天要讲的内容,结束。