MYSQL操作详细操作

事物

1. 什么是事物?

要么都成功,要么都失败


1.SQL执行 A 给 B 转账 A 1000 ---->200 B 200

2.SQL执行 B收到A的钱 A 800 -----> B 400


将一组SQL放在一个批次中去执行

事物原则:ACID 原则 原子性(atomicity),一致性(consistency),隔离性(isolation),持久性(durability) (脏读,幻读。。。)

  1. Atomicity(原子性):要么都成功,要么都失败。

  2. 一致性(Consistency):事务前后的数据完整性要保持一致。

  3. 持久性(durability):事务一旦提交则不可逆,被持久化到数据库中!

  4. 隔离性(isolation):事物的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启事务,不能被其他事物的操作数据所干扰之间要相互隔离。

  5. 隔离会导致的问题

    1. 脏读

    2. 不可重复读

    3. 幻读

2.执行事务
-- =========事物==========
-- mysql 是默认开启事物自动提交的

SET autocommit = 0 -- 关闭
SET autocommit = 1 -- 开启

-- 手动处理事务
SET autocommit = 0 -- 关闭自动条件

-- 事务开启
START TRANSACTION -- 标记一个事务开始,从这个之后 sql 都处在同一事务

INSERT xx
INSERT xx

-- 提交,持久化(成功!)
COMMIT
-- 回滚,回到原来的样子(失败)
ROLLBACK


-- 事务结束
SET autocommit = 1 -- 开启自动提交

-- 了解
SAVEPOINT 保存点名 -- 设置一个事务保存点
ROLLBACK TO SAVEPOINT 保存点名 -- 回滚保存点
RELEASE SAVEPOINT 保存点名  -- 撤销保存点

模拟场景:


-- === 模拟转账 ===
INSERT INTO `shop`.`account`(`name`,`money`)VALUES('A',2000.00),('B',10000.00);
-- 模拟转账:事务
SET autocommit = 0; -- 关闭自动提交
START TRANSACTION -- 开启一个事务(一组事务)
UPDATE `shop`.`account` SET `money` = `money` - 500 WHERE `name` = 'A'; -- A减500
UPDATE `shop`.`account` SET `money` = `money` + 500 WHERE `name` = 'B'; -- B加500

COMMIT; -- 提交事务,就被持久化了!
ROLLBACK; -- 回滚

SET autocommit = 1; -- 恢复默认值
3.索引

