ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JDBC小结

2022-08-10 20:01:05  阅读:134  来源: 互联网

标签:JDBC java String System sql import password 小结


JDBC简介

  • JDBC 全称为Java DataBase Connectivity(Java语言连接数据库)
  • JDBC是SUN公司制定的一套接口(interface)。

    接口都有调用者和实现者。

    面向接口调用、面向接口写实现类,这都属于面向接口编程

  • JDBC之所以要面向接口编程,是因为解耦合:降低程序的耦合度,提高程序的扩展力。多态机制就是非常典型的:面向抽象编程。(不要面向具体编程)

     

  • 因为每一个数据库产品都有自己独特的实现原理,所以不同数据库产品之间需要一个类似桥梁的JDBC接口用来实现操作数据库
  • JDBC编程六步
  1. 注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
  2. 获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)
  3. 获取数据库操作对象(专门执行sql语句的对象)
  4. 执行SQL语句(DQL,DML…)
  5. 处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
  6. 释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)

 

 

 

 

 

IDEA编写JDBC连接MySQL

mysql-connector-java的不同版本对比

MySQL Connector / J 5.1 5.1版本支持java5及其以上的版本,支持5.6、5.7、8.0版本的mysql数据库,支持3.0、4.0、4.1、4.2版本的jdbc。在5.1中,Driver的实现类的全路径名是com.mysql.jdbc.Driver。

MySQL Connector / J 8.0 8.0版本支持java8及其以上的版本,支持5.6、5.7、8.0版本的mysql数据库,支持4.2版本的jdbc。在8.0中,Driver的实现类的全路径名是com.mysql.cj.jdbc.Driver。

下图是官网上mysql-connector-java的版本对应的mysql版本和jdk的版本。

 

下载驱动jar包 mysql-connector-java

要使用mysql连接器,就要先下载它。如果是一般的项目,那我们需要下载jar包,然后放到项目的lib目录下。如果使用maven构建的项目,我们可以通过maven直接安装。不同的下载方式有不同的操作,常见的有直接官网下载和maven下载(下周讲解maven)。 下载jar包最直接的方式是从官网下载,官网地址是:https://dev.mysql.com/downloads/connector/j/。直接点链接进入mysql官网,选择所需的版本和操作系统(要下载jar包就要选:Platform Independent),然后点击download按钮就可以下载了。为java提供的连接器是Connector / J,也就是mysql-connector-java,它分为5.1版本和8.0版本。Connector / J实现了JDBC,为使用java开发的程序提供连接,方便java程序操作数据库。

 

 

2、从maven安装 使用maven安装mysql-connector-java就简单很多,直接打开maven的中央仓库地址,输入mysql-connector-java就可以找到不同版本的依赖。地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java

 

 

6.3 IDEA导入jar包

先检查jar包位置:在目录里新建一个文件夹 libs,把jar包复制进去

 

然后右键选择新建文件夹libs转成library

 

然后就可以写代码啦!

根据六步编写代码:先不写处理代码

 

6.4 JDBC连接mysql 程序编写

6.5.1 第一种注册驱动方式
package com.shujia.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import com.mysql.jdbc.Driver;

/*
       1.注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
       2.获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
       3.获取数据库操作对象(专门执行sql语句的对象)
       4.执行SQL语句(DQL,DML…)
       5.处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
       6.释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)


       工具类:DriverManager
          没有构造方法(构造方法私有化),方法是静态的。
*/
public class JDBCTest1 {
   private static Statement stat;
   private static Connection conn;


