20145234黄斐《Java程序设计》第九周

教材学习内容总结

整合数据库

JDBC入门

  • JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作,开发人员无须接触底层数据库驱动程序的差异性,数据库本身是个独立运行的应用程序,你撰写的应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找。通常你的应用程序会利用一组专门与数据库进行通信协议的链接库,以简化与数据库沟通时的程序撰写。有时候,更换数据库的需求并不是没有,应用程序跨平台也是经常的需求,JDBC基本上就是用来解决这些问题的。JDBC是Java联机数据库的标准规范。具体而言,它定义了一组标准类与接口,应用程序需要联机数据库时调用这组标准API,而标准API中的接口由数据库厂商操作,通常称为JDBC驱动程序。
  • 数据库本身是个独立运行的应用程序
    • 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找
    • JDBC(Java DataBase Connectivity)是Java联机数据库的标准规范
    • 定义一组标准类与接口,应用程序需要联机数据库时调用这组标准API,标准API中接口会由数据库厂商操作,称为JDBC驱动程序
    • JDBC标准分为两部分
    • JDBC应用程序开发者接口
    • JDBC驱动程序开发者接口
    • 依操作方式可将驱动程序分为四种类型:JDBC-ODBC Bridge Driver;Native API Driver;JDBC-Net Driver;Native Protocol Driver
    • Connection接口的操作对象是数据库联机代表对象,要取得Connection操作对象,可以通过DriverManager的getConnection(),除了基本的用户名称、密码之外,还必须提供JDBC URL,其定义了连接数据库时的协议、子协议、数据源识别
    • 取得Connection对象之后,可以使用isClosed()方法测试与数据库连接是否关闭。在操作完之后,若确定不再需要连接,则必须使用close()来关闭与数据库的连接,以释放链接是相关的必要资源。
  • 连接数据库
    • 为了要连接数据库系统,必须要有厂商操作的JDBC驱动程序,必须在CLASSPATH中设定驱动程序JAR文档。
  • 使用Statement、ResultSet
    • Connection是数据库连接的代表对象,接下来要执行SQL的话,必须取得java.sql.Statement操作对象,它是SQL描述的代表对象。Statement的execute()可以用来执行SQL,并可以测试SQL是执行查询或更新,返回true表示SQL执行将返回ResultSet作为查询结果。视需求而定,Statement或者ResultSet在不使用时,可以使用close()将之关闭,以释放相关资源。Statement关闭时,所关联的ResultSet也会自动关闭。
  • 使用PreparedStatement、CallableStatement
    • 如果有些操作只是SQL语句当中某些参数会有所不同,其余的SQL子句皆相同,则可以使用java.sql.PreparedStatement。可以使用Connection的PreparedStatement()方法建立好预先编译的SQL语句,当中参数会变动的部分,先指定“?”这个占位字符。
    • 在JDBC里要表示日期,是使用java.sql.Date,其日期格式是“年、月、日”,要表示时间的话则是使用java.sql.Time,其时间格式为“时、分、秒”,如果要表示“时、分、秒、微秒”的格式,你可以使用java.sql.Timestamp

JDBC进阶

  • 在ResultSet时,默认可以使用next()移动数据光标至下一笔数据,而后使用getXXX()方法来取得数据
    在数据光标移动的API上,可以使用absolute()、afterLast()、beforeFirst()、first()、last()进行绝对位置移动,使用relative()、previous()、next()进行相对位置移动,移动成功返回true。可使用isAfterLast()、isBeforeFirst()、isFrist()、isLast()判断当前位置。
  • 交易的四个基本要求
    • 原子性、一致性、隔离行为与持续性。当多个交易并行时,可能引发的数据不一致问题有哪些呢?
    • 更新遗失:基本上就是指某个交易对字段进行更新的信息,因另一个交易的介入而遗失更新效力。
    • 脏读:两个交易同时进行时,其中一个交易更新数据但未确认,另一个交易就读取数据,就有可能发生脏读问题。
    • 无法重复的读取:某个交易两次读取同一字段的数据并不一致。
    • 幻读:同一交易期间,读取到的数据笔数不一致。
  • 批次更新
    • 每一次执行executeUpdate(),其实都会向数据库发送一次SQL,如果大量更新的SQL有一万笔,就等于通过网络进行了一万次的信息传送,网络传送信息实际上必须打开I/O、进行路由等动作。所以最好就是所有收集的SQL,最后会串为一句SQL,然后传送给数据库,既然是批次更新,顾名思义,就是仅用在更新上,所以批次更新的限制是,SQL不能是SELECT,否则会抛出异常。
  • Blob与Clob
    • JDBC中提供了java.sql.Blob与java.sql.Clob两个类分别代表BLOB与CLOB数据
    • 通过PreparedStatement的setBlob()来设定Blob对象,读取数据时,可以通过ResultSet的getBlob()取得Blob对象

