Mysql

 

01、什么是数据库,为什么要学习数据库

javaEE:企业级java开发 Web

前端(页面:展示,数据!)

后台(连接点:连接数据库JDBC,连接前端(控制,控制视图跳转,和给前端传递数据))

数据库(存数据)

 

1.为什么学习数据库

  1. 岗位需求
  2. 现在的世界,大数据时代,得数据者得天下
  3. 被迫需求:存数据
  4. 数据库是所有软件体系中最核心的存在

  5. 2.什么是数据库

    数据库(DB,database)

    概念:数据仓库,软件,安装在操作系统(window,linux,mac...)之上。SQL,可以存储大量的数据,500w!

    作用:存储数据,管理数据

    02、初始MySQL,关系型和非关系型数据库区别

    1.数据库分类

    关系型数据库:(SQL)

    • MySQL、oracle、SqlServer、DB2、SQLLITE
    • 通过表和表之间,行和列之间的关系进行数据的存储。

    非关系型数据库:(NoSQL) not only

    • Redis、mongdb
    • 非关系型数据库,对象存储,通过对象的自身的属性来决定。

    DBMS(数据库管理系统)

      • 数据库的管理软件,科学有效的管理我们的数据,维护和获取数据
      • MySQL,数据库管理系统

    2.MySQL简介

    MySQL是一个**关系型数据库管理系统**

    前世:瑞典MySQL AB 公司开发

    今生:属于 Oracle 旗下产品

    MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。

    开源的数据库软件

    体积小、速度快、总体拥有成本低,招人成本比较低,所以人必须会用~

    中小型网站,或者大型网站,集群!

    官网:MySQL

    安装建议:

      1. 尽量不要使用exe,注册表
      2. 尽可能使用压缩包安装~

    03、安装MySQL详细说明

    1.安装步骤

        1. 解压 mysql-5.7.34-winx64.zip

        2. 把这个包放到自己的电脑环境目录下

          image-20210610221856286

        3. 配置环境变量

          修改系统变量Path即可

          image-20210610221806497

        4. 新建mysql配置文件ini

          image-20210610221955841

          [mysqld]
          # 设置mysql的安装目录
          basedir=D:\\environment\\mysql-5.7.34-winx64
          # 设置mysql数据库的数据的存放目录
          datadir=D:\\environment\\mysql-5.7.34-winx64\\data
          # 设置3306端口
          port=3306
          # 跳过验证
          skip-grant-tables
           
        5. 启动管理员模式下的cmd,切换到mysql安装目录的bin目录

          image-20210610222126769

        6. 安装mysql服务

          mysqld -install

          image-20210610222200449

        7. 初始化数据库文件

          mysqld --initialize-insecure --user=mysql

          image-20210610222359492

          这个时候安装目录就会多一个data目录

          image-20210610222538940

        8. 启动mysqlnet start mysql,然后用命令mysql -u root -p进入mysql管理界面(-p后面不要加空格)

          image-20210610222826936

          image-20210610222953356

        9. 进入界面后,修改密码(sql语句后面一定要加分号)

          update mysql.user set authentication_string=password('123456') where user='root' and host='localhost';
           

          image-20210610223232491

        10. 输入flush privileges;刷新权限

          image-20210610223414305

        11. 注释掉ini中的跳过密码skip-grant-tables

          image-20210610223507705

        12. 退出mysql命令行exit,停止mysql net stop mysql

    image-20210610223920444

        1. 然后启动服务,再次成功登陆,就ok了

          image-20210610224629970

    2.安装遇到的问题

        1. 执行mysqld -install报错如下的话

    image-20210610221326629

    可以先安装下面这个即可

    Download Visual C++ Redistributable Packages for Visual Studio 2013 from Official Microsoft Download Center

    sc delete mysql 清空服务

    05、基本的命令行操作

    mysql -uroot -p123456 -- 连接数据库
    
    update mysql.user set authentication_string=password('123456') where user='root' and host='localhost'; -- 修改用户密码
    
    flush privileges; -- 刷新权限
    ----------------------------
    -- 所有的语句都使用;结尾
    
    show databases; -- 查看所有的数据库
    
    mysql> use school; -- 切换数据库  use 数据库名
    Database changed
    
    mysql> show tables; -- 显示数据库中所有表的信息
    
    mysql> describe student; -- 显示表的详细信息
    
    create database zyy;  -- 创建一个数据库(这里过于简洁,后面详细介绍)
    
    exit -- 退出连接
    
    -- 单行注释
    /**
    多行注释
    */
    
     

    DDL 数据库定义语言

    DML 数据库操作语言

    DQL 数据库查询语言

    DCL 数据库控制语言

    06、操作数据库语句

    操作数据库 》 操作数据库中表 》操作数据库中表的数据

    ==mysql关键字不区分大小写==

    1.操作数据库(了解)

    1. 创建数据库

      CREATE DATABASE [IF NOT EXISTS] student;
       
    2. 删除数据库

      DROP DATABASE [IF EXISTS] zyy;
       
    3. 使用数据库

      -- 如果你的表名或者字段名是一个特殊字符,就需要带上``
      USER `student`;
       
    4. 查看数据库

      SHOW DATABASES; -- 查看所有的数据库
       

    学习思路

    1. ==对比sqlyog的可视化操作==
    2. 固定的语法或者关键字必须强行记住!

       

       

      07~JDBC操作事务

      ==要么都成功,要么都失败==

      ACID原则

      原子性:要么全部成功,要么全部失败

      一致性:总数不变

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

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

      隔离性的问题:

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

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

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

      代码实现

      1. 开启事务con.setAutoCommit(false);
      2. 一组业务执行完毕,提交事务
      3. 可以在catch语句中显示的定义回滚语句,但是默认失败就会回滚

      正常情况

      import com.zyy.lesson02.utils.JDBCUtils;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      
      /**
       * @ClassName: TestTransaction1
       * @Description: TODO 类描述
       * @Author: zyy
       * @Date: 2021/07/15 21:59
       * @Version: 1.0
       */
      public class TestTransaction1 {
          public static void main(String[] args) {
              Connection con = null;
              PreparedStatement ps = null;
              ResultSet rs = null;
      
              try {
                  con = JDBCUtils.getConnection();
                  //关闭自动提交 自动会开启事务
                  con.setAutoCommit(false);//开启事务
                  // A 转 B 100元
                  String sql1 = "update account set money=money-100 where name='A'";
                  ps = con.prepareStatement(sql1);
                  ps.executeUpdate();
                  String sql2 = "update account set money=money+100 where name='B'";
                  ps = con.prepareStatement(sql2);
                  ps.executeUpdate();
                  //业务完毕,提交事务
                  con.commit();
      
                  System.out.println("A 转 B 100元 成功!");
              } catch (SQLException e) {
                  e.printStackTrace();
                  try {
                      con.rollback();
                  } catch (SQLException ex) {
                      ex.printStackTrace();
                  }
              } finally {
                  JDBCUtils.release(con, ps, rs);
              }
          }
      }
      
       

      异常情况

      import com.zyy.lesson02.utils.JDBCUtils;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      
      /**
       * @ClassName: TestTransaction1
       * @Description: TODO 类描述
       * @Author: zyy
       * @Date: 2021/07/15 21:59
       * @Version: 1.0
       */
      public class TestTransaction2 {
          public static void main(String[] args) {
              Connection con = null;
              PreparedStatement ps = null;
              ResultSet rs = null;
      
              try {
                  con = JDBCUtils.getConnection();
                  //关闭自动提交 自动会开启事务
                  con.setAutoCommit(false);//开启事务
                  // A 转 B 100元
                  String sql1 = "update account set money=money-100 where name='A'";
                  ps = con.prepareStatement(sql1);
                  ps.executeUpdate();
      
                  //默认失败
                  int x = 1/0; //一定会异常
      
                  String sql2 = "update account set money=money+100 where name='B'";
                  ps = con.prepareStatement(sql2);
                  ps.executeUpdate();
                  //业务完毕,提交事务
                  con.commit();
      
                  System.out.println("A 转 B 100元 成功!");
              } catch (SQLException e) {
                  e.printStackTrace();
                  //如果异常,默认也会回滚,下面不写也可以
      //            try {
      //                con.rollback();
      //            } catch (SQLException ex) {
      //                ex.printStackTrace();
      //            }
              } finally {
                  JDBCUtils.release(con, ps, rs);
              }
          }
      }
       

      08、DBCP-C3P0连接池

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

      连接-- 释放 是十分浪费系统资源的

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

      最小连接数:10(常用连接)

      最大连接数:100 (业务最高承载上线)

      等待超时:100ms

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

      开源数据源实现

      DBCP

      C3p0

      Druid:阿里巴巴

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

      DBCP

      需要用到的jar包

      commons-dbcp-1.4

      commons-pool-1.6

      配置文件dbcp.properties

      #连接设置
      driverClassName=com.mysql.jdbc.Driver
      url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
      username=root
      password=123456
      
      #初始化连接
      initialSize=10
      
      #最大连接数量
      maxActive=50
      
      #最大空闲连接
      maxIdle=20
      
      #最小空闲连接
      minIdle=5
      
      #超时等待时间以毫秒为单位 6000毫秒/1000等于60秒
      maxWait=60000
      #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
      #注意:user 与 password 两个属性会被明确地传递,因此这里不需要包含他们。
      connectionProperties=useUnicode=true;characterEncoding=UTF8
      
      #指定由连接池所创建的连接的自动提交(auto-commit)状态。
      defaultAutoCommit=true
      
      #driver default 指定由连接池所创建的连接的只读(read-only)状态。
      #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
      defaultReadOnly=
      
      #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
      #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
      defaultTransactionIsolation=READ_COMMITTED
       

      工具类

      import org.apache.commons.dbcp.BasicDataSourceFactory;
      
      import javax.sql.DataSource;
      import java.io.IOException;
      import java.io.InputStream;
      import java.sql.Connection;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Statement;
      import java.util.Properties;
      
      /**
       * @ClassName: JDBCDBCPUtils
       * @Description: TODO 类描述
       * @Author: zyy
       * @Date: 2021/07/14 17:48
       * @Version: 1.0
       */
      public class JDBCDBCPUtils {
          private static DataSource dataSource = null;
      
          static {
              try {
                  InputStream in = JDBCDBCPUtils.class.getClassLoader().getResourceAsStream("dbcp.properties");
                  Properties properties = new Properties();
                  properties.load(in);
                  //创建数据源 工厂模式
                  dataSource = BasicDataSourceFactory.createDataSource(properties);
              } catch (IOException e) {
                  e.printStackTrace();
              } catch (ClassNotFoundException e) {
                  e.printStackTrace();
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          /**
           * 获取连接
           */
          public static Connection getConnection() throws SQLException {
              //从数据源中获取连接
              return dataSource.getConnection();
          }
      
          /**
           * 释放资源
           */
          public static void release(Connection con, Statement st, ResultSet rs) {
              if (rs != null) {
                  try {
                      rs.close();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
              if (st != null) {
                  try {
                      st.close();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
              if (con != null) {
                  try {
                      con.close();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
       

      测试类

      import com.zyy.lesson02.utils.JDBCUtils;
      import com.zyy.lesson05.utils.JDBCDBCPUtils;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      
      /**
       * @ClassName: TestDBCP
       * @Description: TODO 类描述
       * @Author: zyy
       * @Date: 2021/07/15 22:41
       * @Version: 1.0
       */
      public class TestDBCP {
          public static void main(String[] args) {
              Connection con = null;
              PreparedStatement st = null;
              ResultSet rs = null;
              try {
                  con = JDBCDBCPUtils.getConnection();
                  //使用?占位符代替参数
                  String sql = "INSERT INTO users(`id`,`name`,`password`,`email`,`birthday`) VALUES (?,?,?,?,?)";
                  //预编译SQL,先写SQL,然后不执行
                  st = con.prepareStatement(sql);
                  //手动给参数赋值
                  st.setInt(1, 5);
                  st.setString(2, "钱七");
                  st.setString(3, "123456");
                  st.setString(4, "qianqi@sina.com");
                  st.setDate(5, new java.sql.Date(new java.util.Date().getTime()));
                  int num = st.executeUpdate();
                  if (num > 0) {
                      System.out.println("插入成功!");
                  }
      
              } catch (SQLException e) {
                  e.printStackTrace();
              } finally {
                  JDBCDBCPUtils.release(con, st, rs);
              }
      
          }
      }
       

      C3P0

      需要用到的jar包

      c3p0-0.9.5.5.jar

      mchange-commons-java-0.2.19.jar

      配置文件c3p0-config.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <c3p0-config>
          <!--
          c3p0的缺省(默认)配置
          如果在代码中ComboPooledDataSource ds=new ComboPooledDataSource();这样写就表示使用的是c3p0的缺省(默认)
          -->
          <default-config>
              <property name="driverClass">com.mysql.jdbc.Driver</property>
              <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC</property>
              <property name="user">root</property>
              <property name="password">123456</property>
              <property name="acquiredIncrement">5</property>
              <property name="initialPoolSize">10</property>
              <property name="minPoolSize">5</property>
              <property name="maxPoolSize">20</property>
          </default-config>
      
      
          <!--
          c3p0的命名配置
          如果在代码中ComboPooledDataSource ds=new ComboPooledDataSource("MySQL");这样写就表示使用的是name是MySQL
          -->
          <name-config name="MySQL">
              <property name="driverClass">com.mysql.jdbc.Driver</property>
              <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC</property>
              <property name="user">root</property>
              <property name="password">123456</property>
              <property name="acquiredIncrement">5</property>
              <property name="initialPoolSize">10</property>
              <property name="minPoolSize">5</property>
              <property name="maxPoolSize">20</property>
          </name-config>
      </c3p0-config>
       

      工具类

      import com.mchange.v2.c3p0.ComboPooledDataSource;
      
      import java.sql.Connection;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Statement;
      
      /**
       * @ClassName: JDBCC3P0Utils
       * @Description: TODO 类描述
       * @Author: zyy
       * @Date: 2021/07/14 17:48
       * @Version: 1.0
       */
      public class JDBCC3P0Utils {
          private static DataSource dataSource = null;
          //private static ComboPooledDataSource dataSource = null;
      
      
          static {
              try {
                  //代码的方式配置
      //            dataSource = new ComboPooledDataSource();
      //            dataSource.setDriverClass();
      //            dataSource.setJdbcUrl();
      //            dataSource.setUser();
      //            dataSource.setPassword();
      //            dataSource.setMaxPoolSize();
      //            dataSource.setMinPoolSize();
                  //配置文件写法
                  dataSource = new ComboPooledDataSource("MySQL");
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          /**
           * 获取连接
           */
          public static Connection getConnection() throws SQLException {
              //从数据源中获取连接
              return dataSource.getConnection();
          }
      
          /**
           * 释放资源
           */
          public static void release(Connection con, Statement st, ResultSet rs) {
              if (rs != null) {
                  try {
                      rs.close();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
              if (st != null) {
                  try {
                      st.close();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
              if (con != null) {
                  try {
                      con.close();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
       

      测试类

      import com.zyy.lesson05.utils.JDBCC3P0Utils;
      import com.zyy.lesson05.utils.JDBCDBCPUtils;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      
      /**
       * @ClassName: TestC3P0
       * @Description: TODO 类描述
       * @Author: zyy
       * @Date: 2021/07/15 22:41
       * @Version: 1.0
       */
      public class TestC3P0 {
          public static void main(String[] args) {
              Connection con = null;
              PreparedStatement st = null;
              ResultSet rs = null;
              try {
                  con = JDBCC3P0Utils.getConnection();
                  //使用?占位符代替参数
                  String sql = "INSERT INTO users(`id`,`name`,`password`,`email`,`birthday`) VALUES (?,?,?,?,?)";
                  //预编译SQL,先写SQL,然后不执行
                  st = con.prepareStatement(sql);
                  //手动给参数赋值
                  st.setInt(1, 6);
                  st.setString(2, "刘八");
                  st.setString(3, "123456");
                  st.setString(4, "liuba@sina.com");
                  st.setDate(5, new java.sql.Date(new java.util.Date().getTime()));
                  int num = st.executeUpdate();
                  if (num > 0) {
                      System.out.println("插入成功!");
                  }
      
              } catch (SQLException e) {
                  e.printStackTrace();
              } finally {
                  JDBCC3P0Utils.release(con, st, rs);
              }
      
          }
      }
       

      总结

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

      Welcome to The Apache Software Foundation!

      image-20210719174041225

posted @ 2021-12-30 10:01  码奴2002  阅读(34)  评论(0)    收藏  举报