   public static void main(String[] args) {
       //1.注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
       //第一种注册驱动的方式
       //jdk自己提供了一个工具类DriverManager给我们使用,其中有一个静态的方法registerDriver()可以实现注册驱动功能
       //static void registerDriver(Driver driver)
       //注册与给定的驱动程序 DriverManager 。
       //而jdkapi文档中发现,Driver是一个接口,而接口是不能直接实例化的
       //这里要想传入一个Driver的对象,就必须找到一个对应的实现类
       //我们现在是要使用mysql的驱动,所以就猜测mysql的驱动包中应该有一个类实现了jdk提供的Driver接口
       try {
           DriverManager.registerDriver(new Driver());
           //2.获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
           //jdk自身提供的工具类DriverManager中有一个静态方法,可以让我们调用并且获取与数据库的连接
           //static Connection getConnection(String url, String user, String password)
           //尝试建立与给定数据库URL的连接。
           /**
            *     url: 统一资源定位系统
            *         http/https: 通过网络请求去访问网络上的资源
            *         jdbc:mysql: 是驱动提供的请求头
            *         请求的地址: 指定mysql的服务器地址:192.168.254.150
            *         端口号: 3306
            *         useUnicode=true&characterCharset=utf8
            *
            *     jdbc:mysql://192.168.254.150:3306?useUnicode=true&characterCharset=utf8
            *
            *     user: 用户名 root
            *     password: 密码 123456
            */
           //在mysql5.7+版本不建议使用连接直接访问服务器
           String url = "jdbc:mysql://192.168.254.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false";
           String user = "root";
           String password = "123456";
           conn = DriverManager.getConnection(url, user, password);
           System.out.println("与mysql建立连接成功:"+conn); //com.mysql.jdbc.JDBC4Connection@7d9d1a19

           //3.获取数据库操作对象(专门执行sql语句的对象)
           stat = conn.createStatement();

           //4.执行SQL语句(DQL,DML…)
           //DQL
           //ResultSet executeQuery(String sql)
           //执行给定的SQL语句,该语句返回单个 ResultSet对象。

           //DML
           //int executeUpdate(String sql)
           //执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。
           // 方法的返回值指的是受影响的行数: Affected rows: 1
           int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(70,'教学部','安徽合肥')");
           if(count==1){
               System.out.println("数据保存成功!!");
          }else {
               System.out.println("数据保存失败!!");
          }
      } catch (SQLException e) {
           e.printStackTrace();
      }finally {
           //释放资源的代码
           if(stat!=null){
               try {
                   stat.close();
              } catch (SQLException e) {
                   e.printStackTrace();
              }
          }

           if(conn!=null){
               try {
                   conn.close();
              } catch (SQLException e) {
                   e.printStackTrace();
              }
          }
      }

  }
}

 

6.5.2 第二种注册驱动方式
package com.shujia.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/*
       注册驱动的第二种方式:
           正常情况下,我们今后遇到的数据库肯定不止mysql一种,但是呢,使用java连接数据库的方式却大同小异,无非是内部的实现不一样
           如果按照上午所说的那样注册驱动的话,上午的程序案例只能连接mysql的驱动,将来如果想换成sqlserver的话还不太好换
           想一想,我们之前在安装jdk的过程在配置环境变量的时候,有一步我们可以借鉴它的思想
           所以,我们在这里注册驱动的时候,能不能传入字符串呢?

      注册驱动底层实际上就是用驱动包中对应的类,而驱动包中的类都是class后缀的编译好的文件
      要想直接使用编译好的类,使用反射来实现。
      想一想,反射是如何获取一个类的class文件对象呢?3种方式
      1、getClass
      2、.class
      3、Class.forName()
*/
public class JDBCTest2 {
   public static void main(String[] args) {
       Connection conn = null;
       Statement stat = null;

       try {
           //1、加载驱动
           //第二种方式来实现
           Class.forName("com.mysql.jdbc.Driver");

           //2、创建与数据库的连接对象
           String url = "jdbc:mysql://192.168.254.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=False";
           String username = "root";
           String password = "123456";
           conn = DriverManager.getConnection(url, username, password);

           //3、获取与操作数据库的对象
           stat = conn.createStatement();

           //4、编写sql语句并执行
           //增
//           String sql = "insert into students(sno,sname,sgender,sage,sclass) values('110','小虎','男',18,'19独立营')";
//           int count = stat.executeUpdate(sql);
//           System.out.println(count==1?"数据保存成功!!":"数据保存失败!!");

           //改
//           String sql3 = "update students set sname='李凯迪' where sno='110'";
//           int count3 = stat.executeUpdate(sql3);
//           System.out.println(count3==1?"数据更新成功!!":"数据更新失败!!");
//
           //删
           String sql2 = "delete from students where sno='110'";
           int count2 = stat.executeUpdate(sql2);
           System.out.println(count2==1?"数据删除成功!!":"数据删除失败!!");


      } catch (Exception e) {
           e.printStackTrace();
      }finally {
           //释放资源
           if(stat!=null){
               try {
                   stat.close();
              } catch (SQLException e) {
                   e.printStackTrace();
              }
          }

           if (conn!=null){
               try {
                   conn.close();
              } catch (SQLException e) {
                   e.printStackTrace();
              }
          }
      }
  }
}

 

