A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 小石姐姐 于 2018-1-12 11:12 编辑

反射到数据库知识点





Java进阶(反射, JavaBean, BeanUtils工具类)反射机制概述, 获取字节码对象的3种方式
  • 反射:
    • Reflection. 在程序运行时, 获取任何一个类的所有属性和方法(包括私有的), 调用任意一个对象的所有属性和方法(包括私有的)
  • 反射的前提
    • 获取类的字节码对象
  • 获取字节码对象的3种方法
    • 对象.getClass()
    • 类名.class
    • Class.forName(String clasName)

反射获取构造方法并创建对象
  • 反射使用的相关类和方法

    • java.lang.Class类: 类的字节码对象
      • 获取构造方法
        • Constructor<?>[] getConstructors(): 以数组形式返回该类中所有public的构造方法. 如果没有public的, 则数组长度为0
        • Constructor<?>[] getDeclaredConstructors(): 以数组形式返回该类中所有权限的构造方法, 包括private的. 如果该类是接口, 基本类型, 数组, void, 则数组长度为0
        • Constructor<T> getConstructor(Class<?>... parameterTypes): 根据参数列表返回指定的public的构造方法. 参数列表填写参数的字节码对象
        • Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes): 根据参数列表返回指定的所有权限的构造方法, 包括private的. 参数列表填写参数的字节码对象
      • 创建对象
        • T newInstance(): 使用该类的无参构造创建一个对象

    • java.lang.reflect.Constructor类: 构造方法对象
      • T newInstance(): 通过无参构造方法对象创建一个类的对象
      • T newInstance(Object... initargs): 通过有参构造方法对象创建一个类的对象, 传入构造方法所需的参数列表
      • void setAccessible(boolean canAccess): 设置为true时禁用Java的访问安全检查, 可以访问所有权限的构造方法

  • 注意:

    • Class类和Constructor类中都有T newInstance()方法, 都使用类的无参构造创建对象
  • 反射获取一个类的构造方法的步骤
    • 获取该类Class字节码对象(3种方式)
    • 通过Class对象获取构Constructor造方法对象
    • 通过Constructor对象创建该类的对象


反射获取public成员变量: 设置和获取值
  • Class类中获取成员变量的方法
    • Field[] getFields(): 获取所有public的成员变量
    • Field[] getDeclaredFields(): 获取所有权限的成员变量, 包括private的
    • Field getField(String fieldName): 通过指定的成员变量名获取指定的public的成员变量
    • Field getDeclaredField(String fieldName): 通过指定的成员变量名获取指定的所有权限的成员变量, 包括private的
  • java.lang.reflect.Field类: 成员变量对象
    • Object get(Object obj): 获取指定对象的属性值
    • void set(Object obj, Object value): 将指定对象的属性值设置为指定的值
    • void setAccessible(boolean canAccess): 设置为true时禁用Java的访问安全检查, 可以访问所有权限的成员属性
  • 反射获取一个类的public成员变量的步骤
    • 获取该类Class字节码对象(3种方式)
    • 通过Class对象调用newInstance()方法创建该类的对象
    • 通过Class对象调用获取成员属性的方法获取属性对象
    • 通过Field对象设置或获取属性值

反射获取私有成员变量并修改
  • 反射获取非public成员变量并修改的步骤
    • 获取该类Class字节码对象(3种方式)
    • 通过Class对象调用newInstance()方法创建该类的对象
    • 通过Class对象调用获取成员属性的方法获取属性对象
    • 设置Field对象的访问权限(也叫作暴力访问)
      • void setAccessible(boolean canAccess): 设置为true时可以访问所有权限的成员属性
    • 通过Field对象设置或获取属性值
  • 小结
    • getXxx(): 只能得到public的属性或方法
    • getDeclaredXxx(): 可以得到所有权限的属性或方法. 但如果访问权限不足, 则无法操作
    • setAccessible(true): 获取成员变量, 构造方法, 成员方法的访问权限


