当前考虑的是使用Java操作MySQL
MySQL的自身是使用C或C++来编写的

如果使用其他语言操作数据库?
数据库服务器是本体,通过代码写的程序,调用MySQL的API实现的是一个客户端,
其他编程语言访问数据库,就只要按照MySQL服务器的要求,构造出对应的网络请求就行了

本质上是在实现一个MySQL的客户端
MySQL的客户端有很多(只要能按照人家MySQL约定的网络请求的格式来构造请求)

MySQL Workbench就是官方的一个图形化客户端程序
image.png
Navicat等第三方的图形化客户端程序

连接Connection != 链接Link

总归下来还是SQL语言,就是换个地方敲

JDBC操作

通过Java来操作MySQL
得先得到MySQL的API
可以在MySQL的官网上找到
可惜 自从被Olrea收购了就很难下载
可以去一些其他的“中央仓库”找到相关的API

此驱动不是指平时日常生活中·说的驱动,硬件驱动(也是一个软件,是让操作系统能够通过这个硬件驱动程序向硬件发号施令) 但是术语同样是,driver——>驱动 而下载下来的.jar文件,则是一个压缩文件(同zip、7z之类),针对java的压缩包

Java操作数据库的
java为了简化操作

封装
数据库种类很多,每个数据库都会提供一组API,不同的数据库提供的API还不一样,只需要关注JDBC提供的API即可,JDBC在底层把不同的数据库的接口给统一起来了
其实,所谓JDBC编程就是在底层操作MySQL客户端

操作

  1. 将jar包拷贝到项目的某个目录里
  2. 右键该目录,add as library

后续就可以访问到该jar包中的类了

MySQL是 客户端 和 服务器 结构