6.5.3 将连接数据库的所有信息配置到配置文件中
package com.shujia.jdbc;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Properties;

/*
       使用配置文件将连接数据库的相关参数进行保存,然后在代码中使用
       使用jdk自身提供的Properties类来加载配置文件

       IO流:
           字节流
               字节输入流
               字节输出流
           字符流 = 字符转换流 = 字节流+编码表
               字符输入流
               字符输出流

      相对路径:将项目作为根目录
      绝对路径/完整路径:带盘符的路径
*/
public class JDBCTest3 {
   public static void main(String[] args) throws Exception {
       //使用无参构造方法创建Properties类的对象
       Properties prop = new Properties();

       //使用字符流读取配置文件
//       InputStreamReader , FileReader, BufferedReader
       BufferedReader br = new BufferedReader(new FileReader("E:\\projects\\IdeaProjects\\bigdata19-mysql\\resource\\jdbc.properties"));
       prop.load(br);

       String driver = prop.getProperty("driver");
       String url = prop.getProperty("url");
       String username = prop.getProperty("username");
       String password = prop.getProperty("password");

       //加载驱动
       Class.forName(driver);
       //获取连接对象
       Connection conn = DriverManager.getConnection(url, username, password);

       //获取数据库操作对象
       Statement stat = conn.createStatement();

       //执行sql语句
       int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(80,'管理层','安徽合肥')");

       System.out.println(count==1?"数据插入成功!!":"数据插入失败!!");

       //释放资源
       stat.close();
       conn.close();
  }
}

 

6.5.4 处理查询结果集
package com.shujia.jdbc;

import com.shujia.utils.MySqlTool;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

