20145212 《Java程序设计》第9周学习总结
20145212 《Java程序设计》第9周学习总结
教材学习内容总结
一、JDBC架构
1.数据库驱动
- 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡,同样道理,我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数据库打交道,如下所示:
2.JDBC介绍
- SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范(接口),称之为JDBC。这套接口由数据库厂商去实现,这样,开发人员只需要学习jdbc接口,并通过jdbc加载具体的驱动,就可以操作数据库。
如下图所示:
- JDBC全称为:Java Data Base Connectivity(java数据库连接),它主要由接口组成。
- 组成JDBC的2个包:
java.sql
javax.sql
- 开发JDBC应用需要以上2个包的支持外,还需要导入相应JDBC的数据库实现(即数据库驱动)。
3.DriverManager类讲解
- Jdbc程序中的DriverManager用于加载驱动,并创建与数据库的链接,这个API的常用方法:
DriverManager.registerDriver(new Driver())
DriverManager.getConnection(url, user, password),
```
- 注意:在实际开发中并不推荐采用registerDriver方法注册驱动。原因有二:
1.查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。
2.程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。
推荐方式:```Class.forName("com.mysql.jdbc.Driver");```
采用此种方式不会导致驱动对象在内存中重复出现,并且采用此种方式,程序仅仅只需要一个字符串,不需要依赖具体的驱动,使程序的灵活性更高。
4.Connection类讲解
- Jdbc程序中的Connection,它用于代表数据库的链接,Collection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的,这个对象的常用方法:
·createStatement():创建向数据库发送sql的statement对象。
·prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
·prepareCall(sql):创建执行存储过程的callableStatement对象。
·setAutoCommit(boolean autoCommit):设置事务是否自动提交。
·commit() :在链接上提交事务。
·rollback() :在此链接上回滚事务。
5.ResultSet类卷动、更新数据
- Jdbc程序中的ResultSet用于代表Sql语句的执行结果。Resultset封装执行结果时,采用的类似于表格的方式。ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。
ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:
- 获取任意类型的数据
getObject(int index)
getObject(string columnName)
- 获取指定类型的数据,例如:
getString(int index)
getString(String columnName)
- ResultSet还提供了对结果集进行滚动的方法:
next():移动到下一行
Previous():移动到前一行
absolute(int row):移动到指定行
beforeFirst():移动resultSet的最前面。
afterLast() :移动到resultSet的最后面。
### 二、反射与ClassLoader
- 当我们使用一个类,如果这个类还未加载到内存中,系统会通过加载、连接、初始化对类进行初始化。```
1.类加载:指的是将类的class文件读入JVM,并为之创建一个Class对象。
2.类连接:指的是把类的二进制数据合并到JRE中,这又分为3个阶段:
·校验:检查载入Class文件数据的正确性。
·准备:给类的静态变量分配存储空间,并进行默认初始化。
·解析:将类的二进制数据中的符号引用替换成直接引用。
3.初始化:对类的静态变量、静态初始化块进行初始化。
- 注意:
1.一个final类型的静态属性,如果在编译时已经得到了属性值,那么调用该属性时,不会导致该类初始化,因为这个相当于使用常量;
2.使用ClassLoader()方法,只是加载该类,并未初始化。
4.类加载器

- 类加载器就是负责将.class文件加载到内存中,并为之生成对应的java.lang.Class对象,它负责加载所有的类,而一旦一个类被加载入JVM中,就不会被再次载入了。
- 在Java中,一个类用其全限定类名(即包名+类名)作为标识。
- 在JVM中,一个类用其全限定类名和其类加载器作为标识。
- JVM运行时会产生3个ClassLoader,分别为:```BootstrapClassLoader```(根类加载器)、```ExtClassLoader```(扩展类加载器)和```AppClassLoader```(系统类加载器)。
- UML结构如下:

