JavaDataBase Connectivity Java 数据库连接,操作数据库
操作步骤
1.导入驱动jar包
- 复制jar包到项目的libs目录下
- 右键该目录->Add as Library
2.注册驱动
Class.forName(“com.mysql.cj.jdbc.Driver”);
3.获取数据库连接对象
Connection conn = DriverManager.getConnection(url,user,password);
4.定义sql语句
String sql=”xxx”;
5.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
6.执行sql
int count = stmt.executeUpdate(sql);
7.处理结果
System.out.println(count);
8.释放资源
stmt.close();
conn.close();
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class Demo01 {
public static void main(String[] args) throws Exception {
//2-注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//3-获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javaSQL", "root", "********");
//4-定义sql语句
String sql="update account set balance = 123 where id=1";
//5-获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//6-执行sql
int count = stmt.executeUpdate(sql);
//7-处理结果
System.out.println(count);
//8-释放资源
stmt.close();
conn.close();
}
}
对象
- DriverManager : 驱动管理对象
- Connection : 数据库连接对象
- Statement : 执行sql的对象
- ResultSet : 结果集对象
- PreparedStatement : 执行sql的对象
DriverManager
功能:
1.注册驱动:告诉程序该使用哪一个数据库驱动jarstatic void registerDriver(Driver driver)
: 注册与给定的驱动程序 DriverManager
写代码使用:Class.froName("com.mysql.jdbc.Driver");
查看com.mysql.jdbc.Driver
的源码发现静态代码块
registerDriver就在该代码块中static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
Tips:mysql5之后的驱动jar包可以参略注册驱动步骤
2.获取数据库连接
方法: static Connection getConnevtion(String url, String user, String password)
参数:
url : 指定连接的路径
格式(语法): jdbc:mysql://ip地址(域名):端口号/数据库名称
例子:jdbc:mysql://localhost:3306/javaSQL
user : 用户名
password :密码
Connection
1.功能:
- 获取执行sql的对象
Statement createStatement()
PreparedStatement prepareStatement(String sql)
- 管理事务:
- 开启事务:
void setAutoCommit(boolean autoCommit)
:调用该方法设置参数为false,即开启事务 - 提交事务:
commit()
- 回滚事务:
rollback()
- 开启事务:
Statement 🌟🌟
不同语句的方法
boolean execute(String sql)
: 执行任意sql (不常用)int executeUpdate(String sql)
: 执行DML(insert,update,delete)语句,DDL(表和库的 create,alter,drop)语句(DDL语句不常用)
- 返回值:实际影响的行数 -> 可以通过行数判断DML是否执行成功( >0成功,否则失败)
ResultSet executeQuery(String sql)
: 执行DQL(select)语句 🌟
ResultSet结果集
封装查询结果
方法:
next() : 游标向下移动一行
getXxx(参数) : 获取数据-(Xxx代表数据类型)
参数:1.Int - 代表列编号(从1开始) 2.String - 代表列的名称
如:int getInt(1) , String getString(“name”)
注意
使用步骤:
- 游标向下移动一行
- 判断是否有数据
获取数据 ```java //3
String sql="select * from account";
//4
stmt = conn.createStatement();
//5
rs = stmt.executeQuery(sql);
//6
//游标向下移动
while(rs.next()){
//循环判断游标是否是最后一行末尾
//获取数据
int id = rs.getInt(1);
String name = rs.getString("name");
double balance = rs.getDouble(3);
System.out.println(id +"---"+name+"---" +balance);
}
//注意关闭ResultSet对象资源 if(rs!=null){ try { rs.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } }
<a name="aAvzz"></a>
#### PreparedStatement
执行sql的对象<br />**1.SQL注入问题:**<br />1.输入错误的用户名和密码,但是密码为: a' or 'a' = 'a<br />那么判断用户名和密码的sql语句就变成了"select * from user where username = 'xxx' and password = 'a' or 'a' = 'a' "<br />成为了恒等式,则可以直接登陆成功<br />**2.结果SQL注入问题:**<br />使用PreparedStatement对象<br />预编译的SQL:参数使用?作为占位符<br />步骤:<br />1.导入jar包<br />2.注册驱动<br />3.获取数据库连接对象Connection<br />4.定义sql<br />注意:sql参数使用?作为占位符,如:select * from user where username = ? and password = ?<br />5.获取执行sql语句的对象 PreparedStatement<br />Connection.prepareStatement(String sql) 这里提前传递sql语句<br />6.给?赋值
- 方法:setXxx(参数1,参数2):
- 参数1为?位置,参数2为?的值
7.执行sql,接收返回结果<br />不需要传递sql语句<br />8.处理结果<br />9.释放资源<br />**注意:后期都会使用PreparedStatement来完成增删改查的所有操作**
<a name="6xWbF"></a>
### 例子
<a name="7xPXQ"></a>
#### insert语句
标准格式代码写法**(try..catch..finally)**
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class DMLtest {
public static void main(String[] args) {
//提前创建对象方便finally关闭资源
Statement stmt= null;
Connection conn =null;
//1.注册驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//2.定义sql
String sql = "insert into account values(null,'王武',3000)";
//3 获取Connection对象
conn = DriverManager.getConnection("jdbc:mysql:///javaSQL", "root", "*******");
//4 获取执行sql的对象 Statement
stmt = conn.createStatement();
//5 执行sql
int count = stmt.executeUpdate(sql); //count结果为影响的行数
//6 处理结果
System.out.println(count);
if(count >0){
System.out.println("添加成功");
}else{
System.out.println("添加失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//7 释放资源
//避免 url、账号、密码错误造成的空指针异常
if(stmt !=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn !=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
select语句
练习:
定义一个方法,查询表的数据将其封装为对象,然后装载集合,返回
1.定义Data类
2.定义方法 public List findAll( ){ }
3.实现方法 select * from account;
public class Data {
private int id;
private String name;
private double balance;
//这里参略GetSet以及toString方法...
}
public class JDBCDemo01 {
public static void main(String[] args) {
List<Data> list= new JDBCDemo01().findAll();
System.out.println(list);
System.out.println(list.size());
}
//查询所有Data对象的方法
public List<Data> findAll(){
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
List<Data> list=null;
//1.注册驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
conn = DriverManager.getConnection("jdbc:mysql:///javaSQL", "root", "luoyu-3-233");
//3.定义sql
String sql="select * from account";
//4.获取执行sql的对象
stmt= conn.createStatement();
//5.执行sql->获取结果集
rs = stmt.executeQuery(sql);
//6.遍历结果集,封装对象,装载集合
Data data=null;
list=new ArrayList<Data>();
while (rs.next()) {
//获取数据
int id = rs.getInt("id");
String name = rs.getString("name");
double balance = rs.getDouble("balance");
//创建data对象
data=new Data();
data.setId(id);
data.setName(name);
data.setBalance(balance);
//装载集合
list.add(data);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
return list;
}
}
JDBCUtils
抽取JDBC工具类:JDBCUtils
目的:简化书写
分析:
1.抽取注册驱动
2.抽取一个方法获取连接对象
需求:不用传递参数,保证工具类的通用性
方案:配置文件
jdbc.properties
url=
user=
password=
3.抽取一个方法注册资源
创建一个配置文件,将连接数据库所需的东西存入其中
url=jdbc:mysql:///javaSQL
user=root
password=******
driver=com.mysql.cj.jdbc.Driver
写一个JDBCUtils文件简化书写
/**
*
* 为了简化代码的书写,将注册驱动、连接对象以及关闭资源写入工具类中方便平时书写的简便性和效率
*/
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("src/jdbc.properties");
// String path = res.getPath();
// System.out.println(path);
//这里在使用ClassLoader的时候遇到报错NoClassDefFoundError错误,导致Demo2无法调用JDBCUtils,暂未解决
//2.加载文件
pro.load(new FileReader("/Users/roderickkk/学习/Java代码/Java-project/JDBCcode/src/jdbc.properties"));
//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 e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接的方法
* @return 连接对象
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
/**
* 释放资源
* @param stmt
* @param conn
*/
public static void close(Statement stmt, Connection conn){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 释放资源
* @param rs
* @param stmt
* @param conn
*/
public static void close(ResultSet rs, Statement stmt, Connection conn){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
最后在例子-select语句中使用JDBCUtils类简化操作成功
注册登陆
需求:
1.通过键盘录入用户名和密码
2.判断用户是否登陆成功
select * from user where username =”” and passowrd =””;
如果这个sql有查询结果则成功,反之失败
步骤:
1.创建数据库表 user
2.创建一个类
/**
* 登陆注册练习
*/
public class JDBCDemo03 {
public static void main(String[] args) {
//1.键盘录入,接收用户名密码
Scanner sc=new Scanner(System.in);
System.out.println("用户名:");
String username = sc.nextLine();
System.out.println("密码:");
String password = sc.nextLine();
//2 调用方法
boolean flag = new JDBCDemo03().login(username, password);
//3 判断结果输出不同语句
if(flag){
//登陆成功
System.out.println("登陆成功");
}else {
System.out.println("用户名或密码错误");
}
}
/**
* 登陆方法
*/
public boolean login(String username,String password){
if(username==null && password==null){
return false;
}
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//2.定义sql
String sql="select * from user where username = '"+username+"' and password = '" +password+"' ";
//3.获取执行sql的对象
stmt = conn.createStatement();
//4.执行查询
rs = stmt.executeQuery(sql);
//5.判断
return rs.next();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JDBCUtils.close(rs,stmt,conn);
}
return false;
}
}
JDBC控制事务
事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败
操作:
- 开启事务
- 提交事务
- 回滚事务
使用Connection对象管理事务
- 开启事务:
void setAutoCommit(boolean autoCommit)
:调用该方法设置参数为false,即开启事务 - 提交事务:
commit()
回滚事务:
rollback()
注意:在Catch中进行回滚 -> 一旦出现异常则回滚事务 ```java /**
- 事务操作 / public class JDBCDemo04 {
public static void main(String[] args) {
Connection conn= null; PreparedStatement pstmt1 = null; PreparedStatement pstmt2 = null; try {
//1.获取连接 conn = JDBCUtils.getConnection(); //开启事务 conn.setAutoCommit(false);
//2 定义sql
String sql1="update account set balance = balance - ? where id = ?";
String sql2="update account set balance = balance + ? where id = ?";
//3 获取执行sql对象
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
//4 设置参数
pstmt1.setDouble(1,500);
pstmt1.setInt(2,1);
pstmt2.setDouble(1,500);
pstmt2.setInt(2,2);
//5 执行sql
pstmt1.executeUpdate();
//手动制造异常
int i =3/0;
pstmt2.executeUpdate();
//提交事务
conn.commit();
} catch (Exception throwables) {
try {
//回滚事务
if(conn!=null){
conn.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
}finally {
JDBCUtils.close(pstmt1,conn);
JDBCUtils.close(pstmt2,null);
}
}
} ```