/*
   使用jdbc查询数据库中的数据
*/
public class JDBCTest5 {
   public static void main(String[] args) throws Exception {
       //获取与数据库的连接对象
       //使用工具类的方式进行获取
       Connection conn = MySqlTool.init();

       //获取数据库操作对象
       Statement stat = conn.createStatement();

       //需求:查询dept表中的所有数据
       //查询sql语句中,把要查询的列进行罗列出来
       ResultSet resultSet = stat.executeQuery("select deptno as a1,dname,loc from dept");
       //boolean next()
       //将光标从当前位置向前移动一行。
       //这里的光标可以理解为集合中的光标
//       boolean b = resultSet.next();
//       //如果光标移动的位置有值,这里的返回值是true
//       if(b){
//           //获取一行中每一列的数值,第一种方式
//           //String getString(int columnIndex)
//           //这个检索的当前行中指定列的值 ResultSet对象为 String的Java编程语言。
//           //columnIndex从1开始,1表示一行中的第一列,以此类推
//           String deptno = resultSet.getString(1);
//           String dname = resultSet.getString(2);
//           String loc = resultSet.getString(3);
//           System.out.println("部门编号:"+deptno+",部门名称:"+dname+",地址:"+loc);
//       }

       //正常情况下,一张结果表的行数我们不确定,但是我们知道,当next的结果是false的时候,表示读取到末尾
       //使用while循环
       while (resultSet.next()) {
//           //获取一行中每一列的数值,第一种方式
//           //String getString(int columnIndex)
//           //这个检索的当前行中指定列的值 ResultSet对象为 String的Java编程语言。
//           //columnIndex从1开始,1表示一行中的第一列,以此类推
//           String deptno = resultSet.getString(1);
//           String dname = resultSet.getString(2);
//           String loc = resultSet.getString(3);
//           System.out.println("部门编号:" + deptno + ",部门名称:" + dname + ",地址:" + loc);

           //第二种方式:根据列名获取对应的列值
           //String getString(String columnLabel)
           //这个检索的当前行中指定列的值 ResultSet对象为 String的Java编程语言。
           //注意事项:当查询sql语句中存在起别名的情况时,通过列名获取列值的时候,使用名字是别名
           String deptno = resultSet.getString("a1");
           String dname = resultSet.getString("dname");
           String loc = resultSet.getString("loc");
           System.out.println("部门编号:" + deptno + ",部门名称:" + dname + ",地址:" + loc);
      }
       System.out.println("==================================================================");

       //注意事项2:同一个结果resultSet对象,只能遍历一次
//       while (resultSet.next()) {
////           //获取一行中每一列的数值,第一种方式
////           //String getString(int columnIndex)
////           //这个检索的当前行中指定列的值 ResultSet对象为 String的Java编程语言。
////           //columnIndex从1开始,1表示一行中的第一列,以此类推
////           String deptno = resultSet.getString(1);
////           String dname = resultSet.getString(2);
////           String loc = resultSet.getString(3);
////           System.out.println("部门编号:" + deptno + ",部门名称:" + dname + ",地址:" + loc);
//
//           //第二种方式:根据列名获取对应的列值
//           //String getString(String columnLabel)
//           //这个检索的当前行中指定列的值 ResultSet对象为 String的Java编程语言。
//           //注意事项:当查询sql语句中存在起别名的情况时,通过列名获取列值的时候,使用名字是别名
//           String deptno = resultSet.getString("a1");
//           String dname = resultSet.getString("dname");
//           String loc = resultSet.getString("loc");
//           System.out.println("部门编号:" + deptno + ",部门名称:" + dname + ",地址:" + loc);
//       }
       
       


       //释放资源
       stat.close();
       conn.close();


  }
}

登录注册案例
package com.shujia.jdbc;

/*
       使用JDBC模拟登录注册案例
       1、注册账号:往数据库插入一条数据
       2、登录账号:查询数据库

       实现步骤:
           1、建表
*/
import com.shujia.utils.MySqlTool;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
import java.util.UUID;

public class JDBCTest6 {
   public static void main(String[] args) throws Exception {
       System.out.println("欢迎进入小虎婚介所");
       //创建键盘录入对象
       Scanner sc = new Scanner(System.in);
       System.out.println("请输入用户名:");
       String username = sc.next();
       System.out.println("请输入密码:");
       String password = sc.next();

       //使用工具类获取与数据库的连接对象
       Connection conn = MySqlTool.init();
       //获取数据库操作对象
       Statement stat = conn.createStatement();

       //编写sql语句
       String sql = "select username,password from user where username='"+username+"' and password='"+password+"'";
       //           select username,password from user where username='root' and password='123456'
       //执行sql语句
       ResultSet rs = stat.executeQuery(sql);
       boolean b = rs.next();
       if(b){
           //如果b为true表示,数据库中存在该用户,登录成功
           System.out.println("登录成功!!欢迎进入小虎婚介所!!");
      }else {
           //如果b为false,表示该用户还没有注册,需要先进行注册
           System.out.println("您还未注册,请先注册(Y/N)");
           String choice = sc.next();
           if("Y".equals(choice)){
               while (true){
                   System.out.println("请输入您的用户名:");
                   String new_username = sc.next();
                   System.out.println("请输入您设置的密码:");
                   String new_password = sc.next();
                   System.out.println("请确认密码:");
                   String password_again = sc.next();
                   if(password_again.equals(new_password)){
                       UUID uuid = UUID.randomUUID();
                       String new_uuid = uuid+"-"+System.currentTimeMillis();
                       String sql2 = "insert into user(uid,username,password) values('"+new_uuid+"','"+new_username+"','"+new_password+"')";
                       int count = stat.executeUpdate(sql2);
                       if(count==1){
                           System.out.println("用户注册成功!!!");
                      }else {
                           System.out.println("用户注册失败!!!");
                      }
                       break;
                  }else {
                       System.out.println("两次密码不一致!!请重新输入");
                  }
              }
          }
      }

       //释放资源
       stat.close();
       conn.close();


  }
}

 

