• 20145236 《Java程序设计》第九周学习总结


    20145236 《Java程序设计》第九周学习总结

    教材学习内容总结

    第十六章 整合数据库

    JDBC简介

    1.JDBC是java联机数据库的标准规范。它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程序。

    2.JDBC标准主要分为两个部分:JDBC应用程序开发者接口和JDBC驱动程序开发者接口。应用程序需要联机数据库,其相关API主要在java.sql和javax.sql两个包中。

    3.应用程序使用JDBC联机数据库的通用语法:

    Connection conn = DriverManager.getConnection(……);
    Statement st = conn.createStatement();
    ResultSet rs = st.executeQuery("SELECT * FROM T_USER");
    

    4.JDBC希望达到一个“写一个java程序,操作所有数据库”的目的。

    5.驱动器按照操作方式可分为四种类型:

    (1)JDBC-ODBC Bridge Driver :其在Microsoft系统上最为成熟。 
    缺点:ODBC在平台上先设定好,弹性不足;本身也有跨平台限制。 
    (2)Native API Driver:以原生方式,调用数据库提供的原生链接库。 
    缺点:有跨平台限制  
    优点:速度最快 
    (3)JDBC-Net Driver :将JDBC方法调用转换为特定的网络协议调用 
    优点:跨平台 
    缺点:速度慢,获得架构弹性是使用这种类型驱动程序的目的 
    (4)Native Protocol Driver :由数据库厂商直接提供 
    优点:跨平台 ——是最常见的驱动程序类型。
    

    链接数据库

    1.要连接数据库,必须在CLASSPATH中设定驱动程序JAR文档。

    2.基本数据库操作相关JDBC接口或类是为位于java.sql包中。要取得数据库联机,需要进行几个动作:

    (1)注册Driver对象 
    (2)取得Connection操作对象 
    (3)关闭Connection操作对象
    

    3.注册Driver对象
    使用JDBC要求加载.class文档的4种方式:
    (1)使用Class.forName()
    (2)自行建立Driver接口操作类的实例
    (3)启动JVM时指定jdbc.drivers属性
    (4)设定JAR中/services/java.sql.Driver文档

    4.取得Connection操作对象
    Connection接口的操作对象是数据库联机代表对象。其定义了数据库连接时的协议、子协议、数据源识别:

    协议:子协议:数据源识别 
    协议:jdbc 
    子协议:桥接的驱动程序 
    数据源识别:标出数据库的地址、端口号、名称、用户、密码等信息。 
    注意:要使用中文存取必须给定参数useUnicode和characterEncoding。表明是否使用Unicode,并指定字符编码方式。 
    在XML配置文件中,不能直接写&符号,要写成&amp。
    

    使用Statement、ResultSet

    1.Statement是SQL描述的代表对象,可以使用executeUpdate()、executeQuery()等方法来执行SQL。

    2.Statement的executeUpdate()方法用于SELECT等查询数据库的SQL,返回int结果,表示数据变动的笔数

    3.Statement的executeQuery()方法返回java.sql.ResultSet对象,代表查询结果。

    4.Statement的execute()方法用来执行SQL,返回true表示SQL执行将返回ResultSet作为查询结果。

    使用PreparedStatement、CallableStatement

    1.如果有些操作只是SQL语句当中某些参数会有所不同,其余的SQL子句皆相同,则可以使用java.sql.PreparedStatement。调用clearParametere()清除设置的参数,之后就能再次使用这个PreparedStatement实例。

    2.使用PreparedStatement的好处:

    (1)可以将SQL描述预编译为数据库的执行指令,执行速度可以快很多。 
    (2)防止SQL注入
    

    3.如果撰写数据库的预存程序,并想要使用JDBC来调用,则可使用java.sql.CallableStatement。必须调用prepareCall()建立CallableStatement异常,可以使用registerOutParameter()注册输出参数。

    使用DataSource取得联机

    1.让MessageDAO依赖于java.sql.DataSource接口,可以通过其定义的getConnection()方法取得Connection。

    2.日后要修改数据库服务器主机位置,为了打算重复利用Connection对象而想要加入联机池机制等情况,这个MessageDAO都不用修改。

    3.联机相关信息可以使用.properties设定。

    使用ResultSet卷动、更新数据

    1.建立Statement或PreparedStatement实例时,可以指定结果集类型与并行方式。

    createStatement(int resultSetType,int resultSetConcurrency) prepareStatement(String sql,int resultSetType,int resultSetConcurrency)
    

    2.结果集类型resultSetType可以指定3种:

    ResultSet.TYPE _ FORWARD _ ONLY(默认) 
    ResultSet.TYPE _ SCROLL _ INSENSITIVE 
    ResultSet.TYPE _ SCROLL _ SENSITIVE
    

    3.更新设定resultSetConcurrency可以指定2种:

    ResultSet.CONCURREADONLY(默认) 
    ResultSet.CONCUR_UPDATABLE
    

    4.ResultSet进行数据修改的条件限制

    必须选取单一表格 
    必须选取主键 
    必须选取所有NOT NULL的值
    

    批次更新

    1.批次更新的限制是,SQL不能使SELECT,否则会抛出异常。

    2.要支持批次更新,必须在JDBC URL 上附加rewriteBatchedStatements = true 参数才有实际的作用。

    Blob与Clob

    1.BLOB用于存储大量的二进制数据,像是图档、影音档等;CLOB用于存储大量的文字数据。

    2.可以把BLOB字段对应byte[]或输入输出串流。

    交易简介

    1.交易的四个基本原则:

    原子性:若有一个步骤失败,必须撤回曾经执行过的动作,回到交易前的状态 
    一致性:交易作用的数据集合在交易前后必须一致 
    隔离行为:交易与交易之间,必须互不干扰 
    持续性:即使系统挂了,交易的结果也不能遗失
    

    2.在交易管理时,仅想要撤回某个SQL执行点,则可以设定存储点。

    3.数据库可设定指定的隔离行为,可设定常数为:

    TRANSACTION _ UNCOMMITTED: 更新遗失
    最低隔离层级,读取错误数据的几率太高,一般不会采用这种隔离层级。
    TRANSACTION _ COMMITTED: 更新遗失+脏读 
    交易读取的数据必须是其他交易已确认的数据 
    TRANSACTION _ REPEATABLE _ READ: 更新遗失+脏读+无法重复读取
    读取交易在确认前不阻止其他读取交易,,但会阻止其他更新交易。 
    TRANSACTION _ SERIALIZABLE: 更新遗失+脏读+无法重复读取+幻读 交易时若有数据不一致的疑虑,交易必须可以照顺序逐一进行。
    

    4.通过JDBC得知数据库是否支持某个隔离行为设定,可以通过Connection的getMetaData()取得DatabaseMetadata对象,通过DatabaseMetadata的supportTransaction-IsolationLevel()得知是否支持某个隔离行为。

    metadata简介

    Metadata即“诠读数据的数据”,可以通过connection的getMetaData()方法取得DatabaseMetaData对象,可以取得数据库整体信息,而ResultSet表示查询到的数据,可以通过ResultSet的getMetaData()方法,取得ResultSetMetaData对象。

    RowSet简介

    1.javax.sql.RowSet接口,代表数据的列集合。可以对列集合进行增删改查。通过setCommand()设定查询指令,通过execute()执行查询指令以填充数据。

    2.RowSet定义了五个标准列集合子接口:

    (1)jdbcRowSet 
    是联机式的RowSet,保持与数据库的联机,可视为取得、操作RowSet的行为封装。 
    (2)CacheRowSet 
    是脱机式的RowSet,在查询并填充完数据后,会断开与数据源的联机 
    (3)FilteredRowSet 
    可以对列集合进行过滤,实现类似SQL中WHERE等条件式的功能。 
    (4)JoinRowSet 
    可以让你结合两个RowSet对象,可以通过setMatchColumn()指定要结合的行,然后使用addRowSet()来加入RowSet进行结合。 
    (5)WebRowSet 
    是CachedRowSet的子接口,不仅具备脱机操作,还能进行XM读写。
    

    第十七章 反射与类加载器

    运用反射

    反射:.class文档反映了类基本信息,从Class等API取得类信息的方式称为反射。

    Class与.class文档

    1.java.lang.Class的实例代表Java应用程序运行时加载的.class文档,类、接口、Enum等编译过后,都会生成.class文档。Class类没有公开构造函数,实例时候JVM自动产生,每个.class文档加载时,JVM会自动生成对应的Class对象。

    2.取得Class对象的方式:

    (1)通过Object的getClass方法 
    (2)通过.class常量取得每个对象对应的Class对象 
    (3)如果是基本类型,可以使用对应的打包类加上.TYPE取得Class对象
    

    3.默认首次加载.class文档时会执行静态区块。

    4.类信息是在编译时期存储在.class文档,这是java支持执行运行时类型识别的方式。编译时期若使用到相关类,编译程序会检查对应的.class文档中记载的信息,以确定是否可完成编译。执行时期使用某类是,会先检查是否有对应的Class对象,如果没有,会加载对应的.class文档并生成对应的Class实例。

    5.默认使用getClass()或.class取得的Class实例会是同一个对象。

    使用Class.forName()

    1.Class.forName()方法实现动态加载类,可用字符串指定类名称来获得类相关信息。

    2.Class.forName()另一个版本可以让指定类名称、加载类时是否执行静态区块与类加载器。

    static Class forName(String name,boolean initialize,ClassLoader loader)
    

    从Class获得信息

    Class对象代表加载的.class文档,取得Class对象后,就可以取得.class文档中加载的信息,像是包、构造函数、方法成员、数据成员等类型。

    从Class建立对象

    1.事先不知道类名称时,可以利用Class.forName()动态加载.class文档,取得Class对象之后,利用其newInstance()方法建立类实例。

    Class clz = Class.forName(args[0]); Object obj = clz.newInstance();
    

    2.若类定义有多个构造函数,也可以指定使用哪个构造函数生成对象,这必须在调用Class的getConstructor()方法时指定参数类型,取得代表构造函数的Constructor对象,利用Constructor的newInstance()指定创建时的参数值来建立对象。

    3.生成数组:数组的Class实例是由JVM生成,也可以通过.class或getClass()取得Class实例。生成动态生成长度为10的java.util.ArrayList数组:

    Class clz = java.util.ArrayList.class; Object obj = Array.newInstance(clz,10);
    

    4.从第一个索引取得被手机对象实际的Class实例,此时就可以用它配合Array.newInstance()建立数组实例。

    操作对象方法与成员

    1.可以使用invoke()方法来动态调用指定的方法。

    2.调用受把保护或私有方法,可以使用Class的getDeclaredMethod()取得方法,并在调用Method的setAccessible()时指定为true。

    动态代理

    1.在反射API中有个Proxy类,可动态建立接口的操作对象。

    2.使用代理机制有两种代理方式:静态代理和动态代理。

    3.静态代理
    在静态代理实现中,代理对象与被代理对象必须实现同一接口,在代理对象中可以实现日志服务,必要时调用被代理对象,,可以这样使用代理对象:

    Hello proxy = new HelloProxy(new HelloSpeaker()); proxy.hello("Justin");
    

    创建代理对象HelloProxy时必须指定被代理对象HelloSpeaker,代理对象代理HelloSpeaker执行hello方法。
    静态代理必须为个别接口操作出个别代理类,在应用程序行为复杂时,多个接口必须定义多个代理对象,操作与维护代理对象会有不少的负担。

    4.动态代理
    使用动态代理机制,可使用一个处理者代理多个接口的操作对象,处理者类必须操作java.lang.reflect.InvocationHandler接口。
    使用Proxy.newPrxyInstance()方法建立代理对象,调用时必须指定类加载器,告知要代理的接口,以及接口上定义方法被调用时的处理者,Proxy.newPrxyInstance()方法底层会使用原生方式生成代理对象的Class实例,并利用它来生成代理对象。

    了解类加载器

    类加载器实际的职责就载入.class文档,JDK本身有默认的类加载器。

    类加载器层级架构

    1.Bootstrap Loader:产生Exrtended Loader和System Loader
    Exrtended Loader:父加载器为Bootstrap Loader
    System Loader:父加载器为Exrtended Loader

    2.Bootstrap Loader通常由C撰写而成。若是Oracle的JDK,Bootstrap Loader会搜索系统参数sun.boot.class.path中指定位置的类,默认是JRE目录的classes中的.class文档,或lib目录中.jar文档里的类。

    3.Exrtended Loader由Java撰写而成,会搜索系统参数java.ext.dirs中指定位置的类,默认是JRE目录libextclasses中的.class文档。

    4.System Loader由Java撰写而成,会搜索系统参数java.class.path中指定位置的类,也就是CLASSPATH路径,默认是当前工作路径下的.class文档。

    5.加载类是会以Bootstrap Loader->Exrtended Loader->System Loader的顺序寻找类,如果所有类加载器都找不到指定类,就会抛出java.lang.NoClassDefFoundError.

    6.对null调用getParent()方法会抛出NullPointedException异常。

    7.ClassLoader可以使用loadClass()方法加载类,使用localClass方法加载类时,默认不会执行静态区块,真正使用类建立实例时才会执行静态区块。

    建立ClassLoader实例

    1.使用URLClassLoader来产生新的类加载器,需要java.net.URL作为其参数来指定类加载的搜索路径。使用URLClassLoader的loadClass()方法加载指定类时,会先委托父加载器代为搜索。

    2.由同一类加载器载入的.class文档,只会有一个Class实例。如果同一.class文档由两个不同的类加载器载入,则会有两份不同的Class实例。

    3.path可以输入不在System Loader以上层级类加载器搜索路径的其他路径。

    第十八章 自定义泛型、枚举与注释

    自定义泛型

    泛型定义:

    (1)仅定义在方法上的泛型语法 
    (2)用来限制泛型可用类型的extends与super关键字
    (3)?类型通配字符的使用
    

    使用extends与?

    1.若extends之后指定了类与接口,想再指定其他接口,可以使用&连接。

    2.如果B是A的子类,而Node< B>可视为一种Node< A>,则称Node具有共变性或有弹性的。Java泛型不具有共变性,可以使用类型通配字符?与extends来声明变量,使其达到类似的共变性。

    3.若声明?不搭配extends,则默认为? extends Object。

    Node<?> node = null;//相当于Node<? extends Object>
    

    4.java的泛型语法在执行时期实际上只会知道是Object类型,由于无法在执行时期获得类型信息,编译程序只能就编译时期看到的类型来做检查,因而造成以上谈及的限制。

    使用super与?

    1.如果B是A的子类,而Node< A>可视为一种Node< B>,则称为Node具有逆变性。Java泛型不具有逆变性,可以使用类型通配字符?与super来声明,使其达到类似的逆变性的效果。

    2.若泛型类或接口不具共变性或逆变性,则称为不可变的或严谨的。

    自定义枚举

    了解java.lang.Enum类

    1.直接撰写程序继承Enum类会被编译程序拒绝。

    2.Enum是个抽象类,无法直接实例化,它操作了Comparable接口。Action的构造函数被声明为private,因此只能在Action类中调用。

    3.在JDK1.4之前撰写的API,仍是使用interface定义常数作为枚举值。

    4.Enum的equals()方法与hashCode()方法基本上继承了Object的行为,但被标示为final。由于标示为final,所以定义枚举是,不能重新操作equals()与hashCode(),这是因为枚举成员,在JVM中智慧存在单一实例,Object定义的equals()与hashCode()作为对象相等性比较是适当的定义。

    enum高级运用

    1.values()方法,将内部维护Action枚举实例的数据复制后返回。如果想要知道有哪些枚举成员,就可以使用这个方法。

    2.Enum类可以自行定义构造函数,但不得为公开构造函数,也不可以在构造函数中调用super()。

    3.在enum中调用构造函数比较特别,直接在枚举成员后加上括号,就可以指定构造函数需要的自变量。

    4.在static区块中,编译程序仍自行维护name与ordinal的值,接着才是调用自定义构造函数时传入的value值。

    5.特定值类本体语法:在枚举成员后,直接加上{}操作Command的execute()方法,这代表着每个枚举实例都会有不同的execute()曹组欧,在职责分配上,比switch的方式清楚许多。特定值类本体语法不仅在操作接口时可以使用,,也可以运用在重新定义父类方法。

    关于注释

    在原始码中使用注释,对编译程序提供额外编译提示,或提供应用程序执行时期可读取的组态信息。注释可以仅用于原始码,编译后留在.class文档仅供编译程序读取或开放执行时期读取。

    常用标准注释

    1.@Override
    就是标准注释,被注释的方法必须是父类或接口中已定义的方法,请编译程序协助是否真的为重新定义方法。

    2.@Deprecated
    如果某个方法原先存在与API中,后来不建议再使用,可以在该方法上注释。若有用户后续想调用或重新定义这个方法,编译程序会提出警告。对于支持泛型的API,建议明确指定泛型真正类型,如果没有指定,编译程序会提出警告。

    3.@SuppressWarnings
    指定抑制unchecked的警告产生:

    @SuppressWarnings(value={"unchecked"})

    4.@SafeVarargs
    表明开发人员确定避免了heap pollution问题。heap pollution问题就是编译程序无法检查执行时期的类型错误,无法具体确认自变量类型。

    5.@FunctionalInterface
    让编译程序可协助检查interface是否可做为lambda的目标类型

    自定义注释类型

    1.标示注释:就是注释名称本身就是信息,对编译程序或应用程序来说,主要是检查是否有注释出现,并作出对应的动作。

    2.相关规则:

    (1)如果注释名称本身无法提供足够信息,设置单值注释 
    (2)注释属性也可以用数组形式指定。 
    (3)在定义注释属性时,如果属性名称为value,则可以省略属性名称,直接指定值。 
    (4)对成员设定默认值,使用default关键字即可。 
    (5)要设定数组默认值,可以在default之后加上{},必要时{}中可放置元素值。
    

    3.定义注释时,可使用java.lang.annotation.Target限定时可指定java.lang.annotation.ElementType的枚举值。

    4.在制作JavaDoc文件时,默认不会将注释数据加入文件中,如果想要将注释数据加入文件,可以使用java.lang.annotation.Documented。

    5.默认父类设定的注释,不会被继承至子类,在定义注释时,设定java.lang.annotation.Inherited注释,就可以让注释被子类继承。

    JDK8标注增强功能

    1.ElementType的枚举成员是用来限定哪个声明位置可以进行标注。在JDK8中,增加了两个枚举成员TYPE _PARAMETER、TYPE _USE。

    2.ElementType.TYPE _ USE可用于标注在各式类型,一个标注如果被设定为ElementType.TYPE_USE,只要是类型名称,都可以进行标注。

    3.@Repeatable
    可以让你在同一个位置重复相同标注

    4.@Filters
    作为收集重复标注信息的容器,而每个@Filters储存各自指定的字符串值。

    执行时期读取注释信息

    1.自定义注释,默认会将注释信息存储于.class文档,可被编译程序或位码分析工具读取,但执行时期无法读取注释信息,在执行时期读取注释信息,可以使用java.lang.annotation.Retention搭配java.lang.annotation.RetentionPolicy枚举指定。

    2.RetentionPolicy为RUNTIME的时机,在于让注释在执行时期提供应用程序信息,可使用java.lang.reflect.AnnotatedElement接口操作对象取得注释信息。

    3.JDK 8中新增了getDeclaredAnnotation()、getDeclaredAnnotationsByType()、getAnnotationsByType()三个方法。
    getDeclaredAnnotation()可以让你取回指定的标注,在指定@Repeatable的标注时,会寻找收集重复标注的容器。
    getDeclaredAnnotationsByType()、getAnnotationsByType()就不会处理@Repeatable的标记。

    代码调试中的问题和解决过程

    import java.util.logging.*;
    
    public class LoggerTest {
        public static void main(String[] args) {
            Logger log = Logger.getLogger("lavasoft" );
            log.setLevel(Level.INFO);
            Logger log1 = Logger.getLogger("lavasoft" );
            System.out.println(log==log1);     //true
            Logger log2 = Logger.getLogger("lavasoft.blog" );
            log2.setLevel(Level.WARNING);
    
            log.info("aaa" );
            log2.info("bbb" );
            log2.fine("fine" );
        }
    }
    
    • 运行结果:

    当把log2.setLevel(Level.WARNING);这一行注释掉之后,发现运行结果变成了:

    本周代码托管截图

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 200/200 2/2 20/20
    第二周 300/500 2/4 18/38
    第三周 500/1000 1/5 22/60
    第四周 500/1500 1/6 30/90
    第五周 500/2000 1/7 20/110
    第六周 500/2500 2/9 20/130
    第七周 500/3000 2/11 20/150
    第八周 300/3300 2/13 20/170
    第九周 300/3600 2/15 20/190
  • 相关阅读:
    C# Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
    C# Collection was modified;enumeration operation may not execute
    C# 写文件
    AJAX 入门教程
    ABP 软删除ISoftDelete
    C# 随机列表
    C# ConfigurationManager 类的使用
    mui 关闭当前窗口
    C# 委托
    VSTO:使用C#开发Excel、Word【13】
  • 原文地址:https://www.cnblogs.com/feng886779/p/5437226.html
Copyright © 2020-2023  润新知