反射获取成员方法并调用
  • 获取成员方法
    • Method[] getMethods(): 返回所有public的方法数组
    • Method[] getDeclaredMethods(): 返回所有权限的方法数组
    • Method getMethod(String name, Class<?>... parameterTypes): 获取public的方法, 传入方法名和方法形参字节码对象
    • Method getDeclaredMethod(String name, Class<?>... parameterTypes): 获取所有权限的指定方法, 传入方法名和方法形参字节码对象
  • java.lang.reflect.Method类: 成员方法对象 *Object invoke(Object obj, Object... args): 调用指定对象的成员方法 *void setAccessible(boolean canAccess): 设置为true时禁用Java的访问安全检查, 可以访问所有权限的成员方法
  • 反射获取成员方法并调用的步骤
    • 获取该类Class字节码对象(3种方式)
    • 通过Class对象调用newInstance()方法创建该类的对象
    • 通过Class对象调用获取成员方法的方法获取方法对象
    • 使用Method对象的Object invoke(Object obj, Object... args)方法调用方法, 传入该类的对象和参数, 返回方法的返回值
  • 私有方法, 也是setAccessible(true)获取访问权限
--=
JavaBean概述和规范
  • JavaBean:
    • 概念: 就是一个类
    • 作用: 封装数据
    • 规范:
      • 类必须是public修饰的
      • 通过private的成员变量保存数据
      • 通过public的get/set方法操作数据
      • 至少提供一个无参构造方法
      • 实现Serializable接口(用于写入文件中)


BeanUtils概述和jar包
  • jar包
    • Java ARchive, 一个后缀名为.jar的文件, 类似于rar, 是一个压缩文件, 只不过专门用于压缩Java项目, 所以叫jar
    • 作用
      • jar包中是写好的代码编译出来的class文件, 有了这些类文件, 就可以调用其中的方法
    • jar包从哪里来?
      • 相关类库的官方网站上下载
      • 自己导出jar包
    • 如何使用jar包?
      • 项目根目录下创建名为lib的目录
      • 复制jar文件, 粘贴到项目根目录下的lib目录下
      • 选中项目中的jar包, 右键, 选择Build Path, 点击Add to Build Path. 此时项目中的Referenced Libraries中会出现jar包名称的奶瓶, 说明已经添加成功
      • 导入的jar包整个项目都能使用

  • BeanUtils
    • Apache组织提供的第三方类库Commons中的一个组件
    • 作用:
      • 利用反射技术给一个类的对象的成员属性赋值或获取值, 用于快速封装数据到JavaBean
    • 使用BeanUtils所需jar包
      • commons-beanutils
      • commons-logging


BeanUtils的常用方法
  • org.apache.commons.beanutils.BeanUtils类
    • 常用静态方法
      • static void setProperty(Object bean, String name, Object value): 给对象的成员属性赋值. 传入对象, 成员属性名, 属性值
      • static String getProperty(Object bean, String name): 获取对象成员属性值. 传入对象, 成员属性名, 返回属性值的字符串形式
      • static void populate(Object bean, Map properties): 批量给对象的成员属性赋值, 传入对象, Map的key是属性名, value是属性值

  • BeanUtils的setProperty和getProperty原理
    • 方法底层是通过调用JavaBean的public的get/set方法来获取和设置属性
    • get/set方法是通过反射来找到的
    • 所以如果没有get/set方法则会报错
数据库 MySQL SQL语句




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

  • MySQL
    • 安装
    • 配置和遇到的问题
    • 命令行的登录和退出
      • 登录: mysql -u 用户名 -p
      • 退出: 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工具类的自定义
              • 在静态代码块中初始化连接对象
              • 定义方法获取连接对象, 释放资源

            今日重点
            • 高级SQL语句
              • 排序ORDER BY
              • 聚合函数
                • SUM()
                • COUNT()
                • MIN()
                • MAX()
                • AVG()
              • 分组: GROUP BY 列名 HAVING 条件
            • JDBC
              • 数据库驱动和JDBC原理: 多态的调用
              • 代码:
                • JDBC操作的6个步骤:
                  • (先导入jar包) 注册驱动
                  • 获取连接
                  • 获取执行平台
                  • 执行SQL语句
                  • 处理结果
                  • 释放资源
                • 执行平台
                  • Statement(不能用)
                  • PreparedStatement(重点)













1 个回复

正序浏览
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马