黑马程序员技术交流社区

标题: 【石家庄JavaEE就业六期]】数据库笔记 [打印本页]

作者: 信仰°    时间: 2018-1-11 15:27
标题: 【石家庄JavaEE就业六期]】数据库笔记
本帖最后由 小石姐姐 于 2018-1-12 10:49 编辑

                                                           数据库笔记


  • 数据库
    • 概念: 存储数据的仓库. 本质是一个文件系统, 数据按照指定的格式将数据存储起来, 用户可以对数据库中的数据进行增删改查
    • DBMS: Database Management System, 数据库管理系统. 是操作和管理数据库的大型软件, 用于建立, 使用和维护数据库, 对数据库进行统一管理和控制, 以保证数据库的安全性和完整性. 用户通过数据库管理系统访问数据库中表内的数据
    • 常见数据库
      • MySQL
      • Oracle
    • 数据库: 存储数据表
    • 数据表: 存储记录
      • 由行和列组成的
    • DBMS: 操作数据库
    • 表和Java类的对应关系
      • 表名: Java类名
      • 列名: 成员属性名
      • 记录: 类对象

  • MySQL
    • 安装
    • 配置和遇到的问题
    • 命令行的登录和退出
      • 登录: mysql -u 用户名 -
      • 退出: exit

  • SQL基本语言
    • SQL的概念: Structured Query Language, 结构化查询语言
      • 结构: 数据表是由行和列组成的, 是有结构的, 从这种结构中查询
    • SQL的4中分类
      • DDL: Data Defination Language, 数据定义语言, 用来定义数据库对象(库, 表等)
        • CREATE
        • ALTER
        • DROP
      • DML: Data Manipulation Language, 数据操作语言, 对表中的记录进行增, 删, 改
        • INSERT
        • UPDATE
        • DELETE
      • DQL: Data Query Language, 数据查询语言, 对表中的记录进行查
        • SELECT
        • FROM
        • WHERE
      • DCL: Data Control Language, 数据控制语言, 创建修改用户, 权限
    • SQL特点
      • SQL不区分大小写
      • 一条SQL语句以;分号结尾, 一条语句可以多行书写
      • 单词之间通过空格分隔, 参数之间通过,逗号分隔
      • 字符串和日期要用''或""引起来, 建议单引号
    • SQL注释(2+1种)
      • 2种单行注释
        • #单行注释
        • -- 单行注释: 减号后必须有一个空格
      • 1种多行注释: /* 注释内容 */
    • SQL的数据类型
      • INT: 整数
      • `DOUBLE: 小数
      • `VARCHAR: 可变长度字符
      • `CHAR: 固定长度字符
      • 其他看文档
      • VARCHAR和CHAR的区别:
        • VARCHAR(200), 可变长度字符, 存储占用的内存空间是可变的, 如果你的数据容量小于我们指定的空间大小, 那么就会按照实际的数据空间来开辟内存大小
          • 优点: 节省内存
          • 缺点: 因为每次存入数据时都会判断数据的实际大小, 来动态修改内存空间, 所以需要占用资源, 效率低
        • CHAR(200), 固定长度字符, 存储占用的内存空间是不可变的. 无论实际存入的数据容量是多大, 都占用这么大的空间
          • 优点: 插入数据时不需要额外操作, 效率高
          • 缺点: 可能会浪费空间


    • SQL对库的操作
      • 创建库
        • 使用默认字符集创建库: CREATE DATABASE 库名
          • 默认是UTF-8编码
        • 指定字符集: CREATE DATABASE 库名 CHARACTER SET '字符集';
      • 删除库
        • DROP DATABASE 库名;
      • 查看所有库
        • SHOW DATABASES;
      • 使用库
        • USE 库名;
      • 查看当前使用的库
        • SELECT DATABASE();

    • SQL对表的操作
      • 创建表: CREATE TABLE 表名 (列名1 数据类型 约束, 列名2 数据类型 约束);
      • 删除表: DROP TABLE 表名;
      • 查看当前库中的所有表: SHOW TABLES;
      • 修改表的结构: ALTER TABLE 表名 操作关键字 列名 数据类型 约束;
        • 增加列: ALTER TABLE 表名 ADD 新列名 新数据类型 新约束;
        • 删除列: ALTER TABLE 表名 DROP 列名
        • 修改列的数据类型和约束(不能修改列名): ALTER TABLE 表名 MODIFY 列名 新数据类型 新约束;
        • 修改列的列名, 数据类型, 约束: ALTER TABLE 表名 CHANGE 旧列名 新列名 新数据类型 新约束;
      • 修改表名: RENAME TABLE 旧表名 TO 新表名;
    • SQL对记录的操作

        • 一次插入一条记录: INSERT INTO 表名 (列1, 列2) VALUES (值1, 值2);
        • 一次性插入一条记录(省略自增主键): INSERT INTO 表名 (非主键自增列1, 非主键自增列2) VALUES (值1, 值2);
        • 一次插入所有列的记录(省略列名): `INSERT INTO 表名 VALUES (值1, 值2);
          • 值的数量和顺序必须和表的列一致
        • 一次插入多个记录(指定列): INSERT INTO 表名 (列1, 列2) VALUES (记录1值1, 记录1值2), (记录2值1, 记录2值2);
        • 一次插入多个记录(省略列): INSERT INTO 表名 VALUES (记录1值1, 记录1值2), (记录2值1, 记录2值2);

        • 删除符合条件的记录: DELETE FROM 表名 WHERE 条件;
        • 删除所有记录: DELETE FROM 表名;
        • 清空表: TRUNCATE TABLE 表名;
        • DELETE FROM 表名;和TRUNCATE TABLE 表名;的区别
          • DELETE, 逐条删除记录, 不会重置自增计数器
          • TRUNCATE, 删除表再重建, 会重置自增计数器


        • 修改符合条件的记录: UPDATE 表名 SET 列名1=新值, 列名2=新值 WHERE 条件;
        • 修改所有记录: UPDATE 表名 SET 列名1=新值, 列名2=新值;

        • 查询指定列: SELECT 列名1, 列名2 FROM 表名;
        • 查询所有列: SELECT * FROM 表名;
        • 条件查询: SELECT 列名1, 列名2 FROM 表名 WHERE 条件;
          • 运算符
            • 比较运算符
              • =: 相等
              • <>或!=: 不等
              • >: 大于
              • <: 小于
              • >=: 大于等于
              • <=: 小于等于
              • BETWEEN...AND...: 在一个范围内(包含头和尾)
                • 如: BETWEEN 0 AND 10
              • IN (): 在列表中, 满足列表中一个即可
                • 如: IN (1, 3, 5)
              • IS NULL: 是空
              • LIKE '通配符': 模糊查询
                • %: 一个百分号可以表示任意个字符. 比如'王%', 王大锤, 王五
                • _: 一个下划线可以表示一个字符. 比如'王_', 只能匹配王五

            • 逻辑运算符
              • AND: 与. 两边条件同时成立才成立
              • OR: 或. 两边条件只要有一个成立就成立
              • NOT: 非, 取相反结果
                • NOT BETWEEN ... AND ...: 不在范围内
                • NOT IN: 不在列表中
                • NOT LIKE: 不匹配
                • IS NOT NULL: 非空



        • 去重: SELECT DICTINCT 列名1, 列名2 ... FROM 表名 WHERE 条件;
        • 别名:
          • 字段名 AS 别名
          • 表名 AS 别名




  • 高级SQL
    • 排序
      • ORDER BY 列名 ASC|DESC;
      • 注意:
        • 默认顺序为升序ASC
        • WHERE在前, ORDER BY在后

    • 聚合函数
      • 用在SELECT后或HAVING后
      • COUNT(列名): 计算记录数量
        • NULL值不会被算入数量
      • SUM(列名): 将该列的值求总和
        • 如果不是数字类型, 则结果为0
      • MAX(列名): 求该列值中的最大值
      • MIN(列名): 求该列值中的最小值
      • AVG(列名): 求该列所有值的平均值
        • 如果不是数字类型, 则结果为0

    • 分组
      • GROUP BY 列名 HAVING 条件;: 对查询结果集分组, 然后再按条件过滤
      • 注意:
        • 聚合函数与分组的使用效果
          • 使用聚合函数后再进行分组, 才相当于汇总统计
            • SELECT zname, SUM(zmoney) FROM zhangwu GROUP BY zname;
          • 不使用聚合函数的分组, 只有第一条记录的值
            • SELECT zname, zmoney FROM zhangwu GROUP BY zname;

        • HAVING和WHERE的区别
          • 过滤时机不同
            • WHERE是在分组前先对查询结果进行过滤
            • HAVING是在查询结果分组后再次过滤
          • 是否可跟随聚合函数不同
            • WHERE条件中不可使用聚合函数
            • HAVING条件中可以使用聚合函数
          • 条件可用列名不同
            • HAVING条件中的列名必须是SELECT或GROUP BY中使用过的列名
            • WHERE条件中可以使用表的所有列名




  • JDBC
    • JDBC: Java数据库连接. SUN公司提供的接口, 用来让数据库厂商实现数据库操作的功能
    • 数据库驱动: 就是JDBC的实现
    • JDBC开发步骤:
      • 前提: 导包(数据库驱动)
      • 步骤:
        • 注册驱动
          • DriverManager.registerDriver(): 是真实的注册驱动的方法
          • 因为驱动中实现了这个方法, 推荐我们使用:
            • Class.forName("数据库驱动的Driver实现类全类名")

        • 获取连接:
          • Connection conn = DriverManager.getConnection(url, username, password)
        • 获取执行平台:
          • Statement s = conn.createStatement();: 不安全的
          • PreparedStatement ps = conn.prepareStatement(String sql);: 可以防范SQL注入
            • 设置参数:
              • 占位符: ?, 即使是字符串, 也不要给问号加引号
              • void setObject(int index, Object obj)
                • index从1开始



        • 执行SQL语句
          • Statement
            • 增删改:int s.executeUpdate(String sql)
              • 判断操作是否成功: 判断返回值是否>0则生效, 否则不成功
            • 查:ResultSet rs = s.executeQuery(String sql)
              • 思考: 判断操作是否成功: 是返回null呢还是调用.next()用是否为true判断?

          • PreparedStatement
            • 增删改: int ps.executeUpdate();
              • 判断操作是否成功: 判断返回值是否>0则生效, 否则不成功
            • 查: ResultSet rs = ps.executeQuery();

        • 处理结果
          • ResultSet
            • boolean next();: 将指针向后移动, 如果有下一个记录则true, 否则false
              • 默认不执行的之后, 指针在第一条记录之前; 只有调用一次才能指向第一条: while (rs.next()) {}
            • String getString(String 列名): 获取指定列的值, 以String类型
            • Object getObject(String 列名): 获取指定列的值, 以Object类型

        • 释放资源
          • resultSet.close()
          • preparedStatement.close()
          • statement.close()
          • connection.close()


    • SQL注入
      • 原理: 拼接SQL导致用户的输入可以改变SQL的意义, Statement无法避免注入
      • 超级密码: 1' OR '1=1
      • 如何避免: 使用PreparedStatement替换Statement
    • JDBCUtils工具类的自定义
      • 在静态代码块中初始化连接对象
      • 定义方法获取连接对象, 释放资源


  • 使用Properties配置文件
    • 作用: 将配置信息从源代码中隔离, 达到可以直接修改配置文件, 而不用修改源代码的目的
    • 配置文件的创建
      • 在src目录下创建, 会自动在bin目录下生成
      • 以.properties后缀结尾
      • 配置文件的格式: 键值对, 一行一个键值对
    • 读取配置文件
      • 通过类加载器, 去加载bin目录下的配置文件
      • 类加载器的获取:
        • 获取类的字节码对象: 类名.class
        • 通过类的字节码对象获取类加载器:ClassLoader 字节码对象.getClassLoader()
        • 通过类加载器对象读取资源文件:InputStream getResourceAsStream(String 配置文件路径)
        • 创建Properties对象:Properties p = new Properties();
        • 通过该对象加载流(此时Properties对象才有数据):p.load(inputStream)
        • 通过Properties对象获取属性值:String p.getProperty(String key)


  • DbUtils
    • 是什么: 是Apache的Commons项目中的一个组件, 开源的工具类(第三方库)
    • 三个核心类/接口
      • QueryRunner类: 提供操作SQL语句的API
        • QueryRunner(): 创建对象
        • int update(Connection conn, String sql, Object... param): 执行INSERT, DELETE, UPDATE语句, 同时传入占位符的参数值, 是可变参数
        • <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params): 执行SELECT查询, 并根据传入的结果集处理器来处理结果
      • ResultSetHandler接口: 定义SELECT操作后对结果集的操作方法, 可以将结果集转换为Java类
        • ArrayHandler类: 将结果集的第一条记录封装到一个Object[]数组中, 数组中的每一个元素就是该条记录中的每一列的值
        • ArrayListHandler类: 将结果集中的每一条记录都封装到一个Object[]数组中, 再将这些数组封装到List<Object[]>集合中
        • BeanHandler类: 将结果集中的第一条记录封装到一个指定的JavaBean中
        • BeanListHandler类: 将结果集中的每一条记录都封装到一个指定的JavaBean中, 再将这些JavaBean封装到List<T>集合中
        • ColumnListHandler类: 将结果集中指定的列的字段值, 封装到一个List集合. 用于竖向查一个列
        • ScalarHandler类: 获取单一结果, 用于聚合函数如SELECT COUNT(*) FROM 表的操作
        • MapHandler类: 将结果集的第一条记录封装到一个Map中. key是列名, value是第一条记录的每个字段的值
        • MapListHandler类: 将结果集的每一条记录封装到一个Map中. key是列名, value是第一条记录的每个字段的值. 然后再将这些Map封装到一个List中
      • DbUtils类: 用于关闭资源和事务处理
        • static void closeQuietly(Connection conn): 关闭连接, 内部处理了异常



  • DBCP连接池
    • Apache commons项目中的一个组件
    • 作用: 提供连接池, 替代连接. 连接池可以存放多个连接, 反复使用, 而不用每次创建销毁, 提高效率, 节省资源
    • 普通连接的弊端: 获取连接, 释放资源太消耗资源.
    • Sun公司提供了接口: javax.sql.DataSource接口: 连接池规范
    • 连接池的实现:
      • DBCP
      • C3P0
      • Druid
    • DBCP
      • 导包
        • commons-dbcp-x.x.jar
        • commons-pool-x.x.x.jar
      • BasicDataSource: 是DataSource接口的实现类
        • 必选
          • BasicDataSource BasicDataSource(): 创建对象
          • void setDriverClassName(String name): 设置驱动类名
          • void setUrl(String url): 设置连接地址
          • void setUsername(String username): 设置用户名
          • void setPassword(String password): 设置密码
          • Connection getConnection(): 获取连接对象
        • 可选
          • void setMaxActive(int n): 最大连接数量. 程序能够连接数据库的最大连接数量
          • void setMinIdle(int n): 最小空闲连接. 连接池中允许存在的最小空闲数量, 如果小于该数量, 则会创建新的连接, 直到满足该最小空闲连接数
          • void setMaxIdle(int n): 最大空闲连接. 连接池中允许存在的最大空闲数量, 如果超出该数量, 则超出的空闲连接会被真实关闭
          • void setInitialSize(int size): 初始化连接数. 连接池中最初的连接数

      • 改写JDBCUtils
        • 将注册驱动, 获取连接的代码修改为必选4项
        • 将getConnection()方法替换为getDataSource()方法


  • 用户登录注册案例
    • 理解如何分析需求, 将其转换为不同的步骤
    • 注册:
      • 先检查用户名是否存在(SELECT)
        • 如果存在: 注册失败, 提示更换用户名
        • 如果不存在: 直接注册(INSERT INTO)

    • 登录
      • 查询用户表中是否有匹配的用户名和密码(SELECT)
        • 如果存在: 用户已经注册且密码匹配, 登录成功
        • 如果用户名不存在: 用户没有注册或, 登录失败
        • 如果用户名存在, 密码不匹配: 登录失败

    • dao: 操作数据库的类
      • 类名: XxxDao.java


  • 什么是设计模式
    • 对问题处理方式的总结经验, 形成了一种代码设计的模式, 按这种模式不会再出问题, 所以叫做设计模式
  • 所有的设计模式都源于面向对象的思想
  • Java有23种设计模式
  • 单例:
    • 单一实例, single instance, singleton, 目的是保证这个类只存在一个唯一的对象
  • 为什么叫饿汉式:
    • 因为类一加载, 对象就已经创建了, 像一个饿汉见到吃的马上就吃
  • 3个要点
    • 把构造方法私有化
    • 在类中定义一个静态的本类对象, 并且要初始化
    • 提供一个静态的方法getInstance(), 获取单例对象

  • 线程不安全的懒汉式单例
  • 用于解决创建对象的问题
  • 我们以前在创建对象时, 需要根据每个类的构造方法创建对象





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2