1.
JDBC 是一套接口(规范) 那各个厂商想要让java语言去操作他们的数据库,必须实现这套接口
厂商写的一套实现类 我们叫做 数据库驱动
2.
获取Connection对象:
Connection conn = DriverManager.getConnection(url,user,password);
url:访问数据库的路径
jdbc: mysql:// 192.168.3.100: 3306 /day
主协议 子协议 ip地址 端口号 数据库名称
* 细节:如果连接的是本地的数据库, 则ip和端口可以省略
jdbc:mysql:///day04
3.
Connection:数据库连接对象
* 创建执行sql的对象
* createStatement:创建Statement对象
* prepareStatement:创建preparedStatement对象
* 可以防止sql注入,提高执行效率
* prepareCall: 创建preparedCall对象
* 执行存储过程的
4.
Statement:执行sql的对象
* executeUpdate(sql):执行DML语句 (增、删、改)
* 返回值:int,代表影响的行数
* executeQuery(sql):执行DQL语句 (查询)
* 返回值:ResultSet对象 结果集对象,对结果集的封装
* execute(sql):执行任意语句
* 返回值:boolean,执行成功与否
5.
PreparedStatement:执行sql的对象
* 登陆:
如果使用statement,可能发生sql注入。
* 功能:
* 预防sql注入
* 使用方式:
1.定义sql时,所有的参数位置 需要 使用 ? 作为占位符
2.Connection对象获取执行sql 对象 prepareStatement(sql)
3.给占位符 ? 赋值
* setXxx(参数1,参数2):
* 参数1:?出现的位置 从1开始
* 参数2:?对应的值
4.执行sql时,使用不带参数的方法
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
6.预编译 查询表 抽取工具类
工具类
7.
读取表中的数据
8.防止sql注入 采取预编译
9.事件(以银行转账为例)
现在制造一个异常来模拟:当张三将钱转出去,服务器发生异常,强制终止
这时候会发现zs转账过去了 但ls并没有收到 这时引入 事件
基本概念:
事务使指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。
事务ACID特性
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
事务的特性:
原子性,是一个最小逻辑操作单元 !
一致性,事务过程中,数据处于一致状态。
持久性, 事务一旦提交成功,对数据的更改会反映到数据库中。
隔离性, 事务与事务之间是隔离的。
针对上述服务器异常问题 就需要 回滚来解决
Connection SetAutoCommit(boolean b):开启事物,默认为true,b=false则开启事物
Connection rollback():回滚事物到初始状态(当程序运行异常,张三李四账户余额不变 所以是在异常处抓一下)
Connection commit():提交事物
当服务器发生异常 数据会回滚到最原始
需要设置一个回滚点 Connection setSavepoint():
在两次之间设置一个回滚点 Connection rollback(Connection setSavepoint()):回滚到回滚点上(即回滚到第一次转账结束后)
JDBC 是一套接口(规范) 那各个厂商想要让java语言去操作他们的数据库,必须实现这套接口
厂商写的一套实现类 我们叫做 数据库驱动
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCtest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.导入数据数据库包 jar包
//2 加载驱动jar包
Class.forName("com.mysql.jdbc.Driver");
//3 获取一个数据库连接对象 参数1:数据库的路径 参数2,3 数据库的用户名和密码
String url = "jdbc:mysql:///mydb_01";
String user = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, user, password);
//4 通过连接对象获取操作对象
Statement statement = conn.createStatement();//用于执行静态 SQL 语句并返回它所生成结果的对象。
// statement是一个接口
//5定义sql语句
String sql = "insert into tescher values(3,'rrr','333')";
//6执行语句
int i = statement.executeUpdate(sql);//返回此语句改变的行数
if(i!=0){
System.out.println("成功");
}else{
System.out.println("失败");
}
//7释放资源
conn.close();
statement.close();
}
}
2.
获取Connection对象:
Connection conn = DriverManager.getConnection(url,user,password);
url:访问数据库的路径
jdbc: mysql:// 192.168.3.100: 3306 /day
主协议 子协议 ip地址 端口号 数据库名称
* 细节:如果连接的是本地的数据库, 则ip和端口可以省略
jdbc:mysql:///day04
3.
Connection:数据库连接对象
* 创建执行sql的对象
* createStatement:创建Statement对象
* prepareStatement:创建preparedStatement对象
* 可以防止sql注入,提高执行效率
* prepareCall: 创建preparedCall对象
* 执行存储过程的
4.
Statement:执行sql的对象
* executeUpdate(sql):执行DML语句 (增、删、改)
* 返回值:int,代表影响的行数
* executeQuery(sql):执行DQL语句 (查询)
* 返回值:ResultSet对象 结果集对象,对结果集的封装
* execute(sql):执行任意语句
* 返回值:boolean,执行成功与否
5.
PreparedStatement:执行sql的对象
* 登陆:
如果使用statement,可能发生sql注入。
* 功能:
* 预防sql注入
* 使用方式:
1.定义sql时,所有的参数位置 需要 使用 ? 作为占位符
2.Connection对象获取执行sql 对象 prepareStatement(sql)
3.给占位符 ? 赋值
* setXxx(参数1,参数2):
* 参数1:?出现的位置 从1开始
* 参数2:?对应的值
4.执行sql时,使用不带参数的方法
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
6.预编译 查询表 抽取工具类
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBC03 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//拷贝JAR包
//加载驱动
//Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
//Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb_01", "root", "root");
//通过连接对象获取预编译操作对象
Connection conn = JDBCutils.getConnection();
String sql = "select * from tescher where id = ?";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setInt(1, 3);// 给问号赋值 第一个参数:id位于表中的第几个参数 第二个参数:?的值 Int表示?的类型
//执行sql语句
ResultSet resultSet = statement.executeQuery();
while(resultSet.next()){//如果查到了 光标将发生跳转 返回值变为true
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String sex = resultSet.getString(3);
System.out.println(id+name+sex);
}
// conn.close();
// statement.close();
// resultSet.close();
JDBCutils.close(conn, statement, resultSet);
}
}
工具类
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCutils {
//全局变量
public static String url;
public static String user;
public static String password;
//静态代码块
static{
url = "jdbc:mysql:///mydb_01";
user = "root";
password = "root";
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//不让外界创建对象 私有构造(外界只能通过类名.方法名 来使用)
private JDBCutils(){
super();
}
//返回连接对象
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url, user, password);
}
//关闭资源
public static void close(Connection conn ,Statement statement , ResultSet result ) throws SQLException{
if(conn != null){
conn.close();
}
if(statement!= null){
statement.close();
}
if(result!= null){
result.close();
}
}
//要是有的没有用到结果集(ResultSet) 这时候就需要方法重载
public static void close(Connection conn, Statement statement) throws SQLException{
if(conn!=null){
conn.close();
}
if(statement!=null){
statement.close();
}
}
}
7.
读取表中的数据
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
public class JDBC02 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//导入驱动JAr包
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取链接对象
Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb_01", "root", "root");
//通过连接对象获取操作对象
Statement statement = conn.createStatement();
//定义sql语句
String sql = "select * from tescher";
//executeUpdate(sql):执行DML语句 (增、删、改) 返回值:int,代表影响的行数
//executeQuery(sql):执行DQL语句 (查询) 返回值:ResultSet对象 结果集对象,对结果集的封装
//execute(sql):执行任意语句 返回值:boolean,执行成功与否
//执行sql语句
ResultSet resultSet = statement.executeQuery(sql);
//创建集合来存储读取到的数据 然后输出遍历
ArrayList<User> list = new ArrayList<User>();
//boolean b = resultSet.next();//返回值是用来判断是否还有下一行
while(resultSet.next()){//在结果集里面 按照顺序下移一行
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String sex = resultSet.getString(3);
User user = new User(id,name,sex);//从数据库里面取出数据 是想使用这些数据 先封装到对象 再把每个对象 装到集合里
list.add(user);
}
//遍历集合
System.out.println(list);
//释放资源
conn.close();
statement.close();
resultSet.close();
}
}
8.防止sql注入 采取预编译
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class JDBC04 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入姓名");
String username = sc.next();
System.out.println("请输入密码");
String password = sc.next();
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb_01", "root", "root");
//定义sql语句 通配符?代替数据
String sql = "select * from 登陆表格 where username = ? and password = ? ";
//获取预编译操作对象
PreparedStatement statement = conn.prepareStatement(sql);
//给通配符赋值 参数1为?在表中的位置 参数2为?的值
statement.setString(1, username);
statement.setString(2, password);
//执行sql语句
ResultSet resultSet = statement.executeQuery();
if(resultSet.next()){
System.out.println("登陆成功");
}
else{
System.out.println("登陆失败");
}
//释放资源
resultSet.close();
statement.close();
conn.close();
}
}
9.事件(以银行转账为例)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import JDBC03.JDBCutils;
//zs给ls转账100
public class jdbc05 {
public static void main(String[] args) throws Exception {
//获取连接对象
Connection conn = JDBCutils.getConnection();
//定义sql语句
String sql1 = "update bank set money=money-100 where username = ?";//转出
String sql2 = "update bank set money=money+100 where username = ?";//转入
//获取预编译对象
PreparedStatement statement1 = conn.prepareStatement(sql1);
PreparedStatement statement2 = conn.prepareStatement(sql2);
//给?赋值 参数1为username在表中的位置 参数2为?的值
statement1.setString(1, "zs");
statement2.setString(1, "ls");
//执行sql语句
statement1.execute();
statement2.execute();
//释放资源
JDBCutils.close(conn, statement1);
JDBCutils.close(conn, statement2);
}
}
现在制造一个异常来模拟:当张三将钱转出去,服务器发生异常,强制终止
//执行sql语句
statement1.execute();
//人为加一个异常
System.out.println(1/0);
statement2.execute();
这时候会发现zs转账过去了 但ls并没有收到 这时引入 事件
基本概念:
事务使指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。
事务ACID特性
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
事务的特性:
原子性,是一个最小逻辑操作单元 !
一致性,事务过程中,数据处于一致状态。
持久性, 事务一旦提交成功,对数据的更改会反映到数据库中。
隔离性, 事务与事务之间是隔离的。
针对上述服务器异常问题 就需要 回滚来解决
Connection SetAutoCommit(boolean b):开启事物,默认为true,b=false则开启事物
Connection rollback():回滚事物到初始状态(当程序运行异常,张三李四账户余额不变 所以是在异常处抓一下)
Connection commit():提交事物
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import JDBC03.JDBCutils;
//zs给ls转账100
public class jdbc05 {
public static void main(String[] args) throws Exception {
//建立连接
Connection conn = JDBCutils.getConnection();
//开启事务
conn.setAutoCommit(false);
//定义sql语句
String sql1 = "update bank set money=money-100 where username = ?";//转出
String sql2 = "update bank set money=money+100 where username = ?";//转入
//获取预编译对象
PreparedStatement statement1 = conn.prepareStatement(sql1);
PreparedStatement statement2 = conn.prepareStatement(sql2);
//给?赋值 参数1为username在表中的位置 参数2为?的值
statement1.setString(1, "zs");
statement2.setString(1, "ls");
try {
//执行sql语句
statement1.execute();
//人为加一个异常
System.out.println(1/0);
statement2.execute();
} catch (Exception e) {
//一旦发生异常 回滚到最初状态
conn.rollback();
}finally{
//提交事务
conn.commit();
}
//释放资源
JDBCutils.close(conn, statement1);
JDBCutils.close(conn, statement2);
}
}
当服务器发生异常 数据会回滚到最原始
10.事物回滚点
需要设置一个回滚点 Connection setSavepoint():
在两次之间设置一个回滚点 Connection rollback(Connection setSavepoint()):回滚到回滚点上(即回滚到第一次转账结束后)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import JDBC03.JDBCutils;
//zs给ls转账100
public class jdbc05 {
public static void main(String[] args) throws Exception {
Savepoint savepoint = null;
//建立连接
Connection conn = JDBCutils.getConnection();
//开启事务
conn.setAutoCommit(false);
//定义sql语句
String sql1 = "update bank set money=money-100 where username = ?";//转出
String sql2 = "update bank set money=money+100 where username = ?";//转入
//获取预编译对象
PreparedStatement statement1 = conn.prepareStatement(sql1);
PreparedStatement statement2 = conn.prepareStatement(sql2);
//给?赋值 参数1为username在表中的位置 参数2为?的值
statement1.setString(1, "zs");
statement2.setString(1, "ls");
try {
//执行sql语句
//第一次转账(正常)
statement1.execute();
statement2.execute();
//在第一次和第二次转账之间设置回滚点
savepoint = conn.setSavepoint();
//第二次转账(异常)
statement1.execute();
//人为加一个异常
System.out.println(1/0);
statement2.execute();
} catch (Exception e) {
//一旦发生异常 回滚到设置的回滚点
conn.rollback(savepoint);
}finally{
//提交事务
conn.commit();
}
//释放资源
JDBCutils.close(conn, statement1);
JDBCutils.close(conn, statement2);
}
}