20145306《java程序设计》第九周学习总结
教材学习内容总结
第十六章
一、JDBC入门
1.JDBC简介
JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作,开发人员无须接触底层数据库驱动程序的差异性,数据库本身是个独立运行的应用程序,你撰写的应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找。通常你的应用程序会利用一组专门与数据库进行通信协议的链接库,以简化与数据库沟通时的程序撰写。有时候,更换数据库的需求并不是没有,应用程序跨平台也是经常的需求,JDBC基本上就是用来解决这些问题的。JDBC是Java联机数据库的标准规范。具体而言,它定义了一组标准类与接口,应用程序需要联机数据库时调用这组标准API,而标准API中的接口由数据库厂商操作,通常称为JDBC驱动程序。JDBC标准主要分为两个部分:JDBC应用程序开发者接口以及JDBC驱动程序开发者接口。如果你的应用程序需要联机数据库,就是调用JDBC应用程序开发者接口,相关API主要在java.sql与javax.sql两个包中,JDBC驱动程序开发者接口是数据库厂商操作驱动程序时的规范。如果有一段程序代码,它的作用是联机MySQL数据库,则需要在CLASSPATH中设定JDBC驱动程序,具体来说,就是在CLASSPATH中设定一个JAR文档,如果将来要换为Oracle数据库,只要置换Oracle驱动程序,具体来说就是在CLASSPATH改设为Oracle驱动程序的JAR文档,然而应用程序本身不用修改。JDBC希望达到的目的,是让Java程序设计员在撰写数据库操作程序时,可以有个统一的接口,无须依赖特定数据库的API,希望达到“写一个Java程序,操作所有数据库”的目的。厂商在操作JDBC驱动程序时,依操作方式可将驱动程序分为四种类型:(1)JDBC-ODBC Bridge Driver ,它是由Microsoft主导的数据库连接标准,基本上JDBC是参考ODBC制订而来,所以ODBC在Microsoft系统上最为成熟,不过由于JDBC与ODBC并未一一对应,所以部分调用无法直接转换,因此ODBC驱动程序本身也有跨平台限制。(2)Native API Driver,这个类型的驱动程序会以原生方式,调用数据库提供的原生链接库,在速度上是4种类型中最快的,但没有跨平台性。(3)JDBC-Net Driver,这类型的JDBC驱动程序会将JDBC方法调用转换为特定的网络协议调用,这种方式弹性高,具有跨平台性。(4)Native Protocol Driver ,这种方式可以跨平台,在效能上也有不错的表现,在不需要如(3)获得架构上的弹性时,通常会使用这种类型驱动程序,算是最常见的驱动程序类型。
2.连接数据库
为了要连接数据库系统,必须要有厂商操作的JDBC驱动程序,必须在CLASSPATH中设定驱动程序JAR文档。
3.使用Statement、ResultSet
Connection是数据库连接的代表对象,接下来要执行SQL的话,必须取得java.sql.Statement操作对象,它是SQL描述的代表对象。Statement的execute()可以用来执行SQL,并可以测试SQL是执行查询或更新,返回true表示SQL执行将返回ResultSet作为查询结果。视需求而定,Statement或者ResultSet在不使用时,可以使用close()将之关闭,以释放相关资源。Statement关闭时,所关联的ResultSet也会自动关闭。
4.使用PreparedStatement、CallableStatement
如果有些操作只是SQL语句当中某些参数会有所不同,其余的SQL子句皆相同,则可以使用java.sql.PreparedStatement。可以使用Connection的PreparedStatement()方法建立好预先编译的SQL语句,当中参数会变动的部分,先指定“?”这个占位字符。在JDBC里要表示日期,是使用java.sql.Date,其日期格式是“年、月、日”,要表示时间的话则是使用java.sql.Time,其时间格式为“时、分、秒”,如果要表示“时、分、秒、微秒”的格式,你可以使用java.sql.Timestamp。
二、JDBC进阶
1.使用ResultSet卷动、更新数据
在ResultSet时,默认可以使用next()移动数据光标至下一笔数据,而后使用getXXX()方法来取得数据。结果集类型可以指定3种设定:ResultSet.TYPEFORWARDONLY(默认)、ResultSet.TYPESCROLLINSENSITIVE、ResultSet.TYPESCROLLSENSITIVE。更新设定可以有两种指定:ResultSet.CONCURREADONLY(默认)、ResultSet.CONCUR_UPDATABLE。如果要使用ResultSet进行数据修改,则有些条件限制:必须选取单一表格、必须选取主键、必须选取所有NOT NULL的值。
2.批次更新
每一次执行executeUpdate(),其实都会向数据库发送一次SQL,如果大量更新的SQL有一万笔,就等于通过网络进行了一万次的信息传送,网络传送信息实际上必须打开I/O、进行路由等动作。所以最好就是所有收集的SQL,最后会串为一句SQL,然后传送给数据库,既然是批次更新,顾名思义,就是仅用在更新上,所以批次更新的限制是,SQL不能是SELECT,否则会抛出异常。
3.Blob与Clob
如果要将文档写入数据库,可以在数据库表格字段上使用BLOB或CLOB数据类型,BLOB用于存储大量二进制数据,像是图档、影音档等,CLOB用于存储大量的文字数据。
4.交易简介
交易的四个基本要求是原子性、一致性、隔离行为与持续性。当多个交易并行时,可能引发的数据不一致问题有哪些呢?(1)更新遗失:基本上就是指某个交易对字段进行更新的信息,因另一个交易的介入而遗失更新效力。(2)脏读:两个交易同时进行时,其中一个交易更新数据但未确认,另一个交易就读取数据,就有可能发生脏读问题。(3)无法重复的读取:某个交易两次读取同一字段的数据并不一致。(4)幻读:同一交易期间,读取到的数据笔数不一致。
5.metadata简介
Metadata即“诠读数据的数据”,数据库是用来存储数据的地方,然而数据库本身产品名称为何?数据库中有几个数据表格?表格名称为何?表格中有几个字段等?这些都是metadata。
6.RowSet简介
JDBC定义了java.sql.RowSet接口,用以代表数据的列集合,这里的数据并不一定是数据库中的数据,可以是电子表格数据、XML数据或任何具有列集合概念的数据源。RowSet定义了列集合基本行为,其下有JdbcRowSet、CachedRowSet、FilteredRowSet、JoinRowSet、WebRowSet五个标准列集合子接口。JdbcRowSet是联机式的RowSet,也就是操作JdbcRowSet期间,会保持与数据库的联机,可视为取得、操作ResultSet的行为封装,可简化JDBC程序的撰写,或作为JavaBean使用。CachedRowSet为脱机式的RowSet,在查询并填充完数据后,就会断开与数据源的联机,而不用占据相关联机资源,必要时也可以再与数据源联机进行数据同步。
第十七章
一、运用反射
1.反射
当我们使用一个类,如果这个类还未加载到内存中,系统会通过加载、连接、初始化对类进行初始化。
二、了解类加载器
1.类加载器层级架构
类加载指的是将类的class文件读入JVM,并为之创建一个Class对象。类连接指的是把类的二进制数据合并到JRE中,这又分为3个阶段:(1)校验:检查载入Class文件数据的正确性。(2)准备:给类的静态变量分配存储空间,并进行默认初始化。(3)解析:将类的二进制数据中的符号引用替换成直接引用。初始化指的是对类的静态变量、静态初始化块进行初始化。
注意:
a.一个final类型的静态属性,如果在编译时已经得到了属性值,那么调用该属性时,不会导致该类初始化,因为这个相当于使用常量。
b.使用ClassLoader()方法,只是加载该类,并未初始化。
类加载器就是负责将.class文件加载到内存中,并为之生成对应的java.lang.Class对象,它负责加载所有的类,而一旦一个类被加载入JVM中,就不会被再次载入了。在Java中,一个类用其全限定类名(即包名+类名)作为标识。JVM运行时会产生3个ClassLoader,分别为:BootstrapClassLoader(根类加载器)、ExtClassLoader(扩展类加载器)和AppClassLoader(系统类加载器)。
其中,BootstrapClassLoader负责加载JRE的核心类库,它不是ClassLoader的子类,使用C++编写,因此我们在Java中看不到它,通过其子类的getParent()方法获取时,将返回null,BootstrapClassLoader负责装载JRE目标下的rt.jar、charsets.jar等Java核心类库。
第十八章
一、自定义泛型
1.泛型
在JDK1.5版本之前,如果在集合中添加了不同类型的数据,需要在程序的运行期间对类型之间的转换进行检查。
例如:
List arrayList=new arrayList();
在arrayList中添加String类型的对象和Integer对象,但是我们定义如下一个数组 String[] values=new String[arrayList.size()]; 如果想要把arrayList转换成数组的话就会出现错误: arrayList.toArray(values);//运行期间错误。
这是因为List中包含了整型封装类型的对象。但是该错误只能在运行期间才能发现,程序能够正常的通过编译,并不会报错。对于程序中出现的错误,应该尽早的通知程序员。泛型能够很好地解决这个问题。
泛型在集合中的应用: 在JDK1.5版本之后Java提供了对泛型的支持。例如对于一个ArrayList列表来说,如果只想在列表中放入String类型元素,可以用下面的方法来实现: ArrayList list=new ArrayList();
泛型使得编译器能够在编译期间对集合中加入的对象进行检查,如果加入了不同类型的对象,就会报错,而不必等到运行期间再进行相关的类型转换。和原来没有使用泛型相比,它将原来需要在运行时期才能发现的异常提前到了编译期间,使得程序的安全性也大大提高,泛型一般用于集合类中。
二、枚举
1.枚举类型
枚举也是JDK1.5之后的版本以后Java新加入的特性。使用枚举可以表示一组常量数据。枚举的本质是一个类,可以使用enum关键字来声明一个枚举类型,其声明方式如下: [访问控制符] enum 枚举类型名{value1,value2,......} 使用枚举类型需要注意以下几点:
枚举类型可以定义在类的内部也可以定义在类的外部。如果定义在类的内部,那么其访问控制符可以是public,protected,private或者默认的控制符。如果定义在类的外部,其访·问控制符只能是public和默认控制符;枚举类型中定义的value值都默认为public static final的。其值一经定义就不能在被修改了。多个value值之间需要用逗号隔开;枚举类型中除了可以声明常量之外还可以声明方法。但是方法需要在常量之后,并且常量和方法之间要用分号区分;枚举类型中的值可以通过枚举类型名直接对他们进行访问;枚举类型不能声明为abstract或者final类型;
2.枚举类型的常用方法
public String name()//返回枚举常量的名称; public final int ordinal()//返回枚举常量在枚举类型中的位置,第一个枚举值序号为0,依次类推; public String toString()//返回枚举常量的名字,可以重写此方法; public static valueOf(enumType,String name)//返回与name名字相对应的枚举常量;
三、注释
1.注释类型
在原始码中使用注释,对编译程序提供额外编译提示,或提供应用程序执行时期可读取的组态信息。注释可以仅用于原始码,编译后留在.class文档仅供编译程序读取或开放执行时期读取。
2.常用标准注释
@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注释,就可以让注释被子类继承。
ElementType的枚举成员是用来限定哪个声明位置可以进行标注。在JDK8中,增加了两个枚举成员TYPE _PARAMETER、TYPE _USE。ElementType.TYPE _ USE可用于标注在各式类型,一个标注如果被设定ElementType.TYPE_USE,只要是类型名称,都可以进行标注。@Repeatable 可以让你在同一个位置重复相同标@Filters 作为收集重复标注信息的容器,而每个@Filters储存各自指定的字符串值。 执行时期读取注释信息
时间: 2024-10-20 02:44:50