6.5.6 解决sql注入问题
package com.shujia.jdbc;

/*
       使用JDBC模拟登录注册案例
       1、注册账号:往数据库插入一条数据
       2、登录账号:查询数据库

       实现步骤:
           1、建表

           1234' or '1'='1

       我们写完程序后发现,当我们将密码输入成1234' or '1'='1这个样子的时候,发现登录成功
       原因:sql在编译的时候,会将我们输入的内容存在关键字or,会把or当作sql语法关键字进行执行
       如何解决呢?
           这样的问题,称之为sql注入的问题
           解决的思路就是在sql编译完后再传入数据

      获取数据库操作对象另外一种方式,预编译的方式

*/
import com.shujia.utils.MySqlTool;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
import java.util.UUID;

public class JDBCTest6 {
   public static void main(String[] args) throws Exception {
       System.out.println("欢迎进入小虎婚介所");
       //创建键盘录入对象
       Scanner sc = new Scanner(System.in);
       System.out.println("请输入用户名:");
       String username = sc.nextLine();
       System.out.println("请输入密码:");
       String password = sc.nextLine();

       //使用工具类获取与数据库的连接对象
       Connection conn = MySqlTool.init();
       //获取数据库操作对象
//       Statement stat = conn.createStatement();



       //编写sql语句
//       String sql = "select username,password from user where username='"+username+"' and password='"+password+"'";
       //           select username,password from user where username='root' and password='123456'
       //           select username,password from user where username='xiaohu' and password='1234' or '1'='1'

//       System.out.println(sql);


       //这里的问号相当于一个占位符,为了后面传值
       String sql = "select username,password from user where username=? and password=?";
       //创建预编译数据库操作对象
       PreparedStatement pps = conn.prepareStatement(sql);
       //将sql中的占位符附上值
       //第一个参数表示给第几个问号传值,第二个参数表示具体的值,序号从1开始
       pps.setString(1,username);
       pps.setString(2,password);


       //执行sql语句
//       ResultSet rs = stat.executeQuery(sql);
       ResultSet rs = pps.executeQuery();

       boolean b = rs.next();
       if(b){
           //如果b为true表示,数据库中存在该用户,登录成功
           System.out.println("登录成功!!欢迎进入小虎婚介所!!");
      }else {
           //如果b为false,表示该用户还没有注册,需要先进行注册
           System.out.println("您还未注册,请先注册(Y/N)");
           String choice = sc.next();
           if("Y".equals(choice)){
               while (true){
                   System.out.println("请输入您的用户名:");
                   String new_username = sc.next();
                   System.out.println("请输入您设置的密码:");
                   String new_password = sc.next();
                   System.out.println("请确认密码:");
                   String password_again = sc.next();
                   if(password_again.equals(new_password)){
                       UUID uuid = UUID.randomUUID();
                       String new_uuid = uuid+"-"+System.currentTimeMillis();
                       String sql2 = "insert into user(uid,username,password) values('"+new_uuid+"','"+new_username+"','"+new_password+"')";
//                       int count = stat.executeUpdate(sql2);
                       int count = pps.executeUpdate(sql2);
                       if(count==1){
                           System.out.println("用户注册成功!!!");
                      }else {
                           System.out.println("用户注册失败!!!");
                      }
                       break;
                  }else {
                       System.out.println("两次密码不一致!!请重新输入");
                  }
              }
          }
      }

       //释放资源
//       stat.close();
       pps.close();
       conn.close();


  }
}

 