其中,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<String> list=new ArrayList<String>();```
- 泛型使得编译器能够在编译期间对集合中加入的对象进行检查,如果加入了不同类型的对象,就会报错,而不必等到运行期间再进行相关的类型转换。和原来没有使用泛型相比,它将原来需要在运行时期才能发现的异常提前到了编译期间,使得程序的安全性也大大提高,泛型一般用于集合类中。
2.枚举
- 枚举也是JDK1.5之后的版本以后Java新加入的特性。使用枚举可以表示一组常量数据。枚举的本质是一个类,可以使用enum关键字来声明一个枚举类型,其声明方式如下:
```[访问控制符] enum 枚举类型名{value1,value2,......}```
- 使用枚举类型需要注意以下几点:
·枚举类型可以定义在类的内部也可以定义在类的外部。如果定义在类的内部,那么其访问控制符可以是public,protected,private或者默认的控制符。如果定义在类的外部,其访·问控制符只能是public和默认控制符;
·枚举类型中定义的value值都默认为public static final的。其值一经定义就不能在被修改了。多个value值之间需要用逗号隔开;
·枚举类型中除了可以声明常量之外还可以声明方法。但是方法需要在常量之后,并且常量和方法之间要用分号区分;
·枚举类型中的值可以通过枚举类型名直接对他们进行访问;
·枚举类型不能声明为abstract或者final类型;
- 枚举类型的常用方法
public final String name()//返回枚举常量的名称;
public final int ordinal()//返回枚举常量在枚举类型中的位置,第一个枚举值序号为0,依次类推;
public String toString()//返回枚举常量的名字,可以重写此方法;
public static valueOf(enumType,String name)//返回与name名字相对应的枚举常量;
3.注释
- 在原始码中使用注释,对编译程序提供额外编译提示,或提供应用程序执行时期可读取的组态信息。注释可以仅用于原始码,编译后留在.class文档仅供编译程序读取或开放执行时期读取。
- 常用标准注释
@Override //就是标准注释,被注释的方法必须是父类或接口中已定义的方法,请编译程序协助是否真的为重新定义方法。
@Deprecated //如果某个方法原先存在与API中,后来不建议再使用,可以在该方法上注释。若有用户后续想调用或重新定义这个方法,编译程序会提出警告。对于支持泛型的API,建议明确指定泛型真正类型,如果没有指定,编译程序会提出警告。
@SuppressWarnings //指定抑制unchecked的警告产生:
@SuppressWarnings(value={"unchecked"})
@SafeVarargs //表明开发人员确定避免了heap pollution问题。heap pollution问题就是编译程序无法检查执行时期的类型错误,无法具体确认自变量类型。
@FunctionalInterface //让编译程序可协助检查interface是否可做为lambda的目标类型
- 自定义注释类型
·标示注释:就是注释名称本身就是信息,对编译程序或应用程序来说,主要是检查是否有注释出现,并作出对应的动作。
·相关规则:
(1)如果注释名称本身无法提供足够信息,设置单值注释
(2)注释属性也可以用数组形式指定。
(3)在定义注释属性时,如果属性名称为value,则可以省略属性名称,直接指定值。
(4)对成员设定默认值,使用default关键字即可。
(5)要设定数组默认值,可以在default之后加上{},必要时{}中可放置元素值。
- 定义注释时,可使用java.lang.annotation.Target限定时可指定java.lang.annotation.ElementType的枚举值。
- 在制作JavaDoc文件时,默认不会将注释数据加入文件中,如果想要将注释数据加入文件,可以使用java.lang.annotation.Documented。
- 默认父类设定的注释,不会被继承至子类,在定义注释时,设定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的标记。
## 教材学习问题
- 尝试用JDBC连接数据库,共有以下7个步骤:
1.加载JDBC驱动程序:
在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.lang.Class类的静态方法forName(String className)实现。
try{
//加载MySql的驱动类
Class.forName("com.mysql.jdbc.Driver") ;
}catch(ClassNotFoundException e){
System.out.println("找不到驱动程序类 ,加载驱动失败!");
e.printStackTrace() ;
}
成功加载后,会将Driver类的实例注册到DriverManager类中。
2.提供JDBC连接的URL
·连接URL定义了连接数据库时的协议、子协议、数据源标识。
·书写形式:协议:子协议:数据源标识
·协议:在JDBC中总是以jdbc开始
·子协议:是桥连接的驱动程序或是数据库管理系统名称。
·数据源标识:标记找到数据库来源的地址与连接端口。
//例如:(MySql的连接URL)
jdbc:mysql:
//localhost:3306/test?useUnicode=true&characterEncoding=gbk ;
useUnicode=true:表示使用Unicode字符集。如果characterEncoding设置为
gb2312或GBK,本参数必须设置为true 。characterEncoding=gbk:字符编码方式。
3.创建数据库的连接
·要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象, 该对象就代表一个数据库的连接。
·使用DriverManager的getConnectin(String url , String username ,String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和 密码来获得。
//连接MySql数据库,用户名和密码都是root
String url = "jdbc:mysql://localhost:3306/test" ;
String username = "root" ;
String password = "root" ;
try{
Connection con =
DriverManager.getConnection(url , username , password ) ;
}catch(SQLException se){
System.out.println("数据库连接失败!");
se.printStackTrace() ;
}
4.创建一个Statement
·要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3种类型:
1、执行静态SQL语句。通常通过Statement实例实现。
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
3、执行数据库存储过程。通常通过CallableStatement实例实现。
·具体的实现方式:
Statement stmt = con.createStatement() ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
CallableStatement cstmt =
con.prepareCall("{CALL demoSp(? , ?)}") ;
5.执行SQL语句
·Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate和execute
1.ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个结果集(ResultSet)对象。
2.int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
3.execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的语句。
·具体实现的代码:
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;
int rows = stmt.executeUpdate("INSERT INTO ...") ;
boolean flag = stmt.execute(String sql) ;
6.处理结果
·两种情况:
1.执行更新返回的是本次操作影响到的记录数。
2.执行查询返回的结果是一个ResultSet对象。
7.关闭JDBC对象
`操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声明顺序相反:
1.关闭记录集
2.关闭声明
3.关闭连接对象
if(rs != null){ // 关闭记录集
try{
rs.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(stmt != null){ // 关闭声明
try{
stmt.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(conn != null){ // 关闭连接对象
try{
conn.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}

## 本周代码托管截图


## 其他
七周的学习,我们已经基本学完了Java的基础知识。但是我知道自己并没有掌握好每一个点,如果现在让我独立去编写一个程序,很可能依旧会出现很多错误和漏洞。
在接下来的学习中,我就要多多实践,多编写程序,通过经验的积累让自己对Java的理解逐渐深入。
## 学习进度条
| | 代码行数(新增/累积)| 博客量(新增/累积)|学习时间(新增/累积)|重要成长|
| -------- | :----------------:|:----------------:|:---------------: |:-----:|
| 目标 | 5000行 | 30篇 | 400小时 | |
| 第一周 | 200/200 | 2/2 | 10/10 | |
| 第二周 | 300/500 | 1/3 | 16/26 | |
| 第三周 | 300/800 | 1/4 | 18/44 | |
| 第四周 | 300/1100 | 1/5 | 18/62 | |
| 第五周 | 250/1350 | 1/6 | 14/76 | |
| 第六周 | 400/1750 | 2/8 | 14/90 | |
| 第七周 | 300/2050 | 2/10 | 10/100 | |
| 第八周 | 300/2350 | 2/12 | 10/110 | |
| 第九周 | 300/2650 | 3/15 | 10/120 | |
## 参考资料
- [Java学习笔记(第8版)](http://book.douban.com/subject/26371167/)
- [《Java学习笔记(第8版)》学习指导](http://www.cnblogs.com/rocedu/p/5182332.html)
20145212 《Java程序设计》第9周学习总结的更多相关文章
- 20145213《Java程序设计》第九周学习总结
20145213<Java程序设计>第九周学习总结 教材学习总结 "五一"假期过得太快,就像龙卷风.没有一点点防备,就与Java博客撞个满怀.在这个普天同庆的节日里,根 ...
- 20145213《Java程序设计》第二周学习总结
20145213<Java程序设计>第二周学习总结 教材学习内容总结 本周娄老师给的任务是学习教材的第三章--基础语法.其实我觉得还蛮轻松的,因为在翻开厚重的书本,一股熟悉的气息扑面而来, ...
- 20145213《Java程序设计》第一周学习总结
20145213<Java程序设计>第一周学习总结 教材学习内容总结 期待了一个寒假,终于见识到了神秘的娄老师和他的Java课.虽说算不上金风玉露一相逢,没有胜却人间无数也是情理之中,但娄 ...
- 21045308刘昊阳 《Java程序设计》第九周学习总结
21045308刘昊阳 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 数据库本身是个独立运行的应用程序 撰 ...
- 20145330孙文馨 《Java程序设计》第一周学习总结
20145330孙文馨 <Java程序设计>第一周学习总结 教材学习内容总结 刚开始拿到这么厚一本书说没有压力是不可能的,开始从头看觉得很陌生进入不了状态,就稍微会有一点焦虑的感觉.于是就 ...
- 20145337 《Java程序设计》第九周学习总结
20145337 <Java程序设计>第九周学习总结 教材学习内容总结 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JDBC可以 ...
- 20145337 《Java程序设计》第二周学习总结
20145337 <Java程序设计>第二周学习总结 教材学习内容总结 Java可分基本类型与类类型: 基本类型分整数(short.int.long).字节(byte).浮点数(float ...
- 20145218《Java程序设计》第一周学习总结
20145218 <Java程序设计>第一周学习总结 教材学习内容总结 今天下午看了Java学习的视频,感觉很是新奇,之前觉得Java学起来是艰难枯燥的,但通过第一章的学习觉得如果自己可以 ...
- 《Java程序设计》第九周学习总结
20145224 <Java程序设计>第九周学习总结 第十六章 整合数据库 JDBC入门 ·数据库本身是个独立运行的应用程序 ·撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的 ...
- 《Java程序设计》第二周学习总结
20145224陈颢文<Java程序设计>第二周学习总结 教材学习内容总结 一.类型.变量与运算符 1.类型 整数: 可细分为为short整数(占2字节),int整数(占4字节),long ...
随机推荐
- Smarty单模板多缓存
Smarty单模板多缓存 单模板多缓存 在生成缓存.判断缓存是否存在时,增加第二个参数,会根据第二个参数来确定对应的缓存文件 清除缓存
- (Extjs)对于GridPanel的各种操作
刚才做了个有点特殊的需求,在某窗口关闭时,要把Gridpanel中的选择行清空,因为如果不清空,直接双击,就不能即时更新出来我想要的内容. 答案是:Grid.getSelectionModel().c ...
- git rebase 和 reset的区别
check the command detail by input 'git command --help' rebase: reset:
- FastDFS搭建及java整合代码【转】
FastDFS软件介绍 1.什么是FastDFS FastDFS是用C语言编写的一款开源的分布式文件系统.FastDFS为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高 ...
- 折腾笔记之wordpress安装出现错误---【wordpress点击文章找不到网页的解决办法】
本来写的好好的在后台,然后发表在前台,能够看见在网站首页,但是一点击进去,就提示找不到链接了.郁闷,经过查找资料.终于解决了 1,.htaccess要开放写权限,这样在自定义wp的永久链接时,wp会自 ...
- poj3294 出现次数大于n/2 的公共子串
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 13063 Accepted: 3670 Descr ...
- js-读取系统时间
转载 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.o ...
- 一次更愚蠢的NOIP模拟赛
都可以从COGS上找到 纵横字谜(krizaljka) 时间限制: 1 Sec 内存限制: 32 MB 题目描述 给出两个单词,找到第一个相同的字母,然后第一个单词横数输出,第二个竖着输出形成十字形 ...
- 【UOJ#33】【UR#2】树上GCD 有根树点分治 + 容斥原理 + 分块
#33. [UR #2]树上GCD 有一棵$n$个结点的有根树$T$.结点编号为$1…n$,其中根结点为$1$. 树上每条边的长度为$1$.我们用$d(x,y)$表示结点$x,y$在树上的距离,$LC ...
- Servlet教程
有JSP的教程,就有Servlet教程. http://www.runoob.com/servlet/servlet-tutorial.html