但是不是所有的数据库都是这样的 不是!SQL Server Oracle也是这样的,但是SQLite这个数据库就只有客户端

  1. 创建一个数据源
  2. 给数据源对象设置一些参数
    1. 数据库服务器的ip地址
    2. 数据库服务器的端口号
    3. 访问的数据库名(操作这个数据库服务器上面的哪个数据集合)
    4. 用户名
    5. 密码

  3. ```java import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

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

/**

  • Created with IntelliJ IDEA
  • Description:
  • User:王瀚晨
  • Date:2021-06-01
  • Time: 21:13 */ public class TestJDBC { public static void main(String[] args) throws SQLException {

    1. //1.先和数据库建立连接
    2. // a.创建一个数据源(DataSource)
    3. DataSource dataSource = new MysqlDataSource();
    4. // b.给数据源设置一些属性(为了告诉代码,数据库服务器在哪呢)
    5. //向下转型,一般习惯这么写,有一个好处就是,如果未来需要换一个数据库,改动就会更小
    6. //可能性很低奥,只能说java这个圈子的人都魔怔了,过早优化是万恶之源
    7. ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/shop?characterEncoding=utf8&useSSL=true");
    8. ((MysqlDataSource) dataSource).setUser("root");
    9. ((MysqlDataSource) dataSource).setPassword("123456");
    10. // c.通过getConnection方法来和服务器建立连接
    11. //这里大概率回失败,main方法抛出异常
    12. Connection connection = dataSource.getConnection();
    13. //2.拼装SQL语句——>语法与SQL一致
    14. //插入数据 注意此处的 ; 加不加都可以
    15. String sql = "insert into exam values(10,'张小辉',60,70,80)";
    16. //实际上需要的是一个 语句对象
    17. //PreparedStatement会帮助我们很方便的动态的构造出一个SQL 来
    18. PreparedStatement statement = connection.prepareStatement(sql);
    19. //3.执行SQL语句,上边只是给准备好了语句,还没开始呢
    20. //这里执行的是insert语句,尽管是insert但是使用executeUpdate来完成
    21. //包括delete 和 update 也是使用executeUpdate 来完成
    22. //如果当前执行的是select 语句 , 使用executeQuery来完成
    23. //此处的int ret 表示的是影响到了几行
    24. int ret = statement.executeUpdate();
    25. System.out.println("ret = "+ ret);
  1. //4.收尾工作——>释放前边申请到的资源
  2. /**
  3. * 就算不释放,影响也不大!但最好还是手动释放
  4. * 如果没有手动释放的话,可能会出现问题
  5. * 容易出现问题的情况:短时间内,反复进行建立连接/创建语句
  6. * 原因:MySQL服务器同一时间能处理过来的链接数目是有限的
  7. * 如果不是短时间内高很多链接,在一个长跨度的时间内,反复连接,就不会出现问题
  8. *
  9. * 此处手动释放的及时性要高于等待垃圾回收机制自动释放~~
  10. */
  11. //例如:用于连接的connection
  12. //这里考虑到一个顺序问题,遵循先进后出
  13. //先申请的,后释放
  14. statement.close();
  15. connection.close();
  16. }

}

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/700185/1622721329467-7fa91831-bbd9-4d62-b9d0-b7f8c3667b35.png#align=left&display=inline&height=280&margin=%5Bobject%20Object%5D&name=image.png&originHeight=280&originWidth=451&size=16073&status=done&style=none&width=451)
  2. 手动输入insert
  3. ```java
  4. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
  5. import javax.sql.DataSource;
  6. import java.sql.Connection;
  7. import java.sql.PreparedStatement;
  8. import java.sql.SQLException;
  9. import java.util.Scanner;
  10. /**
  11. * Created with IntelliJ IDEA
  12. * Description:
  13. * User:王瀚晨
  14. * Date:2021-06-01
  15. * Time: 21:13
  16. */
  17. public class TestJDBC {
  18. public static void main(String[] args) throws SQLException {
  19. //1.先和数据库建立连接
  20. // a.创建一个数据源(DataSource)
  21. DataSource dataSource = new MysqlDataSource();
  22. // b.给数据源设置一些属性(为了告诉代码,数据库服务器在哪呢)
  23. //向下转型,一般习惯这么写,有一个好处就是,如果未来需要换一个数据库,改动就会更小
  24. //可能性很低奥,只能说java这个圈子的人都魔怔了,过早优化是万恶之源
  25. ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/shop?characterEncoding=utf8&useSSL=true");
  26. ((MysqlDataSource) dataSource).setUser("root");
  27. ((MysqlDataSource) dataSource).setPassword("123456");
  28. // c.通过getConnection方法来和服务器建立连接
  29. //这里大概率回失败,main方法抛出异常
  30. Connection connection = dataSource.getConnection();
  31. //手动输入
  32. Scanner sc = new Scanner(System.in);
  33. int id = sc.nextInt();
  34. String name = sc.next();
  35. int chinese = sc.nextInt();
  36. int math = sc.nextInt();
  37. int english = sc.nextInt();
  38. //2.拼装SQL语句——>语法与SQL一致
  39. //插入数据 注意此处的 ; 加不加都可以
  40. String sql = "insert into exam values(?,?,?,?,?)";
  41. //实际上需要的是一个 语句对象
  42. //PreparedStatement会帮助我们很方便的动态的构造出一个SQL 来
  43. PreparedStatement statement = connection.prepareStatement(sql);
  44. statement.setInt(1,id);
  45. statement.setString(2,name);
  46. statement.setInt(3,chinese);
  47. statement.setInt(4,math);
  48. statement.setInt(5,english);
  49. //3.执行SQL语句,上边只是给准备好了语句,还没开始呢
  50. //这里执行的是insert语句,尽管是insert但是使用executeUpdate来完成
  51. //包括delete 和 update 也是使用executeUpdate 来完成
  52. //如果当前执行的是select 语句 , 使用executeQuery来完成
  53. //此处的int ret 表示的是影响到了几行
  54. int ret = statement.executeUpdate();
  55. System.out.println("ret = "+ ret);
  56. //4.收尾工作——>释放前边申请到的资源
  57. /**
  58. * 就算不释放,影响也不大!但最好还是手动释放
  59. * 如果没有手动释放的话,可能会出现问题
  60. * 容易出现问题的情况:短时间内,反复进行建立连接/创建语句
  61. * 原因:MySQL服务器同一时间能处理过来的链接数目是有限的
  62. * 如果不是短时间内高很多链接,在一个长跨度的时间内,反复连接,就不会出现问题
  63. *
  64. * 此处手动释放的及时性要高于等待垃圾回收机制自动释放~~
  65. */
  66. //例如:用于连接的connection
  67. //这里考虑到一个顺序问题,遵循先进后出
  68. //先申请的,后释放
  69. statement.close();
  70. connection.close();
  71. }
  72. }

image.png

注意:

  1. 手动拼装SQL不安全!! 为啥呢?
    1. 假设用户的名字形如,name = 'asd';drop database shop;——>SQL注入攻击
    2. 因此使用,PrepareStatement,人家里面的setXXX方法内部做了充分的校验,能够及时的识别出这种SQL注入攻击