反射与类加载器

运用反射

  • Java真正需要某个类时才会加载对应的.class文档,而非在程序启动就加载所有类。java.lang.Class的实例代表Java应用程序运行时加载的.class文档。可以通过Object的getClass()方法,或者通过.class常量取得每个对象对应的Class对象,如果是基本类型,也可以使用对应的打包类加上.TYPE取得Class对象。例如:Integer.TYPE可取得代表int的Class对象。如果事先不知道类名称,可以利用Class.forName()动态加载.class文档,取得Class对象之后,利用其newInstance()方法建立类实例。java.lang.reflect.Method实例是方法的代表对象,可以使用invoke()方法来动态调用指定的方法。

了解类加载器

  • 类加载指的是将类的class文件读入JVM,并为之创建一个Class对象。类连接指的是把类的二进制数据合并到JRE中,这又分为3个阶段
    • 校验:检查载入Class文件数据的正确性。
    • 准备:给类的静态变量分配存储空间,并进行默认初始化。
    • 解析:将类的二进制数据中的符号引用替换成直接引用。初始化指的是对类的静态变量、静态初始化块进行初始化。

自定义泛型、枚举与注释

自定义泛型

  • 泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在调用时传入具体的类型(类型实参)。

自定义枚举

  • 创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类(java.lang.Enum 是一个抽象类)。
  • 定义enum时可以自定义构造函数,条件是不得为公开(public)构造函数,也不可以在构造函数中调用super(),定义enum时有个特定值类本体语法,可用于操作接口或重新定义父类方法。

 

注释

    • 在原始码中使用注释,对编译程序提供额外编译提示,或提供应用程序执行时期可读取的组态信息。注释可以仅用于原始码,编译后留在.class文档仅供编译程序读取或开放执行时期读取。
    • 常用标准注释
      • @Override //就是标准注释,被注释的方法必须是父类或接口中已定义的方法,请编译程序协助是否真的为重新定义方法。
      • @Deprecated //如果某个方法原先存在与API中,后来不建议再使用,可以在该方法上注释。若有用户后续想调用或重新定义这个方法,编译程序会提出警告。对于支持泛型的API,建议明确指定泛型真正类型,如果没有指定,编译程序会提出警告。
      • @SuppressWarnings //指定抑制unchecked的警告产生: @SuppressWarnings(value={"unchecked"})
      • @SafeVarargs //表明开发人员确定避免了heap pollution问题。heap pollution问题就是编译程序无法检查执行时期的类型错误,无法具体确认自变量类型。
      • @FunctionalInterface //让编译程序可协助检查interface是否可做为lambda的目标类型 自定义注释类型 ·标示注释:就是注释名称本身就是信息,对编译程序或应用程序来说,主要是检查是否有注释出现,并作出对应的动作。
    • 相关规则:
      • 如果注释名称本身无法提供足够信息,设置单值注释
      • 注释属性也可以用数组形式指定。
      • 在定义注释属性时,如果属性名称为value,则可以省略属性名称,直接指定值。
      • 对成员设定默认值,使用default关键字即可。
      • 要设定数组默认值,可以在default之后加上{},必要时{}中可放置元素值。
    • 定义注释时,可使用java.lang.annotation.Target限定时可指定java.lang.annotation.ElementType的枚举值。 在制作JavaDoc文件时,默认不会将注释数据加入文件中,如果想要将注释数据加入文件,可以使用java.lang.annotation.Documented。 默认父类设定的注释,不会被继承至子类,在定义注释时,设定java.lang.annotation.Inherited注释,就可以让注释被子类继承。

教材中的问题与解决过程

  • 问题1:幻读与无法重复的读取,隔离层级“可重复读取”、“可循序”如何区分?
  • 问题1解决方案:“可重复读取”针对两次交易读取数据不一致,同一交易读取数据必须相同的情况,“可循序”针对同一交易期间读取到的数据不一致,在数据不一致时,交易可以照顺序逐一进行。
  • 问题2:默认会将注释信息存储于.class文档,可被编译程序或位码分析工具读取,但执行时期无法读取注释信息,在执行时期读取注释信息,用什么方式?
  • 问题2解决方案:可以使用java.lang.annotation.Retention搭配java.lang.annotation.RetentionPolicy枚举指定。

代码托管

上周考试错题解析

自评:7

  1. 教材学习中的问题和解决过程, 一个问题加1分
  2. 本周有效代码超过300分行的(加2分)
  3. -排版精美的加一分
  4. -进度条中记录学习时间与改进情况的加1分
  5. -错题学习深入的加1分

学习进度条

 

posted @ 2017-04-23 20:04  20145234黄斐  阅读(232)  评论(5编辑  收藏  举报