JDBC事物机制: 1.JDBC中的事务自动提交的,什么是自动提交? 只要执行任意一条 DML语句,则自动提交一次。这是JDBC默认的事务行为。 但是在实际的业务中,通常都是N条DML语句共同联合才能完成,必须 保证这些DML语句在同一个事务中同时成功或者同时失败 解决方案:三行重要的代码 conn.setAutoCommit(false);//手动提交事务 conn.commit();//提交事务 conn.rooback;当发生异常时或者程序错误时,进行回滚。

6.5.7 工具类封装
package com.shujia.utils;


import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

/*
   工具类:
       1、不能让外界实例化(构造方法私有化)
       2、方法必须是静态
*/
public class MySqlTool {
   private static Connection conn;

   private MySqlTool(){}

   public static Connection init(){
       try {
           //使用无参构造方法创建Properties类的对象
           Properties prop = new Properties();

           //使用字符流读取配置文件
//       InputStreamReader , FileReader, BufferedReader
           BufferedReader br = new BufferedReader(new FileReader("E:\\projects\\IdeaProjects\\bigdata19-mysql\\resource\\jdbc.properties"));
           prop.load(br);

           String driver = prop.getProperty("driver");
           String url = prop.getProperty("url");
           String username = prop.getProperty("username");
           String password = prop.getProperty("password");

           //加载驱动
           Class.forName(driver);
           //获取连接对象
           conn = DriverManager.getConnection(url, username, password);
      }catch (Exception e){
           e.printStackTrace();
      }

       return conn;
  }

}

工具类使用

package com.shujia.jdbc;

import com.shujia.utils.MySqlTool;
import java.sql.Connection;
import java.sql.Statement;

public class JDBCTest4 {
   public static void main(String[] args) throws Exception {
       //使用工具类获取连接对象
       Connection conn = MySqlTool.init();

       //获取数据库操作对象
       Statement stat = conn.createStatement();

       //执行sql语句
       int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(90,'行政部','数加科技')");

       System.out.println(count==1?"数据插入成功!!":"数据插入失败!!");

       //释放资源
       stat.close();
       conn.close();
  }
}

 

6.5.8 JDBC实现模糊查询
package com.shujia.jdbc;

import com.shujia.utils.MySqlTool;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/*
        进行模糊查询
 */
public class JDBCTest {
    public static void main(String[] args) throws Exception {
        Connection conn = MySqlTool.init();
        PreparedStatement prep = conn.prepareStatement("select uid,username,password from user where username like ?");
        prep.setString(1, "%xiaohu%");
        ResultSet rs = prep.executeQuery();
        while (rs.next()) {
            String uid = rs.getString("uid");
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println("姓名:" + username + ",密码:" + password);

        }
        prep.close();
        conn.close();
    }
}

 

6.5 悲观锁和乐观锁的概念

事务1–>读取到版本号1.1 事务2—>读取到版本号1.1

其中事务1先修改了,修改之后看了版本号是1.1 ,于是提交修改的数据,将版本号修改为1.2 其中事务2后修改的,修改之后准备提交的时候,发现版本号是1.2 ,和它最初读的版本号不一致。回滚。

悲观锁:事务必须排队执行。数据锁住了,不允许并发。 (行级锁: select后面添加for update ) 乐观锁:支持并发,事务也不需要排队,只不过需要一个版本号。

 

6.6 演示索引的效率(springboot,redis,mysql)

 

 

 

 

 

 

标签:JDBC,java,String,System,sql,import,password,小结
来源: https://www.cnblogs.com/slm-1314521/p/16573714.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有