查找

  1. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
  2. import javax.sql.DataSource;
  3. import java.sql.Connection;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. /**
  8. * Created with IntelliJ IDEA
  9. * Description:
  10. * User:王瀚晨
  11. * Date:2021-06-03
  12. * Time: 20:00
  13. */
  14. //使用JDBC查找数据
  15. public class TestJDBC2 {
  16. public static void main(String[] args) throws SQLException {
  17. //1.和数据库建立连接
  18. //创建数据源
  19. DataSource dataSource = new MysqlDataSource();
  20. //给数据源设置。一些属性
  21. ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/shop?characterEncoding=utf8&useSSL=true");
  22. ((MysqlDataSource) dataSource).setUser("root");
  23. ((MysqlDataSource) dataSource).setPassword("123456");
  24. //建立连接,选java.sql的选项
  25. Connection connection = dataSource.getConnection();
  26. //拼接SQL语句
  27. String sql = "select * from exam";
  28. PreparedStatement statement = connection.prepareStatement(sql);
  29. //执行SQL语句 查询语句其实会得到一个临时表
  30. //所以通过RsultSet就能够获取到需要的表格中的数据
  31. ResultSet resultSet = statement.executeQuery();
  32. //通过ResultSet获取到结果内容,遍历结果集合
  33. //注意这里不同于sc.hasNext()
  34. //每次调用next就类似于i++的操作一样
  35. //会先获取到当前的记录,并同时把下标后移
  36. //当整个结果集合遍历完毕后,next会返回false,遍历结束
  37. while(resultSet.next()){
  38. //可以获取到当前记录(当前行的每一列)
  39. //必须保证列名相匹配
  40. int id = resultSet.getInt("id");
  41. String name = resultSet.getString("name");
  42. double chinese = resultSet.getDouble("chinese");
  43. double math = resultSet.getDouble("math");
  44. double english = resultSet.getDouble("english");
  45. System.out.println(id+","+name+","+chinese+","+math+","+english);
  46. }
  47. //释放
  48. resultSet.close();
  49. statement.close();
  50. connection.close();
  51. }
  52. }

image.png

注意:

  1. 请求彼此之间共用一个DataSource即可,当然不是说不能创建多份,只是没必要
  2. 假设如果当前的服务器收到的请求数量很多,随之创建的Connection对象也很多,那么ResultSetPrepareStatement也会变多
  3. 但是Connection创建的开销远远比创建ResultSetPrepareStatement更大
  4. 实际上,我们使用的DataSourcegetConnection并不一定每次调用都创建新的连接对象
    1. 目的就是因为简例连接过程开销太大了,能省则省
    2. 同时又不能把ConnectionDataSource一样只搞一份
    3. 因此引出了,数据库连接池的概念
  5. 诸如DataSource这样的对象我们希望只有一份,之创建一个实例就可以了
    1. 通过单例模式,来保证DataSource只有一个实例

单例模式:
是一种设计模式——>例如棋谱
计算机先人们,针对一些经典的场景,设计了一些解决方案

池的概念pool 在计算机中是一个非常广泛使用的概念 进程池、线程池、内存池……

单例模式

线程安全版本的单例模式——>待学习!!

  1. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
  2. import javax.sql.DataSource;
  3. public class DBUtil {
  4. //类成员 vs 实例成员
  5. private static DataSource dataSource = null;
  6. //后面再写代码的时候都不适用DataSource直接new了
  7. //而是通过下面的getDataSource()方法来获取这个实力
  8. public static DataSource getDataSource(){
  9. if(dataSource == null){
  10. dataSource= new MysqlDataSource();
  11. ((MysqlDataSource) dataSource).setUrl("");
  12. ((MysqlDataSource) dataSource).setUser("");
  13. ((MysqlDataSource) dataSource).setPassword("");
  14. }
  15. return dataSource;
  16. }
  17. }
  1. 操作数据库
  2. 增加数据
  3. 删除数据
  4. 修改数据
  5. 查询数据
  6. 约束
  7. 设计表的方法
  8. 更加复杂的查找——聚合查询,多表查询,子查询
  9. 索引/事务
  10. JDBC编程

注意:
throw是一定会抛出异常
throws是可能会抛出异常
抛出异常,要把close放到finally中,保证其被执行

这时需要了解进程:

  1. 进程不同于可执行文件,可执行文件只是在磁盘上,双击才跑起来,此时在操作系统中就出现了一个对应的进程
  2. 进程包含了一系列相关联的资源(内存、文件资源、CPU……)
  3. 一旦进程被销毁,此时相关的资源也就被回收了
  4. 在代码中,通过colse方法关闭连接,这是一种比较温和的回收资源的方式
  5. 如果直接干掉进程,这是一种比较激烈的回收资源的方式
  6. 实际开发中,进程不是说干掉就能干掉的事情,因为在工作中,涉及到的很多程序对应的进程是一个“服务器进程”