MySQL官方对索引的定义为:索引 (Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。

  1. 索引的分类

    1. 主键索引(PRIMARY KEY)

      1. 唯一的标识:主键不可重复,只能有一个列作为主键。

    2. 唯一索引(UNIQUE KEY)

      1. 避免面重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引。

    3. 常规索引 ( KEY / INDEX )

      1. 默认的,Index、Key关键字设置

    4. 全文索引( FullText )

      1. 在特定数据库引擎下才有,MYSAM

  2. 基础语法:

    -- 索引的使用
    -- 1、在创建表的时候给字段增加索引
    -- 2、创建完毕后,增加索引

    -- 显示所有的索引信息
    SHOW INDEX FROM `school`.`student`

    -- 增加一个索引
    ALTER TABLE `school`.`student` ADD FULLTEXT INDEX `name`(`name`)

    -- EXPLAIN 分析sql执行的状况
    EXPLAIN SELECT * FROM `school`.`student` -- 非全文索引

    EXPLAIN SELECT * FROM `school`.`student` WHERE MATCH(`name`) AGAINST ('yi')
4.测试索引
 INSERT INTO `school`.`app_user`(`name`,`email`,`phone`,`gender`,`password`,`age`) 
VALUES(CONCAT('用户',2),'173@11.com',CONCAT('18',FLOOR(RAND()*100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100)),
(CONCAT('用户',3),'173@11.com',CONCAT('18',FLOOR(RAND()*100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100)),
(CONCAT('用户',4),'173@11.com',CONCAT('18',FLOOR(RAND()*100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100)),
(CONCAT('用户',5),'173@11.com',CONCAT('18',FLOOR(RAND()*100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100)),
(CONCAT('用户',6),'173@11.com',CONCAT('18',FLOOR(RAND()*100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));

SELECT * FROM `school`.`app_user` WHERE `name` = '用户1';
EXPLAIN SELECT * FROM `school`.`app_user` WHERE `name` = '用户1';

CREATE INDEX id_name ON `school`.`app_user`(`name`)
EXPLAIN SELECT * FROM `school`.`app_user` WHERE `name` = '用户1';

 

索引在小数据的时候,用处不打。但是在大数据的时候,区别十分明显~

5.索引原则
  1. 索引不是越多越好。

  2. 不要对进程变动数据加索引。

  3. 小数据量的表不需要加索引。

  4. 索引一般加载常用来查询的字段上。

索引的数据结构:

Hash 类型的索引

Btree:InnoDB的默认数据结构~

阅读:

数据库备份。权限管理。数据库的归约,三大范式。JDBC。

 

6.权限管理和备份
  1. 用户管理:

     

    SQL命令操作:

    1. 用户表:mysql.user
    1. 本质:读这张表进行增删改查
-- 创建用户
CREATE USER yuan1 IDENTIFIED BY '123456';

-- 修改密码 (修改当前用户密码)
SET PASSWORD = PASSWORD('123456');

-- 修改密码(修改指定用户密码)
SET PASSWORD FOR yuan =PASSWORD('111111');

-- 重命名 RENAME USER 原来名字 TO 新名字
RENAME USER yuan TO yuan2

-- 用户授权 ALL PRIVILEGES 全部的权限,库,表
-- ALL PRIVILEGES 除了给别人授权,其他都能干
GRANT ALL PRIVILEGES ON *.* TO yuan

-- 查询权限
SHOW GRANTS FOR yuan -- 查看指定用户权限
SHOW GRANTS FOR root@localhost

-- ROOT用户权限;GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION

-- 撤销权限 REVOKE 哪些权限,在哪个库撤销,给谁撤销
REVOKE ALL PRIVILEGES ON *.* FROM yuan

-- 删除用户
DROP USER yuan
7.MySQL备份

为什么要备份:

  1. 保证重要的数据不丢失。

  2. 数据转移

MySQL数据库备份的方式

  1. 直接拷贝物理文件

  2. 在Sqlyog 这种可视化工具中手动导出:

    1. 在想要导出的表或者库中,右键,选择备份或导出。

       

    2. 使用命令行到处 mysqldump 命令行使用

      # mysqldump -h 主机 -u 用户名 -p密码  数据库 表名 > 物理磁盘位置、文件名
      mysqldump -h localhost -uroot -p123456 school student >D:/a.sql
      # mysqldump -h 主机 -u 用户名 -p密码 数据库 表1 表2 表3 > 物理磁盘位置、文件名

      # 导入
      # 登录的情况下,切换到指定的数据库
      # source 备份文件
      souce D:/a.sql

      #非登录情况下
      mysql -u用户名 -p密码 库名< 备份文件

      假设你要备份数据库,防止数据丢失。

      把数据库给朋友!sql文件给别人即可

     

     

    8.规范数据库设计
    1. 为什么需要设计?

      当数据库比较复杂的时候,我们需要设计。

      糟糕的数据库设计:

      • 数据冗余,浪费空间。

      • 数据插入和删除都会麻烦。异常【屏蔽使用物理瓦检】

      • 程序性能差

      良好的数据库设计:

      • 节省内存空间

      • 保证数据库完整性

      • 方便我们开发系统

      软件开发中,关于数据库的设计

                  * 分析需求:分析业务和需要处理的数据库的需求

      * 概要设计:设计关系图 E- R 图

      设计数据库步骤:(个人博客类似)

      • 收集信息、分析需求

        ** 用户表(用户登录注销,用户个人信息,写博客,创建分类)

        ** 分类表(文章分类,谁创建的)

        ** 文章表(文章的信息)

        ** 友链表(友链信息)

        ** 自定义表(系统信息,某个关键的字,或者一些主字段)

        ** 说说表(发表心情.. id... content )

        key:value

      • 标识实体(把需求落地到每个字段)

      • 标识 实体之间的关系

        ** 写博客:user—> blog

        ** 创建分类:user—> category

        ** 关注:user—>user

        ** 友链:links

        ** 评论:user-user-blog

9.三大范式

为什么需要数据规范化?

  1. 信息重复

  2. 更新异常

  3. 插入异常

    1. 无法正常显示信息

  4. 删除异常

    1. 丢失有效的信息

三大范式:

第一范式(1NF):

原子性:保证每一列不可再分。

第二范式(2NF):

前提:满足第一范式。每张表只描述一件事情。

第三范式(3NF):

前提:满足第一范式和第二范式。

第三范式需要确保数据表中的每一列数据都和主键直接相关。而不能间接相关。

(规范数据库的设计)

 

规范性 和 性能的问题

关联查询的表不得超过三张表

  • 考虑商业化的需求和目标。(成本,用户体验!)数据库性能更加重要。

  • 在规范性能问题的时候,适当考虑规范性。

  • 故意给某些表增加一些字段(从多表查询变为单表查询)

  • 故意增加一些计算列(从大数据量,降低为小数据量的查询:索引)

 

10.JDBC(重点)
  1. 数据库驱动:程序需要通过数据库驱动连接上数据库,再和数据库打交道!

  2. JDBC:SUN公司为了简化开发人员的(对数据库的统一)操作,提供了一个(Java操作数据库)规范,俗称JDBC。这些规范的实现由具体的厂商去做!

    对于开发人员,我们只需要掌握JDBC接口操作即可。

     

java.sql

javax.sql

还需要导入一个数据库驱动包 mysql-connector-java-5.1.47.jar

11.第一个JDBC程序
  1. 创建一个项目

  2. 导入数据库

 

copy进lib后右键 Add as library

  1. 代码建立连接

    import java.sql.*;

    // 我的第一个JDBC 程序
    public class JdbcFirst {
       public static void main(String[] args) throws ClassNotFoundException, SQLException {
           // 1.加载驱动
           Class.forName("com.mysql.cj.jdbc.Driver"); //固定写法,加载驱动
           // 2.连接信息 用户信息和 url
           String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charcterEncoding=utf8&useSSL=true";
    //       String url = "jdbc:mysql://localhost:3306";
           String username= "root";
           String password = "123456";
           // 3.连接成功,数据库对象 Connection 代表数据库
           Connection connection = DriverManager.getConnection(url,username,password);
           // 4.执行SQL的对象 Statement 执行sql对象
           Statement statement=connection.createStatement();
           // 5.执行SQL的对象 去 执行SQL,可能存在结果,查看返回的结果
           String sql = "SELECT * FROM `jdbcstudy`.`users`";
           ResultSet resultSet=statement.executeQuery(sql); // 查看返回的结果集 结果封住了我们查出的全部结果

           while(resultSet.next()){
               System.out.println("id="+resultSet.getObject("id"));
               System.out.println("name="+resultSet.getObject("name"));
               System.out.println("password="+resultSet.getObject("password"));
               System.out.println("email="+resultSet.getObject("email"));
               System.out.println("birth="+resultSet.getObject("birthday"));
               System.out.println("==========");
          }
           // 6.释放连接
           resultSet.close();
           statement.close();
           connection.close();
      }
    }

    步骤总结:

    1. 加载驱动。Class.forName("com.mysql.cj.jdbc.Driver")

    2. 连接数据库DriverManager。 Connection connection = DriverManager.getConnection(url,username,password);

    3. 获得sql的对象。 Statement Statement statement=connection.createStatement();

    4. 获得返回的结果集。ResultSet resultSet=statement.executeQuery(sql);

    5. 释放连接。.close()

    DriverManager

  //DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
       Class.forName("com.mysql.cj.jdbc.Driver"); //固定写法,加载驱动
// 3.连接成功,数据库对象 Connection 代表数据库
       Connection connection = DriverManager.getConnection(url,username,password);

// connection 代表数据库
// 数据库设置自动提交
// 事务提交
// 事务回滚
// connection代表数据库所能干的事
connection.rollback();
connection.commit();
connection.setAutoCommit();

URL

// 2.连接信息 用户信息和 url
       String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charcterEncoding=utf8&useSSL=true";
// mysql -- 3306
// jdbc:mysql://主机地址:端口号/数据库名?参数1&参数2&参数3

// oralce -- 1521
//jdbc:oracle:thin:@localhost:1521:sid

Statement 执行SQL的对象 PrepareStatement

String sql = "SELECT * FROM `jdbcstudy`.`users`"; //编写SQL

statement.executeQuery(); // 查询操作返回 Result
statement.execute(); // 执行任何SQL
statement.executeUpdate() // 更新、插入、删除,返回一个受影响的函数

ResultSet 查询的结果集:封装了所有的查询结果

resultSet.getObject() //在不知道列的类型
// 如果知道列的类型就用指定类型
resultSet.getString()
resultSet.getInt()
resultSet.getFloat()
resultSet.getDate()
resultSet.getObject()
...

遍历,指针

resultSet.beforeFirst() // 移动到最前面
resultSet.afterLast() // 移动到最后面
resultSet.next() // 移动到下一个数据
resultSet.previous() // 移动到前一行
resultSet.absolute(row) // 移动到指定行

释放资源

// 6.释放连接
resultSet.close();
statement.close();
connection.close();
12.statement对象

Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。

Statement对象的executeUpdate方法,用于向数据库发送增、删、改的sql语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。

Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。

CRUD操作-create

使用executeUpdate(String sql)方法完成数据添加操作,示例操作:

Statement str = connection.createStatement();
String sql = "insert into user(...) values(...)";
int num = str.executeUpdate(sql);
if(num > 0){
   System.out.println("输入成功!!")
}

CRUD操作 - delete

使用executeUpdate(String sql)方法完成数据删除操作,示例操作:

Statement str = connection.createStatement();
String sql = "delete from user where id = 1";
int num = str.executeUpdate(sql);
if(num > 0){
   System.out.println("删除成功!!")
}

CRUD操作 - update

使用executeUpdate(String sql)方法完成数据修改操作,示例操作:

Statement str = connection.createStatement();
String sql = "update user set name='' where id = 1";
int num = str.executeUpdate(sql);
if(num > 0){
   System.out.println("修改成功!!")
}

CURD操作 - read

使用executeQuery(String sql)方法完成数据查询操作,示例操作:

Statement str = connection.createStatement();
String sql = "select * from users where id = 1";
int num = str.executeQuery(sql);
if(num.next()){
   System.out.println("查询成功!!")
}

代码实现

  1. 提取工具类

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=true
    username=root
    password=123456

     

    package com.yuan.lesson02.utils;

    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.*;
    import java.util.Properties;

    public class JdbcUtils {

       private static  String driver = null;
       private static String url = null;
       private static String username = null;
       private static String password = null;


       static {
           try {
               InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dp.properties");
               Properties properties = new Properties();
               properties.load(in);
               driver = properties.getProperty("driver");
               url = properties.getProperty("url");
               username = properties.getProperty("username");
               password = properties.getProperty("password");

               // 1.驱动只用加载一次
               Class.forName(driver);

          }catch (IOException e){
               e.printStackTrace();
          } catch (ClassNotFoundException e) {
               throw new RuntimeException(e);
          }
      }
       // 获取连接
       public static Connection getConnection() throws SQLException {
           return DriverManager.getConnection(url,username,password);
      }

       //释放连接资源
       public static void release(Connection conn, Statement st, ResultSet rs){
           if(rs != null){
               try {
                   rs.close();
              } catch (SQLException e) {
                   throw new RuntimeException(e);
              }
          }
           if(st != null){
               try {
                   st.close();
              } catch (SQLException e) {
                   throw new RuntimeException(e);
              }
          }
           if(conn != null){
               try {
                   conn.close();
              } catch (SQLException e) {
                   throw new RuntimeException(e);
              }
          }
      }

    }

     

  2. 编写增删改查 executeUpdate()

    package com.yuan.lesson02.utils;


    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import com.yuan.lesson02.utils.JdbcUtils;

    public class TestInsert {
       public static void main(String[] args) {
           Connection conn = null;
           Statement st = null;
           ResultSet rs =null;
           JdbcUtils JdbcUtils = new JdbcUtils();
           try {
               conn = JdbcUtils.getConnection(); //获取数据库连接
               st = conn.createStatement(); // 获取SQL执行对象
               String sql = "INSERT INTO `jdbcstudy`.`users`(`id`,`name`,`password`,`email`,`birthday`) VALUES(5,'HEQI','123456','HQ@163.com','1990-11-11')";
               int i = st.executeUpdate(sql);
               if(i>0){
                   System.out.println("插入成功");
              }
          } catch (SQLException e) {
               throw new RuntimeException(e);
          }finally {
               JdbcUtils.release(conn,st,rs);
          }

      }
    }
    package com.yuan.lesson02.utils;

    import com.yuan.lesson02.utils.JdbcUtils;

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

    public class TestDelete {
       public static void main(String[] args) {
           Connection conn = null;
           Statement st = null;
           ResultSet rs =null;
           JdbcUtils JdbcUtils = new JdbcUtils();
           try {
               conn = JdbcUtils.getConnection(); //获取数据库连接
               st = conn.createStatement(); // 获取SQL执行对象
               String sql = "DELETE FROM `jdbcstudy`.`users` WHERE `id`=5";
               int i = st.executeUpdate(sql);
               if(i>0){
                   System.out.println("删除成功");
              }
          } catch (SQLException e) {
               throw new RuntimeException(e);
          }finally {
               JdbcUtils.release(conn,st,rs);
          }
      }
    }
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;

    public class TestUpdate {
       public static void main(String[] args) {
           Connection conn = null;
           Statement st = null;
           ResultSet rs =null;
           JdbcUtils JdbcUtils = new JdbcUtils();
           try {
               conn = JdbcUtils.getConnection(); //获取数据库连接
               st = conn.createStatement(); // 获取SQL执行对象
               String sql = "UPDATE `jdbcstudy`.`users` SET `name`='nihao' WHERE `id`=4";
               int i = st.executeUpdate(sql);
               if(i>0){
                   System.out.println("更新成功");
              }
          } catch (SQLException e) {
               throw new RuntimeException(e);
          }finally {
               JdbcUtils.release(conn,st,rs);
          }
      }

    }
  1. 查询

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

    public class TestSelect {
       public static void main(String[] args) {
           Connection conn = null;
           Statement st = null;
           ResultSet rs = null;
           try {
               conn = JdbcUtils.getConnection();
               st = conn.createStatement();

               // SQL
               String sql = "select * from `jdbcstudy`.`users` where id = 1";
               rs = st.executeQuery(sql);
               while(rs.next()){
                   System.out.println(rs.getObject("name"));
              }
          } catch (SQLException e) {
               throw new RuntimeException(e);
          }finally {
               JdbcUtils.release(conn,st,rs);
          }

      }
    }

    SQL 注入问题

sql存在漏洞,会被攻击导致内容泄露。SQL会被拼接 or

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

public class SQL注入 {
   public static void main(String[] args) {
       login(" 'or '1=1'","'or '1=1'");
  }

   // 登录业务
   public static void  login(String username,String password){
       Connection conn = null;
       Statement st = null;
       ResultSet rs = null;
       try {
           conn = JdbcUtils.getConnection();
           st = conn.createStatement();

           // SQL
           String sql = "select * from `jdbcstudy`.`users` where `name` = '"+username+"' AND `password`='"+password+"'" ;
           rs = st.executeQuery(sql);
           while(rs.next()){
               System.out.println(rs.getObject("name"));
               System.out.println(rs.getObject("password"));
          }
      } catch (SQLException e) {
           throw new RuntimeException(e);
      }finally {
           JdbcUtils.release(conn,st,rs);
      }
  }
}
13.PreparedStatement对象

PreparedStatement可以防止SQL注入,效率更好!

  1. 新增

    import java.sql.Connection;
    import java.sql.Date;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;

    public class TestInsert {
       public static void main(String[] args) {
           Connection conn=null;
           PreparedStatement st = null;

           try {
              conn = JdbcUtils.getConnection();

               // 区别
               // 使用?占位符代替参数
               String sql = "INSERT INTO `jdbcstudy`.`users`(`id`,`name`,`password`,`email`,`birthday`) VALUES(?,?,?,?,?)";
               st = conn.prepareStatement(sql); //预编译SQL,先写sql,然后不执行

               // 手动给参数赋值
               st.setInt(1,5); //id
               st.setString(2,"heqi");
               st.setString(3,"123456");
               st.setString(4,"hq@163.com");
               //转化时间戳 sql.Date 数据库用的
               // util.Date Java new Date().getTime() 获得时间戳
               st.setDate(5,new java.sql.Date(new Date(1977,10,10).getTime()));

               // 执行
               int i= st.executeUpdate();
               if(i>0){
                   System.out.println("插入成功");
              }
          } catch (SQLException e) {
               throw new RuntimeException(e);
          }finally {
               JdbcUtils.release(conn,st,null);
          }
      }
    }

     

  2. 删除

    import java.sql.Connection;
    import java.sql.Date;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;

    public class TestDelete {
       public static void main(String[] args) {
           Connection conn=null;
           PreparedStatement st = null;

           try {
               conn = JdbcUtils.getConnection();

               // 区别
               // 使用?占位符代替参数
               String sql = "delete from `jdbcstudy`.`users` where id=?";
               st = conn.prepareStatement(sql); //预编译SQL,先写sql,然后不执行

               // 手动给参数赋值

               st.setInt(1,5);

               // 执行
               int i= st.executeUpdate();
               if(i>0){
                   System.out.println("删除成功");
              }
          } catch (SQLException e) {
               throw new RuntimeException(e);
          }finally {
               JdbcUtils.release(conn,st,null);
          }
      }
    }

     

  3. 改变

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;

    public class TestUpdate {
       public static void main(String[] args) {
           Connection conn=null;
           PreparedStatement st = null;

           try {
               conn = JdbcUtils.getConnection();

               // 区别
               // 使用?占位符代替参数
               String sql = "update `jdbcstudy`.`users` set `name`=? where id=?";
               st = conn.prepareStatement(sql); //预编译SQL,先写sql,然后不执行

               // 手动给参数赋值
               st.setString(1,"heqi2");
               st.setInt(2,5);

               // 执行
               int i= st.executeUpdate();
               if(i>0){
                   System.out.println("修改成功");
              }
          } catch (SQLException e) {
               throw new RuntimeException(e);
          }finally {
               JdbcUtils.release(conn,st,null);
          }
      }
    }
  4. 查找

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

public class TestSelect {
   public static void main(String[] args) {
       Connection conn = null;
       PreparedStatement st = null;
       ResultSet rs = null;
       try {
           conn=JdbcUtils.getConnection();
           String sql = "select * from `jdbcstudy`.`users` where id=?";
           st = conn.prepareStatement(sql);
           st.setInt(1,1);
           // 执行
           rs = st.executeQuery();
           if(rs.next()){
               System.out.println(rs.getObject("name"));
          }
      } catch (SQLException e) {
           throw new RuntimeException(e);
      } finally {
           JdbcUtils.release(conn,st,rs);
      }
  }
}
14.使用IDEA连接数据库

 

连接成功后可以选择数据库。

 

双击数据库,查询数据内容

 

更新数据

 

编写SQL

 

切换数据库

 

连接失败,查看原因

 

 

15.事务

要么都成功,要么都失败

ACID原则

原则性:要么全部完成,要么都不完成。

一致性:总数不变。

隔离性:多个进程互不干扰。

持久性:一旦提交不可逆,持久化到数据库。

隔离性问题:

脏读:一个事务读取了另一个没有提交的事务。

不可重复读:在同一个事务内,重复读取表中的数据,表数据发生改变。

虚读(幻读):在一个事务内,读取到了别人插入的数据,导致前后读出来的结果不一致。

代码实现

  1. 开启事务(conn.setAutoCommit(false); //**开启事务

  2. 一组业务执行完毕,提交事务。

  3. 可以在catch语句中显示的定义,回滚语句,但默认失败就会回滚

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

    public class TestTransaction1 {
       public static void main(String[] args) {
           Connection conn = null;
           PreparedStatement st= null;
           ResultSet rs = null;

           try {
               conn = JdbcUtils.getConnection();
               //关闭数据库的自动提交,自动会开启事务
               conn.setAutoCommit(false); //开启事务
               String sql1="update `shop`.`account` set money = money-100 where id = 1";
               st=conn.prepareStatement(sql1);
               int i=st.executeUpdate();
               String sql2="update `shop`.`account` set money = money+100 where id = 2";
               st=conn.prepareStatement(sql2);
               int s=st.executeUpdate();

               //业务完成,提交事务
               conn.commit();
               if(i>0&&s>0){
                   System.out.println("成功");
              }
          } catch (SQLException e) {
               try {
                   conn.rollback(); // 如果失败回滚事务
              } catch (SQLException ex) {
                   throw new RuntimeException(ex);
              }
          }finally {
               JdbcUtils.release(conn,st,rs);
          }
      }
    }

 

16.数据库连接池

数据库连接——执行完毕——释放

连接——释放 十分浪费系统资源

池化技术:准备一些预先的资源,过来连接预先准备好的

——开门——业务员:等待——服务——

常用连接数:10

最小连接数:10

最大连接数:15业务最高承载上线

等待超时:100ms

编写连接池,实现一个接口。DataSource

开源数据实现(拿来即用)

DBCP

C3P0

Druld:阿里巴巴

使用了这些数据库连接池之后,我们在项目中开发就不需要编写数据库代码了。

DBCP

需要用到的jar包

commons-dbcp-1.4 、commons-pool-1.6

C3P0

需要用到的jar包

c3p0-0.9.5.5、mchange-commons-java-0.2.19

结论

无论使用什么数据源,本质还是一样的。DataSource接口不会变,方法就不会变。

Apache基金会。

posted @   Y~~~  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示