arm-linux-gcc3.4.1
玩开发板的都应该知道基于arm的linux内核编译器。该版本为arm3.4.1版本交叉编译器,适用于2.4-2.6的内核
Verilog的135个经典设计实例
Verilog的135个经典设计实例.源代码文档
Verilog+HDL数字设计与综合课件与课本
这个是教学用的集成电路设计的配套ppt和课本。讲授vhdl语言,芯片电子电路类专业适用。
数据结构和算法动画演示
数据结构和算法动画演示.全部是flash动画
ibm 2010 求职大礼包
想去ibm求职的童鞋看过来。这里有你要的ibm内幕知识。
100个C#初学者编程实例
非常全面的C#入门系列源代码。强烈推荐。
freescale MC9S12HY64参考手册
freescale MC9S12HY64 参考手册
java笔试题大集合及答案(另附各大公司笔试题)
60、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
答:有两种实现方法,分别是继承Thread类与实现Runnable接口
用synchronized关键字修饰同步方法
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
61、sleep() 和 wait() 有什么区别?
答:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
62、同步和异步有何异同,在什么情况下分别使用他们?举例说明。
答:如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
63、启动一个线程是用run()还是start()?
答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。
64、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
答:不能,一个对象的一个synchronized方法只能由一个线程访问。
65、请说出你所知道的线程同步的方法。
答:wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
66、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
答:多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有两种,分别是synchronized,wait与notify
67、线程的基本概念、线程的基本状态以及状态之间的关系
思科模拟器Boson NetSim for CCNA 6.0 7.06 - 附带NetSim入门教程
资源如题所述。
思科模拟器Boson NetSim for CCNA 6.0 7.06 特别版 - 附带Boson NetSim入门进阶Ⅱ教程(2)
Bea JRockit j2sdk 1.4.2_05 win32
号称业界最快java虚拟机,可用于规避perm gen异常。本版本为bea被oracle收购之前的版本。
Cytoscape中文用户手册.pdf
Cytoscape是用于做大规模复杂网络分析与生物信息挖掘的开源中间件,l基于java,gpl方式开源。
文都考研高等数学公式总结
里面包含微积分,线代,概率的各个章节各种公式。各位需要公式速记的请下载。
计算机系统结构量化研究方法 第四版 教材+习题解答
这是John L Hennessy 的大作,想必是好多学院的教材。英文版,非扫描,带目录
自己动手写操作系统。pdf
没什么比自己自己动手写操作系统更带有实践性了。
140个C语言程式-让你不用买书
140个C语言程式-让你不用买书
福建某学校的教材。
[模拟电子电路软件].TINA.Pro.V.6.Educational.rar
[模拟电子电路软件].TINA.Pro.V.6.Educational.rar
[模拟电子电路软件].TINA.Pro.V.6.Educational.rar
嵌入式数字信号处理 实验5 实验报告.doc
1. DSP程序优化的方法有哪些?
(1) 开启IDE自带的优化选项;
(2) 使用硬件循环LSETUP;
(3) 使用双乘累加操作,充分利用两个乘累加器和数据总线宽度,如:R3.H=R0.H*R1.H, R3.L=R0.L*R1.L(LS);
(4) 使用并行指令,如:mnop||R0=[I0++]||R1=[I2++];R3.H=R0.H*R1.H, R3.L=R0.L*R1.L(LS)||R2=[I2++];
(5) 将并行的数据放到两个数据段;
(6) 精简循环,进一步提高指令并行化。
2. 简述汇编代码的优化原理。
(1) 使用硬件循环代替软件循环
使用硬件循环不需要条件转移指令,DSP硬件会更具循环寄存器的值自动执行循环体和提出循环,这样保证了流水线的畅通。而不像软件循环那样,一旦分支预测错误就会浪费9个CPU周期。于是使用硬件循环就会大大提高程序执行的效率。
(2) 充分利用数据总线宽度
本DSP外部数据总线宽度为32位,可以一次存取4字节的数据。这样比起一次取1字节或者2字节的操作,执行速度和效率必然提高。
(3) 使用并行指令
使用并行指令,可以充分利用DSP内部的硬件资源的重复性,减少指令执行次数和提高指令执行的效率。使用一条指令代替二至三条指令的功能。
3. 选做任一实验,总结DSP编程学习过程,得出结论。
(1) DSP学习首先要熟悉书本内容
知道基础的硬件外围接线,基本几个寄存器的配置和基础的代码编写方法;
(2) 然后,就可以通过实验平台验证一些实验
通过验证实验,分析代码模板中每条语句的功能,通过这一过程,让自己进一步熟悉DSP实验的编程;
(3) 第三,通过自己编写一些简单的程序,来进一步熟悉一种DSP芯片的代码编写方法和运作机理;
(4) 第四,做一个项目,在做项目的过程中还会遇到很多的问题有待解决,通过完成一个项目,来把所学的DSP知识综合运用,逐渐融会贯通。
算法导论 第2版 习题答案
这个是第2版的习题答案。就是国外某计科学生做的那一份。
flex 基础入门源代码 learningflexbasics.zip
To view these tutorials, expand each zip into its own directory.
All images and associated files for a tutorial zip are local to the directory that you unzipped the files to.
CCNA工程师认证考试电子书.rar
目 录
序言
前言
第1章 网络互连介绍 1
1.1 认证目标1.01:网络互连模型 1
1.1.1 网络的发展 2
1.1.2 OSI模型 2
1.1.3 封装 3
1.2 认证目标1.02:物理层和数据链路层 4
1.2.1 DIX和802.3 Ethernet 5
1.2.2 802.5令牌环网 7
1.2.3 ANSI FDDI 8
1.2.4 MAC地址 9
1.2.5 接口 9
1.2.6 广域网服务 12
1.3 认证目标1.03:网络层和路径确定 17
1.3.1 第3层地址 17
1.3.2 已选择路由协议和路由选择协议 17
1.3.3 路由选择算法和度 18
1.4 认证目标1.04:传输层 18
1.4.1 可靠性 18
1.4.2 窗口机制 18
1.5 认证目标1.05:上层协议 18
1.6 认证目标1.06:Cisco路由器、交换机
和集线器 18
1.7 认证目标1.07:配置Cisco交换机
和集线器 20
1.8 认证总结 20
1.9 2分钟练习 22
1.10 自我测试 23
第2章 从Cisco IOS软件开始 31
2.1 认证目标 2.01:用户界面 31
2.1.1 用户模式和特权模式 31
2.1.2 命令行界面 32
2.2 认证目标2.02:路由器基础 35
2.2.1 路由器元素 35
2.2.2 路由器模式 35
2.2.3 检查路由器状态 37
2.2.4 Cisco发现协议 38
2.2.5 远程访问路由器 39
2.2.6 基本测试 39
2.2.7 调试 40
2.2.8 路由基础 41
2.3 认证目标2.03:初始配置 43
2.3.1 虚拟配置注册表设置 46
2.3.2 启动序列:引导系统命令 47
2.3.3 将配置传送到服务器或从服务器
上复制配置 47
2.4 认证目标2.04:自动安装配置数据 49
2.5 认证总结 49
2.6 2分钟练习 50
2.7 自我测试 51
第3章 IP寻址 58
3.1 认证目标3.01:IP地址类 58
3.1.1 IP地址的结构 58
3.1.2 特殊情况:回路、广播和网
络地址 59
3.1.3 识别地址类 60
3.1.4 子网掩码的重要性 61
3.1.5 二进制和十进制互相转换 62
3.2 认证目标3.02:子网划分和子网掩码 64
3.2.1 子网划分的目的 65
3.2.2 在默认子网掩码中加入位 65
3.3 认证目标3.03:子网规划 66
3.3.1 选择子网掩码 66
3.3.2 主机数目的影响 66
3.3.3 确定每个子网的地址范围 67
3.4 认证目标3.04:复杂子网 68
3.4.1 子网位穿越8位位组边界 68
3.4.2 变长子网掩码 69
3.4.3 超网划分 70
3.5 认证目标 3.05:用Cisco IOS配
置IP地址 71
3.5.1 设置IP地址和参数 71
3.5.2 主机名称到地址的映射 71
3.5.3 使用ping 72
3.5.4 使用IP TRACE和Telnet 73
3.6 认证总结 73
3.7 2分钟练习 74
3.8 自我测试 75
第4章 TCP/IP协议 88
4.1 认证目标 4.01:应用层服务 89
4.2 认证目标 4.02:表示和会话层服务 89
4.2.1 远程过程调用 89
4.2.2 Socket 89
4.2.3 传输层接口 90
4.2.4 NetBIOS 90
4.3 认证目标4.03:协议的详细结构 90
4.3.1 传输层 91
4.3.2 TCP 91
4.3.3 UDP 93
4.4 认证目标4.04:网络层 94
4.4.1 网际协议 94
4.4.2 地址解析协议 95
4.4.3 反向地址解析协议 96
4.4.4 逆向地址解析协议 96
4.4.5 网际控制消息协议 96
4.5 认证目标4.05:操作系统命令 97
4.5.1 UNIX 97
4.5.2 32位Windows 98
4.6 认证总结 98
4.7 2分钟练习 99
4.8 自我测试 100
第5章 IP路由选择协议 108
5.1 认证目标5.01:为什么使用路由
选择协议 108
5.2 认证目标5.02:静态路由和动
态路由 114
5.3 认证目标 5.03:默认路由 117
5.4 认证目标 5.04:链路状态和距
离向量 119
5.4.1 距离向量路由选择协议 119
5.4.2 链路状态路由选择协议 123
5.4.3 内部和外部网关协议 124
5.5 认证目标 5.05:RIP 124
5.6 认证目标 5.06:IGRP 127
5.7 认证目标 5.07:OSPF 129
5.8 认证总结 131
5.9 2分钟练习 132
5.10 自我测试 133
第6章 IP配置 141
6.1 认证目标 6.01:IP配置命令 141
6.2 认证目标 6.02:配置静态路由 141
6.3 认证目标 6.03:配置默认路由 144
6.4 认证目标 6.04:配置RIP路由选择 144
6.5 认证目标 6.05:配置IGRP路由
选择 145
6.6 认证目标 6.06:IP主机表 147
6.7 认证目标 6.07:DNS和DHCP配置 148
6.7.1 DNS配置 148
6.7.2 转发DHCP请求 148
6.8 认证目标 6.08:辅助寻址 150
6.9 认证总结 151
6.10 2分钟练习 151
6.11 自我测试 152
第7章 配置Novell IPX 158
7.1 认证目标 7.01:IPX协议栈 158
7.2 认证目标 7.02:IPX数据报 159
7.2.1 IPX地址编码 159
7.2.2 IPX路由选择 160
7.2.3 内部网络 160
7.3 认证目标 7.03:IPX封装类型 161
7.3.1 Etherent_II 162
7.3.2 Ethernet_802.3 162
7.3.3 Ethernet_802.2 162
7.3.4 Ethernet_SNAP 163
7.3.5 多重帧类型的路由选择 163
7.4 认证目标 7.04:SAP和RIP 165
7.4.1 SAP 165
7.4.2 SAP和RIP操作实例 167
7.5 认证目标 7.05:IPX配置 169
7.5.1 准备 169
7.5.2 启用IPX和配置接口 169
7.5.3 路由选择协议 172
7.6 认证总结 173
7.7 2分钟练习 173
7.8 自我测试 174
第8章 AppleTalk的配置 182
8.1 认证目标 8.01:AppleTalk 协议栈 183
8.1.1 物理层与数据链路层 183
8.1.2 网络层 183
8.1.3 高层协议 183
8.2 认证目标 8.02:AppleTalk服务 185
8.3 认证目标 8.03:AppleTalk寻址 185
8.3.1 地址结构 187
8.3.2 地址分配 187
8.4 认证目标 8.04:AppleTalk区域 188
8.5 认证目标 8.05:AppleTalk
路由选择 189
8.6 认证目标 8.06:AppleTalk
发现模式 190
8.7 认证目标 8.07:AppleTalk配置 191
8.7.1 所需的AppleTalk命令 191
8.7.2 AppleTalk过滤 192
8.7.3 验证和监视AppleTalk的配置 194
8.8 认证总结 195
8.9 2分钟练习 196
8.10 自我测试 196
第9章 用访问列表管理基本通信量 205
9.1 认证目标 9.01:标准IP访问列表 205
9.2 认证目标 9.02:扩展IP访问列表 210
9.3 认证目标 9.03:命名访问列表 211
9.4 认证目标 9.04:标准IPX访问列表 213
9.5 认证目标 9.05:IPX SAP过滤 214
9.6 认证目标 9.06:AppleTalk访问列表 218
9.7 认证总结 220
9.8 2分钟练习 221
9.9 自我测试 222
第10章 广域连网 227
10.1 认证目标10.01:配置ISDN 227
10.1.1 配置ISDN BRI 227
10.1.2 配置ISDN PRI 229
10.2 认证目标10.02:配置X.25 229
10.3 认证目标10.03:配置帧中继 231
10.3.1 虚电路 232
10.3.2 差错校正 233
10.3.3 逻辑接口 233
10.3.4 在Cisco路由器上配置帧中继 233
10.4 认证目标10.04:配置ATM 235
10.5 认证目标10.05:配置PPP和多
链路PPP 238
10.5.1 PPP配置 238
10.5.2 配置多链路PPP 240
10.6 认证总结 241
10.7 2分钟练习 242
10.8 自我测试 243
第11章 虚拟局域网 250
11.1 认证目标11.01:交换和VLAN 250
11.2 认证目标11.02:生成树协议
和VLAN 254
11.3 认证目标11.03:默认VLAN配置 255
11.4 认证目标11.04:跨域配置VLAN 256
11.5 认证目标11.05:到VLAN的分组
交换机端口 259
11.5.1 配置ISL主干 264
11.5.2 IEEE 802.1Q主干 265
11.6 VLAN故障诊断 265
11.7 认证总结 267
11.8 2分钟练习 270
11.9 自我测试 271
附录A 自我测试题答案 278
附录B 关于配套光盘 299
附录C 关于Web站点 300
词汇表 301
Berkeley DB Java Edition 4.0.92 开发包
这个是最流行的嵌入式高性能开源数据库内核开发包,java企业开发必备。
SQL SERVER 2005 详细操作演示教程ppt
SQL SERVER 2005 详细操作演示教程ppt,每个操作都配图。方便各位快速入门。
powerdesigner 12 详细操作演示教程ppt
这个文档ppt配图非常细致,基本是手把手配图了,方便数据库设计员有样学样。
arcgis api for flex 1.3 arcgis_api_for_flex_1_3
这个压缩包包含agslib 1.3和相关的全套范例源代码!!!
可以在flex里做高级地学分析。
org.eclipse.jdt.core_3.4.0.v_874.jar
您开发drools规则应用是否遇到过报错org.drools.RuntimeDroolsException: Unable to load dialect 'org.drools.rule.builder.dialect.java.JavaDialectConfiguration:java'呢?
这个jar包可解您燃眉之急。
java日志记录组件log4j-1.2.14和commons-logging-1.1.1
本压缩包内附带log4j-1.2.14和commons-logging-1.1.1,Java日志记录行业标准组件。不要分啦。鄙视开源组件还收费的猥琐鬼。
Flex 3 cookbook 中文版官方教程。高清带目录
这个是做flex富客户端必备的资料。做flex就必须经常参考的官方flex教程的中文版。
基于龙芯的MIPS Linux中断代码分析
本文详细讲解了龙芯cpu的lootloader启动加载机制和中断处理原理。有志于推广国产cpu的人士适用。
地理学的数学模型与应用.pdf
这本书详细探讨了高等数学在地理学各个分支上的深入应用,gis资深开发者以及gis领域研究员适用。
一个超级简单可用的flex+asp.net的图片上传演示源代码压缩档
这个是新手学习flex + asp.net的图片上传的简单而好的代码。
drools 5.0完整组件打包压缩文档 drools-5.0-bin.zip
这个是drools5.0完整组件库。包含了drools引擎所依赖的完整jar包集合。不收资源分啦。
mysql-connector-java-5.1.10.zip
这个是mysql的java连接组件包。将压缩包内的jar包拖进java工程的lib 目录就可用。
有感于某些人对这种开源的组件还要收什么下载资源分,太猥琐啦,这个就不要分了。
JSP网页编程.ppt
这个没什么好说的。一份讲解jsp的ppt
powerdesigner 9.5 物理模型用户入门手册
图书说明... .................................................................v
1 关于PDM教学...............................................................1
你将要做什么.....................................................................2
学习所需时间............... .................................................... 2
你将要学到到的内容. ............................................................ 3
安装............................................................................ 4
2 怎样开始PDM教学...........................................................5
启动Po werDesigner.............................................................. 6
打开新的PDM..................................................................... 7
返回操作PDM教学................................................................. 9
使用选项板梗具........................ ......................................... 11
定义PDM 属性和选项.............................................................. 16
在图形窗口安排符号.............................................................. 19
保存tutorial PDM................................................................ 20
3 在P D M 中创建一张表格...................................................21
添加一张表格...... ............................................................. 23
添加列...........................................................................25
创建一个区域...... ............................................................. 29
将列加于区域上.................................................................. 32
创建列...........................................................................34
在索引中创建关键字.............................................................. 36
为没有关键字的列创建索引....... ................................................ 39
4 定义参照和参照完整性................................. ...................43
创建一个参照...... ............................................................. 45
定义参照属性.................................................................... 46
定义参照完整性....... .......................................................... 48
5 创建视图...................................................................51
视图的组成.... ................................................................. 52
一般视图.... ................................................................... 53
6 参照完整性触发器的使用..............................................57
定义触发器的参照完整性..........................................59
触发器自动的创建............................................... 60
触发器裕览..................................................... 65
产生触发器的脚本................... .................................... 67
7 抽象数据类型的使用..................... ..............................71
指定一个Java类的抽象数据类型..................................... 73
创建一个PowerDesigner面向对象模型................................ 76
访问Java类的属性................................................. 77
8 生成一个数据库脚本..................... ..............................81
生成一个数据库创建脚本..... ..................................... 82
9 生成一个测试数据脚本................... ................................85
导入测试数据profiles(配置文件) .................................. 87
生成一个新的测试数据profiles(配置文件)........................ 89
定义一个测试数据作为自动测试数据
生成的源........................................................ 91
定义一个文件作为测试数据的源......... ...........................94
将一个测试数据的profiles赋值给所选列............................ 96
生成一个测试数据创建脚本........................................ 100
10 创建一个数据仓库数据库模式.........................................103
创建一个新模型并复制表格...........................................104
向模型添加一个表格................................................107
在当前模型定义一个数据源..........................................110
给关系创建一个关系映射........................................... 112
产生一个extraction脚本........................................... 119
11 多维特性的使用........................................................121
检索多维对象....................................................... 122
cube的重建........................................................ 124
产生cube数据...................................................... 129
退出PowerDesigner ................................................ 131
术语.......................................................................133
索引. .....................................................................137
MySQL 5.1中文手冊
前言
1. 一般信息
1.1. 关于本手册
1.2. 本手册采用的惯例
1.3. MySQL AB概述
1.4. MySQL数据库管理系统概述
1.4.1. MySQL的历史
1.4.2. MySQL的的主要特性
1.4.3. MySQL稳定性
1.4.4. MySQL表最大能达到多少
1.4.5. 2000年兼容性
1.5. MaxDB数据库管理系统概述
1.5.1. 什么是MaxDB?
1.5.2. MaxDB的历史
1.5.3. MaxDB的特性
1.5.4. 许可和支持
1.5.5. MaxDB和MySQL之间的特性差异
1.5.6. MaxDB和MySQL之间的协同性
1.5.7. 与MaxDB有关的链接
1.6. MySQL发展大事记
1.6.1. MySQL 5.1的新特性
1.7. MySQL信息源
1.7.1. MySQL邮件列表
1.7.2. IRC(在线聊天系统)上的MySQL社区支持
1.7.3. MySQL论坛上的MySQL社区支持
1.8. MySQL标准的兼容性
1.8.1. MySQL遵从的标准是什么
1.8.2. 选择SQL模式
1.8.3. 在ANSI模式下运行MySQL
1.8.4. MySQL对标准SQL的扩展
1.8.5. MySQL与标准SQL的差别
1.8.6. MySQL处理约束的方式
2. 安装MySQL
2.1. 一般安装问题
2.1.1. MySQL支持的操作系统
2.1.2. 选择要安装的MySQL分发版
2.1.3. 怎样获得MySQL
2.1.4. 通过MD5校验和或GnuPG验证软件包的完整性
2.1.5. 安装布局
2.2. 使用二进制分发版的标准MySQL安装
2.3. 在Windows上安装MySQL
2.3.1. Windows系统要求
2.3.2. 选择安装软件包
2.3.3. 用自动安装器安装MySQL
2.3.4. 使用MySQL安装向导
2.3.5. 使用配置向导
2.3.6. 通过非安装Zip文件安装MySQL
2.3.7. 提取安装档案文件
2.3.8. 创建选项文件
2.3.9. 选择MySQL服务器类型
2.3.10. 首次启动服务器
2.3.11. 从Windows命令行启动MySQL
2.3.12. 以Windows服务方式启动MySQL
2.3.13. 测试MySQL安装
2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除
2.3.15. 在Windows下升级MySQL
2.3.16. Windows版MySQL同Unix版MySQL对比
2.4. 在Linux下安装MySQL
2.5.在Mac OS X中安装MySQL
2.6. 在NetWare中安装MySQL
2.7. 在其它类Unix系统中安装MySQL
2.8. 使用源码分发版安装MySQL
2.8.1. 源码安装概述
2.8.2. 典型配置选项
2.8.3. 从开发源码树安装
2.8.4. 处理MySQL编译问题
2.8.5. MIT-pthreads注意事项
2.8.6. 在Windows下从源码安装MySQL
2.8.7. 在Windows下编译MySQL客户端
2.9. 安装后的设置和测试
2.9.1. Windows下安装后的过程
2.9.2. Unix下安装后的过程
2.9.3. 使初始MySQL账户安全
2.10. 升级MySQL
2.10.1. 从5.0版升级
2.10.2. 升级授权表
2.10.3. 将MySQL数据库拷贝到另一台机器
2.11. 降级MySQL
2.12. 具体操作系统相关的注意事项
2.12.1. Linux注意事项
2.12.2. Mac OS X注意事项
2.12.3. Solaris注意事项
2.12.4. BSD注意事项
2.12.5. 其它Unix注意事项
2.12.6. OS/2注意事项
2.13. Perl安装注意事项
2.13.1. 在Unix中安装Perl
2.13.2. 在Windows下安装ActiveState Perl
2.13.3. 使用Perl DBI/DBD接口的问题
3. 教程
3.1. 连接与断开服务器
3.2. 输入查询
3.3. 创建并使用数据库
3.3.1. 创建并选择数据库
3.3.2. 创建表
3.3.3. 将数据装入表中
3.3.4. 从表检索信息
3.4. 获得数据库和表的信息
3.5. 在批处理模式下使用mysql
3.6. 常用查询的例子
3.6.1. 列的最大值
3.6.2. 拥有某个列的最大值的行
3.6.3. 列的最大值:按组
3.6.4. 拥有某个字段的组间最大值的行
3.6.5. 使用用户变量
3.6.6. 使用外键
3.6.7. 根据两个键搜索
3.6.8. 根据天计算访问量
3.6.9. 使用AUTO_INCREMENT
3.7. 孪生项目的查询
3.7.1. 查找所有未分发的孪生项
3.7.2. 显示孪生对状态的表
3.8. 与Apache一起使用MySQL
4. MySQL程序概述
4.1. MySQL程序概述
4.2. 调用MySQL程序
4.3. 指定程序选项
4.3.1. 在命令行上使用选项
4.3.2. 使用选项文件
4.3.3. 用环境变量指定选项
4.3.4. 使用选项设置程序变量
5. 数据库管理
5.1. MySQL服务器和服务器启动脚本
5.1.1. 服务器端脚本和实用工具概述
5.1.2. mysqld-max扩展MySQL服务器
5.1.3. mysqld_safe:MySQL服务器启动脚本
5.1.4. mysql.server:MySQL服务器启动脚本
5.1.5. mysqld_multi:管理多个MySQL服务器的程序
5.2. mysqlmanager:MySQL实例管理器
5.2.1. 用MySQL实例管理器启动MySQL服务器
5.2.2. 连接到MySQL实例管理器并创建用户账户
5.2.3. MySQL实例管理器命令行选项
5.2.4. MySQL实例管理器配置文件
5.2.5. MySQL实例管理器识别的命令
5.3. mysqld:MySQL服务器
5.3.1. mysqld命令行选项
5.3.2. SQL服务器模式
5.3.3. 服务器系统变量
5.3.4. 服务器状态变量
5.4. mysql_fix_privilege_tables:升级MySQL系统表
5.5. MySQL服务器关机进程
5.6. 一般安全问题
5.6.1. 通用安全指南
5.6.2. 使MySQL在攻击者面前保持安全
5.6.3. Mysqld安全相关启动选项
5.6.4. LOAD DATA LOCAL安全问题
5.7. MySQL访问权限系统
5.7.1. 权限系统的作用
5.7.2. 权限系统工作原理
5.7.3. MySQL提供的权限
5.7.4. 与MySQL服务器连接
5.7.5. 访问控制, 阶段1:连接核实
5.7.6. 访问控制, 阶段2:请求核实
5.7.7. 权限更改何时生效
5.7.8. 拒绝访问错误的原因
5.7.9. MySQL 4.1中的密码哈希处理
5.8. MySQL用户账户管理
5.8.1. MySQL用户名和密码
5.8.2. 向MySQL增加新用户账户
5.8.3. 从MySQL删除用户账户
5.8.4. 限制账户资源
5.8.5. 设置账户密码
5.8.6. 使你的密码安全
5.8.7. 使用安全连接
5.9. 备份与恢复
5.9.1. 数据库备份
5.9.2. 示例用备份与恢复策略
5.9.3. 自动恢复
5.9.4. 表维护和崩溃恢复
5.9.5. myisamchk:MyISAM表维护实用工具
5.9.6. 建立表维护计划
5.9.7. 获取关于表的信息
5.10. MySQL本地化和国际应用
5.10.1. 数据和排序用字符集
5.10.2. 设置错误消息语言
5.10.3. 添加新的字符集
5.10.4. 字符定义数组
5.10.5. 字符串比较支持
5.10.6. 多字节字符支持
5.10.7. 字符集问题
5.10.8. MySQL服务器时区支持
5.11. MySQL日志文件
5.11.1. 错误日志
5.11.2. 通用查询日志
5.11.3. 二进制日志
5.11.4. 慢速查询日志
5.11.5. 日志文件维护
5.12. 在同一台机器上运行多个MySQL服务器
5.12.1. 在Windows下运行多个服务器
5.12.2. 在Unix中运行多个服务器
5.12.3. 在多服务器环境中使用客户端程序
5.13. MySQL查询高速缓冲
5.13.1. 查询高速缓冲如何工作
5.13.2. 查询高速缓冲SELECT选项
5.13.3. 查询高速缓冲配置
5.13.4. 查询高速缓冲状态和维护
6. MySQL中的复制
6.1. 复制介绍
6.2. 复制实施概述
6.3. 复制实施细节
6.3.1. 复制主线程状态
6.3.2. 复制从I/O线程状态
6.3.3. 复制从SQL线程状态
6.3.4. 复制传递和状态文件
6.4. 如何设置复制
6.5. 不同MySQL版本之间的复制兼容性
6.6. 升级复制设置
6.6.1. 将复制升级到5.0版
6.7. 复制特性和已知问题
6.8. 复制启动选项
6.9. 复制FAQ
6.10. 复制故障诊断与排除
6.11. 通报复制缺陷
6.12. 多服务器复制中的Auto-Increment
7. 优化
7.1. 优化概述
7.1.1. MySQL设计局限与折衷
7.1.2. 为可移植性设计应用程序
7.1.3. 我们已将MySQL用在何处?
7.1.4. MySQL基准套件
7.1.5. 使用自己的基准
7.2. 优化SELECT语句和其它查询
7.2.1. EXPLAIN语法(获取SELECT相关信息)
7.2.2. 估计查询性能
7.2.3. SELECT查询的速度
7.2.4. MySQL怎样优化WHERE子句
7.2.5. 范围优化
7.2.6. 索引合并优化
7.2.7. MySQL如何优化IS NULL
7.2.8. MySQL如何优化DISTINCT
7.2.9. MySQL如何优化LEFT JOIN和RIGHT JOIN
7.2.10. MySQL如何优化嵌套Join
7.2.11. MySQL如何简化外部联合
7.2.12. MySQL如何优化ORDER BY
7.2.13. MySQL如何优化GROUP BY
7.2.14. MySQL如何优化LIMIT
7.2.15. 如何避免表扫描
7.2.16. INSERT语句的速度
7.2.17. UPDATE语句的速度
7.2.18. DELETE语句的速度
7.2.19. 其它优化技巧
7.3. 锁定事宜
7.3.1. 锁定方法
7.3.2. 表锁定事宜
7.4. 优化数据库结构
7.4.1. 设计选择
7.4.2. 使你的数据尽可能小
7.4.3. 列索引
7.4.4. 多列索引
7.4.5. MySQL如何使用索引
7.4.6. MyISAM键高速缓冲
7.4.7. MyISAM索引统计集合
7.4.8. MySQL如何计算打开的表
7.4.9. MySQL如何打开和关闭表
7.4.10. 在同一个数据库中创建多个表的缺陷
7.5. 优化MySQL服务器
7.5.1. 系统因素和启动参数的调节
7.5.2. 调节服务器参数
7.5.3. 控制查询优化器的性能
7.5.4. 编译和链接怎样影响MySQL的速度
7.5.5. MySQL如何使用内存
7.5.6. MySQL如何使用DNS
7.6. 磁盘事宜
7.6.1. 使用符号链接
8. 客户端和实用工具程序
8.1. 客户端脚本和实用工具概述
8.2. myisampack:生成压缩、只读MyISAM表
8.3. mysql:MySQL命令行工具
8.3.1. 选项
8.3.2. mysql命令
8.3.3. 怎样从文本文件执行SQL语句
8.3.4. mysql技巧
8.4. mysqlaccess:用于检查访问权限的客户端
8.5. mysqladmin:用于管理MySQL服务器的客户端
8.6. mysqlbinlog:用于处理二进制日志文件的实用工具
8.7. mysqlcheck:表维护和维修程序
8.8. mysqldump:数据库备份程序
8.9. mysqlhotcopy:数据库备份程序
8.10. mysqlimport:数据导入程序
8.11. mysqlshow-显示数据库、表和列信息
8.12. myisamlog:显示MyISAM日志文件内容
8.13. perror:解释错误代码
8.14. replace:字符串替换实用工具
8.15. mysql_zap:杀死符合某一模式的进程
9. 语言结构
9.1. 文字值
9.1.1. 字符串
9.1.2. 数值
9.1.3. 十六进制值
9.1.4. 布尔值
9.1.5. 位字段值
9.1.6. NULL值
9.2. 数据库、表、索引、列和别名
9.2.1. 识别符限制条件
9.2.2. 识别符大小写敏感性
9.3. 用户变量
9.4. 系统变量
9.4.1. 结构式系统变量
9.5. 注释语法
9.6. MySQL中保留字的处理
10. 字符集支持
10.1. 常规字符集和校对
10.2. MySQL中的字符集和校对
10.3. 确定默认字符集和校对
10.3.1. 服务器字符集和校对
10.3.2. 数据库字符集和校对
10.3.3. 表字符集和校对
10.3.4. 列字符集和校对
10.3.5. 字符集和校对分配示例
10.3.6. 连接字符集和校对
10.3.7. 字符串文字字符集和校对
10.3.8. 在SQL语句中使用COLLATE
10.3.9. COLLATE子句优先
10.3.10. BINARY操作符
10.3.11. 校对确定较为复杂的一些特殊情况
10.3.12. 校对必须适合字符集
10.3.13. 校对效果的示例
10.4. 字符集支持影响到的操作
10.4.1. 结果字符串
10.4.2. CONVERT()
10.4.3. CAST()
10.4.4. SHOW语句
10.5. Unicode支持
10.6. 用于元数据的UTF8
10.7. 与其它DBMS的兼容性
10.8. 新字符集配置文件格式
10.9. 国家特有字符集
10.10. MySQL支持的字符集和校对
10.10.1. Unicode字符集
10.10.2. 西欧字符集
10.10.3. 中欧字符集
10.10.4. 南欧与中东字符集
10.10.5. 波罗的海字符集
10.10.6. 西里尔字符集
10.10.7. 亚洲字符集
11. 列类型
11.1. 列类型概述
11.1.1. 数值类型概述
11.1.2. 日期和时间类型概述
11.1.3. 字符串类型概述
11.2. 数值类型
11.3. 日期和时间类型
11.3.1. DATETIME、DATE和TIMESTAMP类型
11.3.2. TIME类型
11.3.3. YEAR类型
11.3.4. Y2K事宜和日期类型
11.4. String类型
11.4.1. CHAR和VARCHAR类型
11.4.2. BINARY和VARBINARY类型
11.4.3. BLOB和TEXT类型
11.4.4. ENUM类型
11.4.5. SET类型
11.5. 列类型存储需求
11.6. 选择正确的列类型
11.7. 使用来自其他数据库引擎的列类型
12. 函数和操作符
12.1. 操作符
12.1.1. 操作符优先级
12.1.2. 圆括号
12.1.3. 比较函数和操作符
12.1.4. 逻辑操作符
12.2. 控制流程函数
12.3. 字符串函数
12.3.1. 字符串比较函数
12.4. 数值函数
12.4.1. 算术操作符
12.4.2. 数学函数
12.5. 日期和时间函数
12.6. MySQL使用什么日历?
12.7. 全文搜索功能
12.7.1. 布尔全文搜索
12.7.2. 全文搜索带查询扩展
12.7.3. 全文停止字
12.7.4. 全文限定条件
12.7.5. 微调MySQL全文搜索
12.8. Cast函数和操作符
12.9. 其他函数
12.9.1. 位函数
12.9.2. 加密函数
12.9.3. 信息函数
12.9.4. 其他函数
12.10. 与GROUP BY子句同时使用的函数和修改程序
12.10.1. GROUP BY(聚合)函数
12.10.2. GROUP BY修改程序
12.10.3. 具有隐含字段的GROUP BY
13. SQL语句语法
13.1. 数据定义语句
13.1.1. ALTER DATABASE语法
13.1.2. ALTER TABLE语法
13.1.3. CREATE DATABASE语法
13.1.4. CREATE INDEX语法
13.1.5. CREATE TABLE语法
13.1.6. DROP DATABASE语法
13.1.7. DROP INDEX语法
13.1.8. DROP TABLE语法
13.1.9. RENAME TABLE语法
13.2. 数据操作语句
13.2.1. DELETE语法
13.2.2. DO语法
13.2.3. HANDLER语法
13.2.4. INSERT语法
13.2.5. LOAD DATA INFILE语法
13.2.6. REPLACE语法
13.2.7. SELECT语法
13.2.8. Subquery语法
13.2.9. TRUNCATE语法
13.2.10. UPDATE语法
13.3. MySQL实用工具语句
13.3.1. DESCRIBE语法(获取有关列的信息)
13.3.2. USE语法
13.4. MySQL事务处理和锁定语句
13.4.1. START TRANSACTION, COMMIT和ROLLBACK语法
13.4.2. 不能回滚的语句
13.4.3. 会造成隐式提交的语句
13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT语法
13.4.5. LOCK TABLES和UNLOCK TABLES语法
13.4.6. SET TRANSACTION语法
13.4.7. XA事务
13.5. 数据库管理语句
13.5.1. 账户管理语句
13.5.2. 表维护语句
13.5.3. SET语法
13.5.4. SHOW语法
13.5.5. 其它管理语句
13.6. 复制语句
13.6.1. 用于控制主服务器的SQL语句
13.6.2. 用于控制从服务器的SQL语句
13.7. 用于预处理语句的SQL语法
14. 插件式存储引擎体系结构
14.1. 前言
14.2. 概述
14.3. 公共MySQL数据库服务器层
14.4. 选择存储引擎
14.5. 将存储引擎指定给表
14.6. 存储引擎和事务
14.7. 插入存储引擎
14.8. 拔出存储引擎
14.9. 插件式存储器的安全含义
15. 存储引擎和表类型
15.1. MyISAM存储引擎
15.1.1. MyISAM启动选项
15.1.2. 键所需的空间
15.1.3. MyISAM表的存储格式
15.1.4. MyISAM表方面的问题
15.2. InnoDB存储引擎
15.2.1. InnoDB概述
15.2.2. InnoDB联系信息
15.2.3. InnoDB配置
15.2.4. InnoDB启动选项
15.2.5. 创建InnoDB表空间
15.2.6. 创建InnoDB表
15.2.7. 添加和删除InnoDB数据和日志文件
15.2.8. InnoDB数据库的备份和恢复
15.2.9. 将InnoDB数据库移到另一台机器上
15.2.10. InnoDB事务模型和锁定
15.2.11. InnoDB性能调节提示
15.2.12. 多版本的实施
15.2.13. 表和索引结构
15.2.14. 文件空间管理和磁盘I/O
15.2.15. InnoDB错误处理
15.2.16. 对InnoDB表的限制
15.2.17. InnoDB故障诊断与排除
15.3. MERGE存储引擎
15.3.1. MERGE表方面的问题
15.4. MEMORY (HEAP)存储引擎
15.5. BDB (BerkeleyDB)存储引擎
15.5.1. BDB支持的操作系统
15.5.2. 安装BDB
15.5.3. BDB启动选项
15.5.4. BDB表的特性
15.5.5. 修改BDB所需的事宜
15.5.6. 对BDB表的限制
15.5.7. 使用BDB表时可能出现的错误
15.6. EXAMPLE存储引擎
15.7. FEDERATED存储引擎
15.7.1. 安装FEDERATED存储引擎
15.7.2. FEDERATED存储引擎介绍
15.7.3. 如何使用FEDERATED表
15.7.4. FEDERATED存储引擎的局限性
15.8. ARCHIVE存储引擎
15.9. CSV存储引擎
15.10. BLACKHOLE存储引擎
16. 编写自定义存储引擎
16.1. 前言
16.2. 概述
16.3. 创建存储引擎源文件
16.4. 创建handlerton
16.5. 对处理程序进行实例化处理
16.6. 定义表扩展
16.7. 创建表
16.8. 打开表
16.9. 实施基本的表扫描功能
16.9.1. 实施store_lock()函数
16.9.2. 实施external_lock()函数
16.9.3. 实施rnd_init()函数
16.9.4. 实施info()函数
16.9.5. 实施extra()函数
16.9.6. 实施rnd_next()函数
16.10. 关闭表
16.11. 为存储引擎添加对INSERT的支持
16.12. 为存储引擎添加对UPDATE的支持
16.13. 为存储引擎添加对DELETE的支持
16.14. API引用
16.14.1. bas_ext
16.14.2. close
16.14.3. create
16.14.4. delete_row
16.14.5. delete_table
16.14.6. external_lock
16.14.7. extra
16.14.8. info
16.14.9. open
16.14.10. rnd_init
16.14.11. rnd_next
16.14.12. store_lock
16.14.13. update_row
16.14.14. write_row
17. MySQL簇
17.1. MySQL簇概述
17.2. MySQL簇的基本概念
17.3. 多计算机的简单基础知识
17.3.1. 硬件、软件和联网
17.3.2. 安装
17.3.3. 配置
17.3.4. 首次启动
17.3.5. 加载示例数据并执行查询
17.3.6. 安全关闭和重启
17.4. MySQL簇的配置
17.4.1. 从源码创建MySQL簇
17.4.2. 安装软件
17.4.3. MySQL簇的快速测试设置
17.4.4. 配置文件
17.5. MySQL簇中的进程管理
17.5.1. 用于MySQL簇的MySQL服务器进程使用
17.5.2. ndbd,存储引擎节点进程
17.5.3. ndb_mgmd,“管理服务器”进程
17.5.4. ndb_mgm,“管理客户端”进程
17.5.5. 用于MySQL簇进程的命令选项
17.6. MySQL簇的管理
17.6.1. MySQL簇的启动阶段
17.6.2. “管理客户端”中的命令
17.6.3. MySQL簇中生成的事件报告
17.6.4. 单用户模式
17.6.5. MySQL簇的联机备份
17.7. 使用与MySQL簇的高速互连
17.7.1. 配置MySQL簇以使用SCI套接字
17.7.2. 理解簇互连的影响
17.8. MySQL簇的已知限制
17.9. MySQL簇发展的重要历程
17.9.1. MySQL 5.0中的MySQL簇变化
17.9.2. 关于MySQL簇的MySQL 5.1发展历程
17.10. MySQL簇常见问题解答
17.11. MySQL簇术语表
18. 分区
18.1. MySQL中的分区概述
18.2. 分区类型
18.2.1. RANGE分区
18.2.2. LIST分区
18.2.3. HASH分区
18.2.4. KEY分区
18.2.5. 子分区
18.2.6. MySQL分区处理NULL值的方式
18.3. 分区管理
18.3.1. RANGE和LIST分区的管理
18.3.2. HASH和KEY分区的管理
18.3.3. 分区维护
18.3.4. 获取关于分区的信息
19. MySQL中的空间扩展
19.1. 前言
19.2. OpenGIS几何模型
19.2.1. Geometry类的层次
19.2.2. 类Geometry
19.2.3. 类Point
19.2.4. 类Curve
19.2.5. 类LineString
19.2.6. 类Surface
19.2.7. 类Polygon
19.2.8. 类GeometryCollection
19.2.9. 类MultiPoint
19.2.10. 类MultiCurve
19.2.11. 类MultiLineString
19.2.12. 类MultiSurface
19.2.13. 类MultiPolygon
19.3. 支持的空间数据格式
19.3.1. 著名的文本(WKT)格式
19.3.2. 著名的二进制(WKB)格式
19.4. 创建具备空间功能的MySQL数据库
19.4.1. MySQL空间数据类型
19.4.2. 创建空间值
19.4.3. 创建空间列
19.4.4. 填充空间列
19.4.5. 获取空间数据
19.5. 分析空间信息
19.5.1. Geometry格式转换函数
19.5.2. Geometry函数
19.5.3. 从已有Geometry创建新Geometry的函数
19.5.4. 测试几何对象间空间关系的函数
19.5.5. 关于几何最小边界矩形(MBR)的关系
19.5.6. 测试几何类之间空间关系的函数
19.6. 优化空间分析
19.6.1. 创建空间索引
19.6.2. 使用空间索引
19.7. MySQL的一致性和兼容性
19.7.1. 尚未实施的GIS特性
20. 存储程序和函数
20.1. 存储程序和授权表
20.2. 存储程序的语法
20.2.1. CREATE PROCEDURE和CREATE FUNCTION
20.2.2. ALTER PROCEDURE和ALTER FUNCTION
20.2.3. DROP PROCEDURE和DROP FUNCTION
20.2.4. SHOW CREATE PROCEDURE和SHOW CREATE FUNCTION
20.2.5. SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS
20.2.6. CALL语句
20.2.7. BEGIN ... END复合语句
20.2.8. DECLARE语句
20.2.9. 存储程序中的变量
20.2.10. 条件和处理程序
20.2.11. 光标
20.2.12. 流程控制构造
20.3. 存储程序、函数、触发程序和复制:常见问题
20.4. 存储子程序和触发程序的二进制日志功能
21. 触发程序
21.1. CREATE TRIGGER语法
21.2. DROP TRIGGER语法
21.3. 使用触发程序
22. 视图
22.1. ALTER VIEW语法
22.2. CREATE VIEW语法
22.3. DROP VIEW语法
22.4. SHOW CREATE VIEW语法
23. INFORMATION_SCHEMA信息数据库
23.1. INFORMATION_SCHEMA表
23.1.1. INFORMATION_SCHEMA SCHEMATA表
23.1.2. INFORMATION_SCHEMA TABLES表
23.1.3. INFORMATION_SCHEMA COLUMNS表
23.1.4. INFORMATION_SCHEMA STATISTICS表
23.1.5. INFORMATION_SCHEMA USER_PRIVILEGES表
23.1.6. INFORMATION_SCHEMA SCHEMA_PRIVILEGES表
23.1.7. INFORMATION_SCHEMA TABLE_PRIVILEGES表
23.1.8. INFORMATION_SCHEMA COLUMN_PRIVILEGES表
23.1.9. INFORMATION_SCHEMA CHARACTER_SETS表
23.1.10. INFORMATION_SCHEMA COLLATIONS表
23.1.11. INFORMATION_SCHEMA COLLATION_CHARACTER_SET_APPLICABILITY表
23.1.12. INFORMATION_SCHEMA TABLE_CONSTRAINTS表
23.1.13. INFORMATION_SCHEMA KEY_COLUMN_USAGE表
23.1.14. INFORMATION_SCHEMA ROUTINES表
23.1.15. INFORMATION_SCHEMA VIEWS表
23.1.16. INFORMATION_SCHEMA TRIGGERS表
23.1.17. 其他INFORMATION_SCHEMA表
23.2. SHOW语句的扩展
24. 精度数学
24.1. 数值的类型
24.2. DECIMAL数据类型更改
24.3. 表达式处理
24.4. 四舍五入
24.5. 精度数学示例
25. API和库
25.1. libmysqld,嵌入式MySQL服务器库
25.1.1. 嵌入式MySQL服务器库概述
25.1.2. 使用libmysqld编译程序
25.1.3. 使用嵌入式MySQL服务器时的限制
25.1.4. 与嵌入式服务器一起使用的选项
25.1.5. 嵌入式服务器中尚需完成的事项(TODO)
25.1.6. 嵌入式服务器示例
25.1.7. 嵌入式服务器的许可
25.2. MySQL C API
25.2.1. C API数据类型
25.2.2. C API函数概述
25.2.3. C API函数描述
25.2.4. C API预处理语句
25.2.5. C API预处理语句的数据类型
25.2.6. C API预处理语句函数概述
25.2.7. C API预处理语句函数描述
25.2.8. C API预处理语句方面的问题
25.2.9. 多查询执行的C API处理
25.2.10. 日期和时间值的C API处理
25.2.11. C API线程函数介绍
25.2.12. C API嵌入式服务器函数介绍
25.2.13. 使用C API时的常见问题
25.2.14. 创建客户端程序
25.2.15. 如何生成线程式客户端
25.3. MySQL PHP API
25.3.1. 使用MySQL和PHP的常见问题
25.4. MySQL Perl API
25.5. MySQL C++ API
25.5.1. Borland C++
25.6. MySQL Python API
25.7. MySQL Tcl API
25.8. MySQL Eiffel Wrapper
25.9. MySQL程序开发实用工具
25.9.1. msql2mysql:转换mSQL程序以用于MySQL
25.9.2. mysql_config:获取编译客户端的编译选项
26. 连接器
26.1. MySQL Connector/ODBC
26.1.1. MyODBC介绍
26.1.2. 关于ODBC和MyODBC的一般信息
26.1.3. 如何安装MyODBC
26.1.4. 在Windows平台上从二进制版本安装MyODBC
26.1.5. I在Unix平台上从二进制版本安装MyODBC
26.1.6. 在Windows平台上从源码版本安装MyODBC
26.1.7. 在Unix平台上从源码版本安装MyODBC
26.1.8. 从BitKeeper开发源码树安装MyODBC
26.1.9. MyODBC配置
26.1.10. 与MyODBC连接相关的事宜
26.1.11. MyODBC和Microsoft Access
26.1.12. MyODBC和Microsoft VBA及ASP
26.1.13. MyODBC和第三方ODBC工具
26.1.14. MyODBC通用功能
26.1.15. 基本的MyODBC应用步骤
26.1.16. MyODBC API引用
26.1.17. MyODBC数据类型
26.1.18. MyODBC错误代码
26.1.19. MyODBC与VB:ADO、DAO和RDO
26.1.20. MyODBC与Microsoft.NET
26.1.21. 感谢
26.2. MySQL Connector/NET
26.2.1. 前言
26.2.2. 下载并安装MySQL Connector/NET
26.2.3. Connector/NET体系结构
26.2.4. 使用MySQL Connector/NET
26.2.5. MySQL Connector/NET变更史
26.3. MySQL Connector/J
26.3.1. 基本的JDBC概念
26.3.2. 安装 Connector/J
26.3.3. JDBC引用
26.3.4. 与J2EE和其他Java框架一起使用 Connector/J
26.3.5. 诊断 Connector/J方面的问题
26.3.6. Changelog
26.4. MySQL Connector/MXJ
26.4.1. 前言
26.4.2. 支持平台:
26.4.3. Junit测试要求
26.4.4. 运行Junit测试
26.4.5. 作为JDBC驱动程序的一部分运行
26.4.6. 在Java对象中运行
26.4.7. MysqldResource API
26.4.8. 在JMX代理(custom)中运行
26.4.9. 部署在标准的JMX代理环境下 (JBoss)
26.4.10. 安装
27. 扩展MySQL
27.1. MySQL内部控件
27.1.1. MySQL线程
27.1.2. MySQL测试套件
27.2. 为MySQL添加新函数
27.2.1. 自定义函数接口的特性
27.2.2. CREATE FUNCTION/DROP FUNCTION语法
27.2.3. 添加新的自定义函数
27.2.4. 添加新的固有函数
27.3. 为MySQL添加新步骤
27.3.1. 步骤分析
27.3.2. 编写步骤
A. 问题和常见错误
A.1. 如何确定导致问题的原因
A.2. 使用MySQL程序时的常见错误
A.2.1. 拒绝访问
A.2.2. 无法连接到[local] MySQL服务器
A.2.3. 客户端不支持鉴定协议
A.2.4. 输入密码时出现密码错误
A.2.5. 主机的host_name被屏蔽
A.2.6. 连接数过多
A.2.7. 内存溢出
A.2.8. MySQL服务器不可用
A.2.9. 信息包过大
A.2.10. 通信错误和失效连接
A.2.11. 表已满
A.2.12. 无法创建文件/写入文件
A.2.13. 命令不同步
A.2.14. 忽略用户
A.2.15. 表tbl_name不存在
A.2.16. 无法初始化字符集
A.2.17. 文件未找到
A.3. 与安装有关的事宜
A.3.1. 与MySQL客户端库的链接问题
A.3.2. 如何以普通用户身份运行MySQL
A.3.3. 与文件许可有关的问题
A.4. 与管理有关的事宜
A.4.1. 如何复位根用户密码
A.4.2. 如果MySQL依然崩溃,应作些什么
A.4.3. MySQL处理磁盘满的方式
A.4.4. MySQL将临时文件储存在哪里
A.4.5. 如何保护或更改MySQL套接字文件/tmp/mysql.sock
A.4.6. 时区问题
A.5. 与查询有关的事宜
A.5.1. 搜索中的大小写敏感性
A.5.2. 使用DATE列方面的问题
A.5.3. 与NULL值有关的问题
全面解析JDBC文档。
综述:Java数据库连接体系结构是用于Java应用程序连接数据库的标准方法。JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。JDBC使用已有的SQL标准并支持与其它数据库连接标准,如ODBC之间的桥接。JDBC实现了所有这些面向标准的目标并且具有简单、严格类型定义且高性能实现的接口。
如何选择合适的JDBC产品?
有关JDBC最新的信息,有兴趣的读者可以查阅JDBC的官方网站--即JavaSoft的主页,其URL为:http://Java.sun.com/products/jdbc
1. JavaSoft框架
JavaSoft提供三种JDBC产品组件,它们是Java开发工具包(JDK)的组成部份:JDBC驱动程序管理器、JDBC驱动程序测试工具包和JDBC-ODBC桥。
JDBC驱动程序管理器是JDBC体系结构的支柱。它实际上很小,也很简单;其主要作用是把Java应用程序连接到正确的JDBC驱动程序上,然后即退出。
JDBC驱动程序测试工具包为使JDBC驱动程序运行您的程序提供一定的可信度。只有通过JDBC驱动程序测试的驱动程序才被认为是符合JDBC标准TM的。
JDBC-ODBC桥使ODBC驱动程序可被用作JDBC驱动程序。它的实现为JDBC的快速发展提供了一条途径,其长远目标提供一种访问某些不常见的DBMS(如果对这些不常见的DBMS未实现JDBC)的方法。
2. JDBC驱动程序的类型
目前比较常见的JDBC驱动程序可分为以下四个种类:
(1)JDBC-ODBC桥加ODBC驱动程序
JavaSoft桥产品利用ODBC驱动程序提供JDBC访问。注意,必须将ODBC二进制代码(许多情况下还包括数据库客户机代码)加载到使用该驱动程序的每个客户机上。因此,这种类型的驱动程序最适合于企业网(这种网络上客户机的安装不是主要问题),或者是用Java编写的三层结构的应用程序服务器代码。
(2)本地API
这种类型的驱动程序把客户机API上的JDBC调用转换为Oracle、Sybase、Informix、DB2或其它DBMS的调用。注意,象桥驱动程序一样,这种类型的驱动程序要求将某些二进制代码加载到每台客户机上。
(3)JDBC网络纯Java驱动程序
这种驱动程序将JDBC转换为与DBMS无关的网络协议,之后这种协议又被某个服务器转换为一种DBMS协议。这种网络服务器中间件能够将它的纯Java客户机连接到多种不同的数据库上。所用的具体协议取决于提供者。通常,这是最为灵活的JDBC驱动程序。有可能所有这种解决方案的提供者都提供适合于Intranet用的产品。为了使这些产品也支持Internet访问,它们必须处理Web所提出的安全性、通过防火墙的访问等方面的额外要求。几家提供者正将JDBC驱动程序加到他们现有的数据库中间件产品中。
(4)本地协议纯Java驱动程序
这种类型的驱动程序将JDBC调用直接转换为DBMS所使用的网络协议。这将允许从客户机机器上直接调用DBMS服务器,是Intranet访问的一个很实用的解决方法。由于许多这样的协议都是专用的,因此数据库提供者自己将是主要来源,有几家提供者已在着手做这件事了。
据专家预计第(3)、(4)类驱动程序将成为从JDBC访问数据库的首方法。第(1)、(2)类驱动程序在直接的纯Java驱动程序还没有上市前会作为过渡方案来使用。对第(1)、(2)类驱动程序可能会有一些变种,这些变种要求有连接器,但通常这些是更加不可取的解决方案。第(3)、(4)类驱动程序提供了Java的所有优点,包括自动安装(例如,通过使用JDBC驱动程序的appletapplet来下载该驱动程序)。
3. JDBC驱动程序的获取
目前已有几十个(1)类的驱动程序,即可与Javasoft桥联合使用的ODBC驱动程序的驱动程序。有大约十多个属于种类(2)的驱动程序是以DBMS的本地API为基础编写的。只有几个属于种类(3)的驱动程序,其首批提供者是SCO、OpenHorizon、Visigenic和WebLogic。此外,JavaSoft和数据库连接的领先提供者Intersolv还合作研制了JDBC-ODBC桥和JDBC驱动程序测试工具包。
如何建立JDBC连接?
Connection 对象代表与数据库的连接。连接过程包括所执行的 SQL 语句和在该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与许多数据库有连接。
1. 打开连接
与数据库建立连接的标准方法是调用DriverManager.getConnection方法。该方法接受含有某个URL的字符串。DriverManager类(即所谓的JDBC管理层)将尝试找到可与那个URL所代表的数据库进行连接的驱动程序。DriverManager类存有已注册的Driver类的清单。当调用方法getConnection时,它将检查清单中的每个驱动程序,直到找到可与URL中指定的数据库进行连接的驱动程序为止。Driver的方法connect使用这个URL来建立实际的连接。
用户可绕过JDBC管理层直接调用Driver方法。这在以下特殊情况下将很有用:当两个驱动器可同时连接到数据库中,而用户需要明确地选用其中特定的驱动器。但一般情况下,让DriverManager类处理打开连接这种事将更为简单。
下述代码显示如何打开一个与位于URL"jdbc:odbc:wombat"的数据库的连接。所用的用户标识符为"freely",口令为"ec":
String url = "jdbc:odbc:wombat";
Connection con = DriverManager.getConnection(url, "freely", "ec");
2. 一般用法的URL
由于URL常引起混淆,我们将先对一般URL作简单说明,然后再讨论JDBCURL。URL(统一资源定位符)提供在Internet上定位资源所需的信息。可将它想象为一个地址。URL的第一部份指定了访问信息所用的协议,后面总是跟着冒号。常用的协议有"ftp"(代表"文件传输协议")和"http"(代表"超文本传输协议")。如果协议是"file",表示资源是在某个本地文件系统上而非在Internet上(下例用于表示我们所描述的部分;它并非URL的组成部分)。
ftp://Javasoft.com/docs/JDK-1_apidocs.zip
http://Java.sun.com/products/jdk/CurrentRelease
file:/home/haroldw/docs/books/tutorial/summary.html
URL的其余部份(冒号后面的)给出了数据资源所处位置的有关信息。如果协议是file,则URL的其余部份是文件的路径。对于ftp和http协议,URL的其余部份标识了主机并可选地给出某个更详尽的地址路径。例如,以下是JavaSoft主页的URL。该URL只标识了主机:http://Java.sun.com。从该主页开始浏览,就可以进到许多其它的网页中,其中之一就是JDBC主页。JDBC主页的URL更为具体,它具体表示为:
http://Java.sun.com/products/jdbc
3. JDBC URL
JDBC URL提供了一种标识数据库的方法,可以使相应的驱动程序能识别该数据库并与之建立连接。实际上,驱动程序编程员将决定用什么JDBC URL来标识特定的驱动程序。用户不必关心如何来形成JDBC URL;他们只须使用与所用的驱动程序一起提供的URL即可。JDBC的作用是提供某些约定,驱动程序编程员在构造他们的JDBC URL时应该遵循这些约定。
由于JDBC URL要与各种不同的驱动程序一起使用,因此这些约定应非常灵活。首先,它们应允许不同的驱动程序使用不同的方案来命名数据库。例如,odbc子协议允许(但并不是要求)URL含有属性值。
其次,JDBC URL应允许驱动程序编程员将一切所需的信息编入其中。这样就可以让要与给定数据库对话的applet打开数据库连接,而无须要求用户去做任何系统管理工作。
最后,JDBC URL应允许某种程度的间接性。也就是说,JDBC URL可指向逻辑主机或数据库名,而这种逻辑主机或数据库名将由网络命名系统动态地转换为实际的名称。这可以使系统管理员不必将特定主机声明为JDBC名称的一部份。网络命名服务(例如DNS、NIS和DCE)有多种,而对于使用哪种命名服务并无限制。
JDBC URL的标准语法如下所示。它由三部分组成,各部分间用冒号分隔:
jdbc:<子协遥荆海甲用疲?br> JDBC URL的三个部分可分解如下:
(1)jdbc协议:JDBC URL中的协议总是jdbc。
(2)<子协议>:驱动程序名或数据库连接机制(这种机制可由一个或多个驱动程序支持)的名称。子协议名的典型示例是"odbc",该名称是为用于指定ODBC风格的数据资源名称的URL专门保留的。例如,为了通过JDBC-ODBC桥来访问某个数据库,可以用如下所示的URL:jdbc:odbc:book。本例中,子协议为"odbc",子名称"book"是本地ODBC数据资源。如果要用网络命名服务(这样JDBC URL中的数据库名称不必是实际名称),则命名服务可以作为子协议。例如,可用如下所示的URL:jdbc:dcenaming:accounts。本例中,该URL指定了本地DCE命名服务应该将数据库名称"accounts"解析为更为具体的可用于连接真实数据库的名称。
(3)<子名称>:种标识数据库的方法。子名称可以依不同的子协议而变化。它还可以有子名称的子名称(含有驱动程序编程员所选的任何内部语法)。使用子名称的目的是为定位数据库提供足够的信息。前例中,因为ODBC将提供其余部份的信息,因此用"book"就已足够。然而,位于远程服务器上的数据库需要更多的信息。例如,如果数据库是通过Internet来访问的,则在JDBC URL中应将网络地址作为子名称的一部份包括进去,且必须遵循如下所示的标准URL命名约定://主机名:端口/子协议。
假设"dbnet"是个用于将某个主机连接到Internet上的协议,则JDBC URL应为:jdbc:dbnet://wombat:356/fred。
4. "odbc"子协议
子协议odbc是一种特殊情况。它是为用于指定ODBC风格的数据资源名称的URL而保留的,并具有下列特性:允许在子名称(数据资源名称)后面指定任意多个属性值。odbc子协议的完整语法为:
jdbc:odbc:<数据资源名称>[;<属性名>=<属性值>],因此,以下都是合法的jdbc:odbc名称:
jdbc:odbc:qeor7
jdbc:odbc:wombat
jdbc:odbc:wombat;CacheSize=20;ExtensionCase=LOWER
jdbc:odbc:qeora;UID=kgh;PWD=fooey
5. 注册子协议
驱动程序编程员可保留某个名称以将之用作JDBC URL的子协议名。当DriverManager类将此名称加到已注册的驱动程序清单中时,为之保留该名称的驱动程序应能识别该名称并与它所标识的数据库建立连接。例如,odbc是为JDBC-ODBC桥而保留的。假设有个Miracle公司,它可能会将"miracle"注册为连接到其Miracle DBMS上的JDBC驱动程序的子协议,从而使其他人都无法使用这个名称。
JavaSoft目前作为非正式代理负责注册JDBC子协议名称。要注册某个子协议名称,请发送电子邮件到下述地址:jdbc@wombat.eng.sun.com。
6. 发送SQL语句
连接一旦建立,就可用来向它所涉及的数据库传送SQL语句。JDBC对可被发送的SQL语句类型不加任何限制。这就提供了很大的灵活性,即允许使用特定的数据库语句或甚至于非SQL语句。然而,它要求用户自己负责确保所涉及的数据库可以处理所发送的SQL语句,否则将自食其果。例如,如果某个应用程序试图向不支持储存程序的DBMS发送储存程序调用,就会失败并将抛出异常。JDBC要求驱动程序应至少能提供ANSI SQL-2 Entry Level功能才可算是符合JDBC标准TM的。这意味着用户至少可信赖这一标准级别的功能。
JDBC提供了三个类,用于向数据库发送SQL语句。Connection接口中的三个方法可用于创建这些类的实例。下面列出这些类及其创建方法:
(1)Statement:由方法createStatement所创建。Statement对象用于发送简单的SQL语句。
(2)PreparedStatement:由方法prepareStatement所创建。PreparedStatement对象用于发送带有一个或多个输入参数(IN参数)的SQL语句。PreparedStatement拥有一组方法,用于设置IN参数的值。执行语句时,这些IN参数将被送到数据库中。PreparedStatement的实例扩展了Statement,因此它们都包括了Statement的方法。PreparedStatement对象有可能比Statement对象的效率更高,因为它已被预编译过并存放在那以供将来使用。
(3)CallableStatement:由方法prepareCall所创建。CallableStatement对象用于执行SQL储存程序─一组可通过名称来调用(就象函数的调用那样)的SQL语句。CallableStatement对象从PreparedStatement中继承了用于处理IN参数的方法,而且还增加了用于处理OUT参数和INOUT参数的方法。
不过通常来说createStatement方法用于简单的SQL语句(不带参数)、prepareStatement方法用于带一个或多个IN参数的SQL语句或经常被执行的简单SQL语句,而prepareCall方法用于调用已储存过程。
7. 事务
事务由一个或多个这样的语句组成:这些语句已被执行、完成并被提交或还原。当调用方法commit或rollback时,当前事务即告就结束,另一个事务随即开始。缺省情况下,新连接将处于自动提交模式。也就是说,当执行完语句后,将自动对那个语句调用commit方法。这种情况下,由于每个语句都是被单独提交的,因此一个事务只由一个语句组成。如果禁用自动提交模式,事务将要等到commit或rollback方法被显式调用时才结束,因此它将包括上一次调用commit或rollback方法以来所有执行过的语句。对于第二种情况,事务中的所有语句将作为组来提交或还原。
方法commit使SQL语句对数据库所做的任何更改成为永久性的,它还将释放事务持有的全部锁。而方法rollback将弃去那些更改。有时用户在另一个更改生效前不想让此更改生效。这可通过禁用自动提交并将两个更新组合在一个事务中来达到。如果两个更新都是成功,则调用commit方法,从而使两个更新结果成为永久性的;如果其中之一或两个更新都失败了,则调用rollback方法,以将值恢复为进行更新之前的值。
大多数JDBC驱动程序都支持事务。事实上,符合JDBC的驱动程序必须支持事务。DatabaseMetaData给出的信息描述DBMS所提供的事务支持水平。
8. 事务隔离级别
如果DBMS支持事务处理,它必须有某种途径来管理两个事务同时对一个数据库进行操作时可能发生的冲突。用户可指定事务隔离级别,以指明DBMS应该花多大精力来解决潜在冲突。例如,当事务更改了某个值而第二个事务却在该更改被提交或还原前读取该值时该怎么办。
假设第一个事务被还原后,第二个事务所读取的更改值将是无效的,那么是否可允许这种冲突?JDBC用户可用以下代码来指示DBMS允许在值被提交前读取该值("dirty读取"),其中con是当前连接:
con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);
事务隔离级别越高,为避免冲突所花的精力也就越多。Connection接口定义了五级,其中最低级别指定了根本就不支持事务,而最高级别则指定当事务在对某个数据库进行操作时,任何其它事务不得对那个事务正在读取的数据进行任何更改。通常,隔离级别越高,应用程序执行的速度也就越慢(由于用于锁定的资源耗费增加了,而用户间的并发操作减少了)。在决定采用什么隔离级别时,开发人员必须在性能需求和数据一致性需求之间进行权衡。当然,实际所能支持的级别取决于所涉及的DBMS的功能。
当创建Connection对象时,其事务隔离级别取决于驱动程序,但通常是所涉及的数据库的缺省值。用户可通过调用setIsolationLevel方法来更改事务隔离级别。新的级别将在该连接过程的剩余时间内生效。要想只改变一个事务的事务隔离级别,必须在该事务开始前进行设置,并在该事务结束后进行复位。我们不提倡在事务的中途对事务隔离级别进行更改,因为这将立即触发commit方法的调用,使在此之前所作的任何更改变成永久性的。
JDBC驱动管理内幕是怎么样的?
DriverManager 类是 JDBC 的管理层,作用于用户和驱动程序之间。它跟踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接。另外,DriverManager类也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等事务。
对于简单的应用程序,一般程序员需要在此类中直接使用的唯一方法是DriverManager.getConnection。正如名称所示,该方法将建立与数据库的连接。JDBC允许用户调用DriverManager的方法getDriver、getDrivers和registerDriver及Driver的方法connect。但多数情况下,让DriverManager类管理建立连接的细节为上策。
1. 跟踪可用驱动程序
DriverManager类包含一列Driver类,它们已通过调用方法DriverManager.registerDriver对自己进行了注册。所有Driver类都必须包含有一个静态部分。它创建该类的实例,然后在加载该实例时DriverManager类进行注册。这样,用户正常情况下将不会直接调用DriverManager.registerDriver;而是在加载驱动程序时由驱动程序自动调用。加载Driver类,然后自动在DriverManager中注册的方式有两种:
(1)调用方法Class.forName
这将显式地加载驱动程序类。由于这与外部设置无关,因此推荐使用这种加载驱动程序的方法。以下代码加载类acme.db.Driver:Class.forName("acme.db.Driver")。
如果将acme.db.Driver编写为加载时创建实例,并调用以该实例为参数的DriverManager.registerDriver(本该如此),则它在DriverManager的驱动程序列表中,并可用于创建连接。
(2)将驱动程序添加到Java.lang.System的属性jdbc.drivers中
这是一个由DriverManager类加载的驱动程序类名的列表,由冒号分隔:初始化DriverManager类时,它搜索系统属性jdbc.drivers,如果用户已输入了一个或多个驱动程序,则DriverManager类将试图加载它们。以下代码说明程序员如何在~/.hotJava/properties中输入三个驱动程序类(启动时,HotJava将把它加载到系统属性列表中):
jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.test.ourDriver;
对DriverManager方法的第一次调用将自动加载这些驱动程序类。注意:加载驱动程序的第二种方法需要持久的预设环境。如果对这一点不能保证,则调用方法Class.forName显式地加载每个驱动程序就显得更为安全。这也是引入特定驱动程序的方法,因为一旦DriverManager类被初始化,它将不再检查jdbc.drivers属性列表。
在以上两种情况中,新加载的Driver类都要通过调用DriverManager.registerDriver类进行自我注册。如上所述,加载类时将自动执行这一过程。
由于安全方面的原因,JDBC管理层将跟踪哪个类加载器提供哪个驱动程序。这样,当DriverManager类打开连接时,它仅使用本地文件系统或与发出连接请求的代码相同的类加载器提供的驱动程序。
2. 建立连接
加载Driver类并在DriverManager类中注册后,它们即可用来与数据库建立连接。当调用DriverManager.getConnection方法发出连接请求时,DriverManager将检查每个驱动程序,查看它是否可以建立连接。
有时可能有多个JDBC驱动程序可以与给定的URL连接。例如,与给定远程数据库连接时,可以使用JDBC-ODBC桥驱动程序、JDBC到通用网络协议驱动程序或数据库厂商提供的驱动程序。在这种情况下测试驱动程序的顺序至关重要,因为DriverManager将使用它所找到的第一个可以成功连接到给定URL的驱动程序。
首先DriverManager试图按注册的顺序使用每个驱动程序(jdbc.drivers中列出的驱动程序总是先注册)。它将跳过代码不可信任的驱动程序,除非加载它们的源与试图打开连接的代码的源相同。它通过轮流在每个驱动程序上调用方法Driver.connect,并向它们传递用户开始传递给方法DriverManager.getConnection的URL来对驱动程序进行测试,然后连接第一个认出该URL的驱动程序。这种方法初看起来效率不高,但由于不可能同时加载数十个驱动程序,因此每次连接实际只需几个过程调用和字符串比较。
以下代码是通常情况下用驱动程序(例如JDBC-ODBC桥驱动程序)建立连接所需所有步骤的示例:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//加载驱动程序
String url = "jdbc:odbc:fred";
DriverManager.getConnection(url,"userID","passwd");
如何利用JDBC发送SQL语句?
Statement对象用于将SQL语句发送到数据库中。实际上有三种Statement对象,它们都作为在给定连接上执行SQL语句的包容器:Statement、PreparedStatement(它从Statement继承而来)和CallableStatement(它从PreparedStatement继承而来)。它们都专用于发送特定类型的SQL语句:Statement对象用于执行不带参数的简单SQL语句;PreparedStatement对象用于执行带或不带IN参数的预编译SQL语句;CallableStatement对象用于执行对数据库已存储过程的调用。
Statement接口提供了执行语句和获取结果的基本方法;PreparedStatement接口添加了处理IN参数的方法;而CallableStatement添加了处理OUT参数的方法。
1. 创建Statement对象
建立了到特定数据库的连接之后,就可用该连接发送SQL语句。Statement对象用Connection的方法createStatement创建,如下列代码段中所示:
Connection con = DriverManager.getConnection(url,"sunny","");
Statement stmt = con.createStatement();
为了执行Statement对象,被发送到数据库的SQL语句将被作为参数提供给Statement的方法:
ResultSet rs = stmt.executeQuery("SELECT a,b,c FROM Table2");
2. 使用Statement对象执行语句
Statement接口提供了三种执行SQL语句的方法:executeQuery、executeUpdate和execute。使用哪一个方法由SQL语句所产生的内容决定。
方法executeQuery用于产生单个结果集的语句,例如SELECT语句。方法executeUpdate用于执行INSERT、UPDATE或DELETE语句以及SQL DDL(数据定义语言)语句,例如CREATE TABLE和DROP TABLE。INSERT、UPDATE或DELETE语句的效果是修改表中零行或多行中的一列或多列。executeUpdate的返回值是一个整数,指示受影响的行数(即更新计数)。对于CREATE TABLE或DROP TABLE等不操作行的语句,executeUpdate的返回值总为零。
执行语句的所有方法都将关闭所调用的Statement对象的当前打开结果集(如果存在)。这意味着在重新执行Statement对象之前,需要完成对当前ResultSet对象的处理。应注意,继承了Statement接口中所有方法的PreparedStatement接口都有自己的executeQuery、executeUpdate和execute方法。Statement对象本身不包含SQL语句,因而必须给Statement.execute方法提供SQL语句作为参数。PreparedStatement对象并不需要SQL语句作为参数提供给这些方法,因为它们已经包含预编译SQL语句。
CallableStatement对象继承这些方法的PreparedStatement形式。对于这些方法的PreparedStatement或CallableStatement版本,使用查询参数将抛出SQLException。
3. 语句完成
当连接处于自动提交模式时,其中所执行的语句在完成时将自动提交或还原。语句在已执行且所有结果返回时,即认为已完成。对于返回一个结果集的executeQuery方法,在检索完ResultSet对象的所有行时该语句完成。对于方法executeUpdate,当它执行时语句即完成。但在少数调用方法execute的情况中,在检索所有结果集或它生成的更新计数之后语句才完成。
有些DBMS将已存储过程中的每条语句视为独立的语句;而另外一些则将整个过程视为一个复合语句。在启用自动提交时,这种差别就变得非常重要,因为它影响什么时候调用commit方法。在前一种情况中,每条语句单独提交;在后一种情况中,所有语句同时提交。
4. 关闭Statement对象
Statement对象将由Java垃圾收集程序自动关闭。而作为一种好的编程风格,应在不需要Statement对象时显式地关闭它们。这将立即释放DBMS资源,有助于避免潜在的内存问题。
5. 使用方法execute
execute方法应该仅在语句能返回多个ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用。当执行某个已存储过程或动态执行未知SQL字符串(即应用程序程序员在编译时未知)时,有可能出现多个结果的情况,尽管这种情况很少见。例如,用户可能执行一个已存储过程,并且该已存储过程可执行更新,然后执行选择,再进行更新,再进行选择,等等。通常使用已存储过程的人应知道它所返回的内容。
因为方法execute处理非常规情况,所以获取其结果需要一些特殊处理并不足为怪。例如,假定已知某个过程返回两个结果集,则在使用方法execute执行该过程后,必须调用方法getResultSet获得第一个结果集,然后调用适当的getXXX方法获取其中的值。要获得第二个结果集,需要先调用getMoreResults方法,然后再调用getResultSet方法。如果已知某个过程返回两个更新计数,则首先调用方法getUpdateCount,然后调用getMoreResults,并再次调用getUpdateCount。
对于不知道返回内容,则情况更为复杂。如果结果是ResultSet对象,则方法execute返回true;如果结果是Javaint,则返回false。如果返回int,则意味着结果是更新计数或执行的语句是DL命令。在调用方法execute之后要做的第一件事情是调用getResultSet或getUpdateCount。调用方法getResultSet可以获得两个或多个ResultSet对象中第一个对象;或调用方法getUpdateCount可以获得两个或多个更新计数中第一个更新计数的内容。
当SQL语句的结果不是结果集时,则方法getResultSet将返回null。这可能意味着结果是一个更新计数或没有其它结果。在这种情况下,判断null真正含义的唯一方法是调用方法getUpdateCount,它将返回一个整数。这个整数为调用语句所影响的行数;如果为-1则表示结果是结果集或没有结果。如果方法getResultSet已返回null(表示结果不是ResultSet对象),则返回值-1表示没有其它结果。也就是说,当下列条件为真时表示没有结果(或没有其它结果):
((stmt.getResultSet()==null)&&(stmt.getUpdateCount()==-1))
如果已经调用方法getResultSet并处理了它返回的ResultSet对象,则有必要调用方法getMoreResults以确定是否有其它结果集或更新计数。如果getMoreResults返回true,则需要再次调用getResultSet来检索下一个结果集。如上所述,如果getResultSet返回null,则需要调用getUpdateCount来检查null是表示结果为更新计数还是表示没有其它结果。
当getMoreResults返回false时,它表示该SQL语句返回一个更新计数或没有其它结果。因此需要调用方法getUpdateCount来检查它是哪一种情况。在这种情况下,当下列条件为真时表示没有其它结果:
((stmt.getMoreResults()==false)&&(stmt.getUpdateCount()==-1))
下面的代码演示了一种方法用来确认已访问调用方法execute所产生的全部结果集和更新计数:
stmt.execute(queryStringWithUnknownResults);
while(true){
introwCount=stmt.getUpdateCount();
if(rowCount>0){//它是更新计数
System.out.println("Rows changed="+count);
stmt.getMoreResults();
continue;
}
if(rowCount==0){//DDL命令或0个更新
System.out.println("No rows changed or statement was DDL command");
stmt.getMoreResults();
continue;
}
//执行到这里,证明有一个结果集
//或没有其它结果
ResultSet rs=stmt.getResultSet();
if(rs!=null){
...//使用元数据获得关于结果集列的信息
while(rs.next()){
...//处理结果
stmt.getMoreResults();
continue;
}
break;//没有其它结果
如何获得SQL语句的执行结果?
ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问。ResultSet.next方法用于移动到ResultSet中的下一行,使下一行成为当前行。
下面的代码段是执行SQL语句的示例。该SQL语句将返回行集合,其中列1为int,列2为String,而列3则为字节数组:
Java.sql.Statementstmt=conn.createStatement();
ResultSet r=stmt.executeQuery("SELECT a,b,c FROM Table1");
while(r.next()){
//打印当前行的值。
Int i=r.getInt("a");
String s=r.getString("b");
Float f=r.getFloat("c");
System.out.println("ROW="+i+" "+s+" "+f);
}
1. 行和光标
ResultSet维护指向其当前数据行的光标。每调用一次next方法,光标向下移动一行。
最初它位于第一行之前,因此第一次调用next将把光标置于第一行上,使它成为当前行。随着每次调用next导致光标向下移动一行,按照从上至下的次序获取ResultSet行。
在ResultSet对象或其父辈Statement对象关闭之前,光标一直保持有效。在SQL中,结果表的光标是有名字的。如果数据库允许定位更新或定位删除,则需要将光标的名字作为参数提供给更新或删除命令。可通过调用方法getCursorName获得光标名。
DatabaseMetaData.supportsPositionedDelete和supportsPositionedUpdate方法来检查特定连接是否支持这些操作。当DBMS支持定位更新和删除操作时,DBMS/驱动程序必须确保适当锁定选定行,以使定位更新不会导致更新异常或其它并发问题。
2. 列
方法getXXX提供了获取当前行中某列值的途径。在每一行内,可按任何次序获取列值。但为了保证可移植性,应该从左至右获取列值,并且一次性地读取列值。
列名或列号可用于标识要从中获取数据的列。例如,如果ResultSet对象rs的第二列名为"title",并将值存储为字符串,则下列任一代码将获取存储在该列中的值:
String s=rs.getString("title");
String s=rs.getString(2);
注意列是从左至右编号的,并且从列1开始。同时,用作getXXX方法的输入的列名不区分大小写。
提供使用列名这个选项的目的是为了让在查询中指定列名的用户可使用相同的名字作为getXXX方法的参数。另一方面,如果select语句未指定列名(例如在"select * from table1"中或列是导出的时),则应该使用列号。这些情况下,用户将无法确切知道列名。
有些情况下,SQL查询返回的结果集中可能有多个列具有相同的名字。如果列名用作getXXX方法的参数,则getXXX将返回第一个匹配列名的值。因而,如果多个列具有相同的名字,则需要使用列索引来确保检索了正确的列值。这时,使用列号效率要稍微高一些。
关于ResultSet中列的信息,可通过调用方法ResultSet.getMetaData得到。返回的ResultSetMetaData对象将给出其ResultSet对象各列的编号、类型和属性。
如果列名已知,但不知其索引,则可用方法findColumn得到其列号。
3. 数据类型和转换
对于getXXX方法,JDBC驱动程序试图将基本数据转换成指定Java类型,
然后返回适合的Java值。例如,如果getXXX方法为getString,而基本数据库中数据类型为VARCHAR,则JDBC驱动程序将把VARCHAR转换成JavaString。getString的返回值将为JavaString对象。
4. 对非常大的行值使用流
ResultSet可以获取任意大的LONGVARBINARY或LONGVARCHAR数据。方法getBytes和getString将数据返回为大的块(最大为Statement.getMaxFieldSize的返回值)。但是,以较小的固定块获取非常大的数据可能会更方便,而这可通过让ResultSet类返回Java.io.Input流来完成。从该流中可分块读取数据。注意:必须立即访问这些流,因为在下一次对ResultSet调用getXXX时它们将自动关闭(这是由于基本实现对大块数据访问有限制)。
JDBCAPI具有三个获取流的方法,分别具有不同的返回值:
·getBinaryStream:返回只提供数据库原字节而不进行任何转换的流。
·getAsciiStream返回提供单字节ASCII字符的流。
·getUnicodeStream返回提供双字节Unicode字符的流。
注意:它不同于Java流,后者返回无类型字节并可(例如)通用于ASCII和Unicode字符。下列代码演示了getAsciiStream的用法:
Java.sql.Statementstmt=con.createStatement();
ResultSet r=stmt.executeQuery("SELECT x FROM Table2");
//现在以4K块大小获取列1结果:
byte buff=newbyte[4096];
while(r.next()){
Java.io.InputStream fin=r.getAsciiStream(1);
for(;;){
intsize=fin.read(buff);
if(size==-1){//到达流末尾
break;
}
//将新填充的缓冲区发送到ASCII输出流:
output.write(buff,0,size);
}
}
5. NULL结果值
要确定给定结果值是否是JDBC NULL,必须先读取该列,然后使用ResultSet.wasNull
方法检查该次读取是否返回JDBC NULL。
当使用ResultSet.getXXX方法读取JDBC NULL时,方法wasNull将返回下列值之一:
(1)Javanull值
对于返回Java对象的getXXX方法(例如getString、getBigDecimal、getBytes、getDate、getTime、getTimestamp、getAsciiStream、getUnicodeStream、getBinaryStream、getObject等)。
(2)零值:对于getByte、getShort、getInt、getLong、getFloat和getDouble。
(3)false值:对于getBoolean。
6. 可选结果集或多结果集
通常使用executeQuery(它返回单个ResultSet)或executeUpdate(它可用于任何数据库修改语句,并返回更新行数)可执行SQL语句。但有些情况下,应用程序在执行语句之前不知道该语句是否返回结果集。此外,有些已存储过程可能返回几个不同的结果集和/或更新计数。
为了适应这些情况,JDBC提供了一种机制,允许应用程序执行语句,然后处理由结果集和更新计数组成的任意集合。这种机制的原理是首先调用一个完全通用的execute方法,然后调用另外三个方法,getResultSet、getUpdateCount和getMoreResults。这些方法允许应用程序一次一个地研究语句结果,并确定给定结果是ResultSet还是更新计数。
用户不必关闭ResultSet;当产生它的Statement关闭、重新执行或用于从多结果序列中获取下一个结果时,该ResultSet将被Statement自动关闭。
基于JDBC有哪些数据库通用访问方法?
1. 通用数据库Bean设计
本实例中对数据库连接和执行SQL语句等通用数据库操作进行了封装,通过实现DBConnBean和DBQueryBean两个JavaBean来完成上述功能。其中DBConnBean负责Java应用程序和数据库的连接;DBQueryBean提供了一组执行标准SQL的功能,可以实现标准SQL完成的所有功能。其功能代码分别如下所示:
① DBConnBean.Java的源代码如下所示:
package dbaccess;
import Java.sql.*;
import Java.util.*;
import Java.io.*;
public class DBConnBean
implements Serializable{
private String DBDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
private String DBHost = "127.0.0.1";
private String DBName = "demo";
private String conp = "jdbc:odbc:db_demo";
private String username = "";
private String password = "";
private boolean xdebug = true;
public Connection con = null;
public String sql = null;
Statement stmt = null;
public ResultSet result = null;
private int affectedRows = 0;
public DBConnBean()
{
xdebug = true;
con = null;
sql = null;
}
public Connection Connect()
throws Exception
{
String msg = null;
try
{
Class.forName(DBDriver).newInstance();
}
catch(Exception e)
{
msg = "加载数据库驱动失败";
if (xdebug) msg += "(驱动'"+DBDriver+"')";
throw new Exception(msg);
}
try
{
String conStr = conp;
con = DriverManager.getConnection(conStr,username,password);
}
catch(SQLException e)
{
msg = "!!数据库连接失败";
if (xdebug)
{
msg += "(错误信息='" + e.getMessage()+"' SQL状态值='" + e.getSQLState()+"' 错误代码='" + e.getErrorCode()+"')";
}
throw new Exception(msg);
}
return con;
}
protected void finalize()
throws Throwable
{
super.finalize();
if (stmt != null) stmt.close();
if (result != null) result.close();
}
//最近一次对数据库查询受影响的行数
public int getAffectedRows()
{
return affectedRows;
}
public Connection getCon()
{
return con;
}
public String getConp()
{
return conp;
}
public String getDBDriver()
{
return DBDriver;
}
public String getDBName()
{
return DBName;
}
public boolean getDebug()
{
return xdebug;
}
public String getPassword()
{
return password;
}
public ResultSet getResult()
{
return result;
}
public String getSql()
{
return sql;
}
public String getUsername()
{
return username;
}
public void over()
throws Throwable
{
finalize();
}
public ResultSet query()
throws Exception
{
result = null;
affectedRows = 0;
if (con == null)
Connect();
if (stmt == null)
stmt = con.createStatement();
if (sql.substring(0,6).equalsIgnoreCase("select"))
{
result = stmt.executeQuery(sql);
}
else
{
affectedRows = stmt.executeUpdate(sql);
}
return result;
}
public ResultSet query(String s)
throws Exception
{
sql = s;
return query();
}
public void setDBDriver(String s)
{
DBDriver = s;
}
public void setDebug(boolean b)
{
xdebug = b;
}
public void setgetConp(String s)
{
conp = s;
}
public void setgetDBName(String s)
{
DBName = s;
}
public void setgetUsername(String s)
{
username = s;
}
public void setPassword(String s)
{
password = s;
}
public void setSql(String s)
{
sql = s;
}
}
② DBQueryBean.Java的源代码如下所示:
package dbaccess;
import Java.sql.*;
import Java.util.*;
import Java.io.*;
import Java.lang.reflect.*;
public class DBQueryBean
implements Serializable
{
DBConnBean dbc;
String sql = null;
int rowcount = 0;
int colcount = 0;
// int limitcount = 0;
Vector result = null;
public String _WATCH = "";
public DBQueryBean()
{
dbc = new DBConnBean();
try {
dbc.Connect();
} catch(Exception e) {
handleException(e);
}
}
protected void finalize()
throws Throwable
{
super.finalize();
if (dbc != null) dbc.over();
if (result != null) result.removeAllElements();
}
public String get(int row, int col)
{
if (result==null || row >= result.size()) return null;
String r[] = (String[])result.elementAt(row);
if (col >= Java.lang.reflect.Array.getLength(r)) return null;
return r[col];
}
public int getAffRows() { return dbc.getAffectedRows(); }
public int getColumncount() {
return colcount;
}
public String[] getRow(int row)
{
if (result==null || row >= result.size()) return null;
return (String [])result.elementAt(row);
/*String ret[] = new String[colcount];
Vector r = (Vector)result.elementAt(row);
for (int i=0; i<colcount; i++)
ret[i] = (String)r.elementAt(i);
return ret;*/
}
public int getRowcount() {
return rowcount;
}
public void handleException(Exception e)
{
_WATCH = e.getMessage();
}
public void init()
{
rowcount = 0;
colcount = 0;
// limitcount = 0;
result = null;
}
public void over()
throws Throwable
{
finalize();
}
public int query(String sql)
{
result = new Vector();
int ret = 0;
try {
ResultSet rs = dbc.query(sql);
if (rs == null)
{
ret = dbc.getAffectedRows();
}
else
{
ResultSetMetaData rm = rs.getMetaData();
colcount = rm.getColumnCount();
while (rs.next())
{
String row[] = new String[colcount];
for (int i=0; i<colcount; i++)
row[i] = rs.getString(i+1);
result.addElement(row);
rowcount++;
}
rs.close(); // to release the resource.
ret = result.size();
}
}
catch(Exception e)
{
handleException(e);
return -1;
}
return ret;
}
}
2. 数据库表结构
本实例中主要出现了三个数据库表,表名和字段分别如下所示:
计划采购表:jhcg_table
字段名称 中文名称 类型 长度
Goods_no 物品编号 vchar 10
Goods_name 物品名称 Vchar 50
Amount 采购数量 Int
Price 采购单价 float
Gold 币种 Vchar 15
Units 单位 Vchar 10
Date 时间 Date
Remark 备注 vchar 100
库存统计表:kctj_table
字段名称 中文名称 类型 长度
Goods_no 物品编号 Vchar 10
Goods_name 物品名称 Vchar 50
amount 库存数量 Int
Date 时间 Date
remark 备注 Vchar 100
实际采购表:sjcg_table
字段名称 中文名称 类型 长度
Goods_no 物品编号 Vchar 10
Goods_name 物品名称 Vchar 50
Amount 采购数量 Int
Price Price 采购单价 Float
Gold 币种 Vchar 15
Units 采购单位 Vchar 10
Date 时间 Date
Remark 备注 vchar 100
其中业务逻辑非常简单,即根据计划采购表和库存统计表生成实际采购表。同时,对各表完成数据库的增、删、改、查等通用操作。
3. JSP设计
① 插入操作
完成对数据库表的记录插入功能,其中计划采购表的插入主页面(insert_jhcg.htm)为:
图1 计划采购表插入主页面
insert_jhcg.htm将用户输入传送给demo_insert_jhcg.jsp,完成插入操作。改jsp文件的功能代码为:
<html>
<body>
<jsp:useBean id="DBConn" class="dbaccess.DBConnBean" scope="page"/>
<jsp:useBean id="DBBean" class="dbaccess.DBQueryBean" scope="page"/>
<hr>
<!--test JavaBean-->
<%
if (DBConn == null||DBBean == null){
out.println("JavaBean not found!");
return;
}
%>
<!--try db_demo connection-->
<%
try{
DBConn.Connect();
}catch(Exception e){
out.println(e.getMessage());
}
%>
<!--execute sql statement-->
<%
String insGoodno = request.getParameter("ed_jhcg_no");
String insGoodname = request.getParameter("ed_jhcg_name");
int insAmount = (Integer.valueOf(request.getParameter("ed_jhcg_amount"))).intValue();
float insPrice = (Float.valueOf(request.getParameter("ed_jhcg_price"))).floatValue();
String insGold = request.getParameter("ed_jhcg_gold");
String insUnit = request.getParameter("ed_jhcg_unit");
String insRemark = request.getParameter("ed_jhcg_remark");
String sqlStatement = "insert into jhcg_table(good_no,good_name,amount,
price,gold,unit,remark) values("+"'"+insGoodno+"'"+","+"'"+insGoodname+"'"+",
"+insAmount+","+insPrice+","+"'"+insGold+"'"+","+"'"+insUnit+"'"+","+"'"+
insRemark+"'"+")";
try{
DBBean.query(sqlStatement);
}catch(Exception e){
out.println(e.getMessage());
}
%>
<a href="demo_main.htm">Records inserted...Click here to return</a></p>
</body>
</html>
② 查询操作
该查询主页面主要提供对三个数据库表的条件查询功能,如下图所示:
图2 查询主页面
query.htm将用户选择查询的数据库表和查询条件发送给demo_query.jsp,由jsp文件完成数据库查询操作和查询结果集的返回及显示,其功能代码如下:
<html>
<body>
<%
String sqlStatement;
String sqlField = "";
String whichTable = "";
String whereClause = "";
String queryNo = "";
String queryName = "";
%>
<jsp:useBean id="DBConn" class="dbaccess.DBConnBean" scope="page"/>
<jsp:useBean id="DBBean" class="dbaccess.DBQueryBean" scope="page"/>
<hr>
<!--test JavaBean-->
<%
if (DBConn == null||DBBean == null){
out.println("JavaBean not found!");
return;
}
%>
<!--try db_demo connection-->
<%
try{
DBConn.Connect();
}catch(Exception e){
out.println(e.getMessage());
}
%>
<!--prepare sql statement-->
<%
String queryRequest = request.getParameter("rb_request");
//out.println("queryRequest:"+queryRequest);
String whichCB = "";
if (queryRequest.equals("1")){
whichCB = "ck_jhcg";
whichTable = "jhcg_table";
queryNo = request.getParameter("ed_jhcg_no");
queryName = request.getParameter("ed_jhcg_name");
if (!queryNo.equals(""))
whereClause = " where good_no="+"'"+queryNo+"'";
if (!queryName.equals("")){
if (!queryNo.equals(""))
whereClause += " and good_name="+"'"+queryName+"'";
else whereClause = " where good_name="+"'"+queryName+"'";
}
}
if (queryRequest.equals("2")){
whichCB = "ck_kctj";
whichTable = "kctj_table";
queryNo = request.getParameter("ed_kctj_no");
queryName = request.getParameter("ed_kctj_name");
if (!queryNo.equals(""))
whereClause = " where good_no="+"'"+queryNo+"'";
if (!queryName.equals("")){
if (!queryNo.equals(""))
whereClause += " and good_name="+"'"+queryName+"'";
else whereClause = " where good_name="+"'"+queryName+"'";
}
}
if (queryRequest.equals("3")){
whichCB = "ck_sjcg";
whichTable = "sjcg_table";
queryNo = request.getParameter("ed_sjcg_no");
queryName = request.getParameter("ed_sjcg_name");
if (!queryNo.equals(""))
whereClause = " where good_no="+"'"+queryNo+"'";
if (!queryName.equals("")){
if (!queryNo.equals(""))
whereClause += " and good_name="+"'"+queryName+"'";
else whereClause = " where good_name="+"'"+queryName+"'";
}
}
String[] printTitle = request.getParameterValues(whichCB);
%>
<!--create query sql statement-->
<%
sqlStatement = "select ";
for(int i = 0;i<printTitle.length;i++){
sqlField += printTitle[i]+",";
}
sqlStatement += sqlField.substring(0,sqlField.length()-1)+" from "+whichTable;
if (!whereClause.equals(""))
sqlStatement += whereClause;
%>
<!--show query response-->
<%
try{
DBBean.query(sqlStatement);
}catch(Exception e){
out.println("Database Error!");
}
int rows = DBBean.getRowcount();
int cols = DBBean.getColumncount();
%>
<Table align="center" width="80%" border=1>
<tr align=center>
<%
for(int i = 0;i < printTitle.length;i++){
out.println("<td><b>");
out.println(printTitle[i]);
out.println("</b></td>");
}
%>
</tr>
<%
for (int i = 0;i < rows;i++){
out.println("<tr>");
for (int j = 0;j < cols;j++)
out.println("<td>"+DBBean.get(i,j)+"</td>");
out.println("</tr>");
}
%>
</Table>
<br>
<hr>
<a href="demo_main.htm">Click here to return</a></p>
</body>
</html>
③ 生成实际采购表
生成数据库表是一个隐式操作,程序根据计划采购表和库存统计表的相应字段生成实际采购表,不需要用户的任何输入,其功能代码如下(demo_create.jsp):
<%@page import="Java.util.*"%>
<html>
<body>
<jsp:useBean id="DBConn" class="dbaccess.DBConnBean" scope="page"/>
<jsp:useBean id="DBBean" class="dbaccess.DBQueryBean" scope="page"/>
<hr>
<!--test JavaBean-->
<%
if (DBConn == null||DBBean == null){
out.println("JavaBean not found!");
return;
}
%>
<!--try db_demo connection-->
<%
try{
DBConn.Connect();
}catch(Exception e){
out.println(e.getMessage());
}
%>
<!--prepare sql statement-->
<%
int amount_jhcg,amount_kctj;
Vector updateRs = new Vector();
DBBean.query("delete * from sjcg_table"); //delete all old records in sjcg_table
DBBean.query("select jhcg_table.good_no,jhcg_table.good_name,jhcg_table.amount,kctj_table.amount,jhcg_table.unit from jhcg_table left join kctj_table on kctj_table.good_no=jhcg_table.good_no");
int rows = DBBean.getRowcount();
int cols = DBBean.getColumncount();
for (int i = 0;i < rows;i++){
String record[] = new String[4];
record[0] = DBBean.get(i,0);
record[1] = DBBean.get(i,1);
amount_jhcg = (Integer.valueOf(DBBean.get(i,2))).intValue();
if (DBBean.get(i,3) == null) amount_kctj = 0;
else amount_kctj = (Integer.valueOf(DBBean.get(i,3))).intValue();
record[2] = Integer.toString(amount_jhcg - amount_kctj);
record[3] = DBBean.get(i,4);
updateRs.addElement(record);
}
for (int i = 0;i < rows;i++){
String insRecord[] = (String [])updateRs.elementAt(i);
String insGoodno,insGoodname,insUnit,insAmount;
insGoodno = insRecord[0];
insGoodname = insRecord[1];
insAmount = insRecord[2];
insUnit = insRecord[3];
String sqlStatement = "insert into sjcg_table(good_no,good_name,amount,unit) values?quot;+"'"+insGoodno+"'"+","+"'"+insGoodname+"'"+","+insAmount+","+"'"+insUnit+"'"+")";
DBBean.query(sqlStatement);
DBBean.query("delete * from sjcg_table where amount<=0");
}
%>
<a href="demo_main.htm">Database created...Click here to return</a></p>
</body>
</html>
上述的开发工具综合应用介绍了基于Java开发电子商务应用系统的全过程,包括应用开发平台搭建、业务流程分析、JavaBean封装和JSP开发等内容,其中JSP开发中涉及到了通用SQL(查询和插入数据库表)和游标操作(生成实际采购表),基本可以完成任何网络数据库应用的需求。本实例基本上可以将前面介绍的基于Java的电子商务开发技术串接起来,指导读者进行电子商务应用开发。
如何在JSP中实现分页显示?
分页显示是Web数据库应用中经常需要遇到的问题,当用户的数据库查询结果远远超过了计算机屏幕的显示能力的时候,我们该如何合理的将数据呈现给用户呢?答案就是数据库分页显示,可以完美的解决上述问题。下面是一个数据库分页操作的通用实例,对任何数据库平台上的分页功能都有很好的借鉴意义。
<%@ page contentType="text/html;charset=8859_1" %>
<%
//变量声明
Java.sql.Connection sqlCon; //数据库连接对象
Java.sql.Statement sqlStmt; //SQL语句对象
Java.sql.ResultSet sqlRst; //结果集对象
Java.lang.String strCon; //数据库连接字符串
Java.lang.String strSQL; //SQL语句
int intPageSize; //一页显示的记录数
int intRowCount; //记录总数
int intPageCount; //总页数
int intPage; //待显示页码
Java.lang.String strPage;
int i;
//设置一页显示的记录数
intPageSize = 2;
//取得待显示页码
strPage = request.getParameter("page");
if(strPage==null){//表明在QueryString中没有page这一个参数,此时显示第一页数据
intPage = 1;
}
else{//将字符串转换成整型
intPage = Java.lang.Integer.parseInt(strPage);
if(intPage<1) intPage = 1;
}
//装载JDBC驱动程序
Java.sql.DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
//设置数据库连接字符串
strCon = "jdbc:oracle:thin:@linux:1521:ora4cweb";
//连接数据库
sqlCon = Java.sql.DriverManager.getConnection(strCon,"hzq","hzq");
//创建一个可以滚动的只读的SQL语句对象
sqlStmt = sqlCon.createStatement(Java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,Java.sql.ResultSet.CONCUR_READ_ONLY);
//准备SQL语句
strSQL = "select name,age from test";
//执行SQL语句并获取结果集
sqlRst = sqlStmt.executeQuery(strSQL);
//获取记录总数
sqlRst.last();
intRowCount = sqlRst.getRow();
//记算总页数
intPageCount = (intRowCount+intPageSize-1) / intPageSize;
//调整待显示的页码
if(intPage>intPageCount) intPage = intPageCount;
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>JSP数据库操作例程 - 数据分页显示 - JDBC 2.0 - Oracle</title>
</head>
<body>
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<th>姓名</th>
<th>年龄</th>
</tr>
<%
if(intPageCount>0){
//将记录指针定位到待显示页的第一条记录上
sqlRst.absolute((intPage-1) * intPageSize + 1);
//显示数据
i = 0;
while(i<intPageSize && !sqlRst.isAfterLast()){
%>
<tr>
<td><%=sqlRst.getString(1)%></td>
<td><%=sqlRst.getString(2)%></td>
</tr>
<%
sqlRst.next();
i++;
}
}
%>
</table>
第<%=intPage%>页 共<%=intPageCount%>页
<%if(intPage<intPageCount){%><a href="jdbc20-oracle.jsp?page=<%=intPage+1%>">下一页
</a><%}%> <%if(intPage>1){%><a href="jdbc20-oracle.jsp?page=<%=intPage-1%>">上一页</a><%}%>
</body>
</html>
<%
//关闭结果集
sqlRst.close();
//关闭SQL语句对象
sqlStmt.close();
//关闭数据库
sqlCon.close();
%>
全面解析JDBC
2002-07-20· ·包路跃··Yesky
上一页 1 2 3 4 5 6 7 8
附录:JDBC TM技术解析
1. JDBCTM的定义
JDBCTM 是一种用于执行 SQL 语句的 JavaTM API,它由一组用 Java 编程语言编写的类和接口组成。JDBC 为工具/数据库开发人员提供了一个标准的API,使他们能够用纯 Java API 来编写数据库应用程序。
有了 JDBC,向各种关系数据库发送 SQL 语句就是一件很容易的事。换言之,有了 JDBC API,就不必为访问 Sybase 数据库专门写一个程序,为访问 Oracle 数据库又专门写一个程序,为访问 Informix 数据库又写另一个程序,等等。您只需用 JDBC API 写一个程序就够了它可向相应数据库发送 SQL 语句。而且,使用 Java 编程语言编写的应用程序,就无须去忧虑要为不同的平台编写不同的应用程序。将Java 和 JDBC 结合起来将使程序员只须写一遍程序就可让它在任何平台上运行。
Java 具有坚固、安全、易于使用、易于理解和可从网络上自动下载等特性,是编写数据库应用程序的杰出语言。所需要的只是 Java应用程序与各种不同数据库之间进行对话的方法。而 JDBC 正是作为此种用途的机制。
JDBC 扩展了 Java 的功能。例如,用 Java 和 JDBC API 可以发布含有 applet 的网页,而该 applet 使用的信息可能来自远程数据库企业也可以用 JDBC 通过 Intranet 将所有职员连到一个或多个内部数据库中(即使这些职员所用的计算机有 Windows、 Macintosh 和UNIX 等各种不同的操作系统)。随着越来越多的程序员开始使用Java 编程语言,对从 Java 中便捷地访问数据库的要求也在日益增加。
MIS 管理员们都喜欢 Java 和 JDBC 的结合,因为它使信息传播变得容易和经济。企业可继续使用它们安装好的数据库,并能便捷地存取信息,即使这些信息是储存在不同数据库管理系统上。新程序的开发期很短。安装和版本控制将大为简化。程序员可只编写一遍应用程序或只更新一次,然后将它放到服务器上,随后任何人就都可得到最新版本的应用程序。对于商务上的销售信息服务, Java 和JDBC 可为外部客户提供获取信息更新的更好方法。
2. JDBC 的用途
简单地说,JDBC 可做三件事:与数据库建立连接、发送 SQL 语句并处理结果。下列代码段给出了以上三步的基本示例:
Connection con = DriverManager.getConnection("jdbc:odbc:wombat","login",
"password");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next()) {
int x = rs.getInt("a");
String s = rs.getString("b");
float f = rs.getFloat("c");
}
上述代码对基于JDBC的数据库访问做了经典的总结,当然,在本小节的后续部分会对它做详尽的分析讲解。
3. JDBC API
JDBC 是个"低级"接口,也就是说,它用于直接调用 SQL 命令。在这方面它的功能极佳,并比其它的数据库连接 API 易于使用,但它同时也被设计为一种基础接口,在它之上可以建立高级接口和工具。高级接口是"对用户友好的"接口,它使用的是一种更易理解和更为方便的 API,这种API在幕后被转换为诸如 JDBC 这样的低级接口。
在关系数据库的"对象/关系"映射中,表中的每行对应于类的一个实例,而每列的值对应于该实例的一个属性。于是,程序员可直接对 Java 对象进行操作;存取数据所需的 SQL 调用将在"掩盖下"自动生成。此外还可提供更复杂的映射,例如将多个表中的行结合进一个 Java 类中。
随着人们对 JDBC 的兴趣日益增涨,越来越多的开发人员一直在使用基于 JDBC 的工具,以使程序的编写更加容易。程序员也一直在编写力图使最终用户对数据库的访问变得更为简单的应用程序。例如应用程序可提供一个选择数据库任务的菜单。任务被选定后,应用程序将给出提示及空白供填写执行选定任务所需的信息。所需信息输入应用程序将自动调用所需的 SQL 命令。在这样一种程序的协助下,即使用户根本不懂 SQL 的语法,也可以执行数据库任务。
4. JDBC与ODBC和其它API的比较
目前,Microsoft 的 ODBC API 可能是使用最广的、用于访问关系数据库的编程接口。它能在几乎所有平台上连接几乎所有的数据库。为什么 Java 不使用 ODBC?对这个问题的回答是:Java 可以使用 ODBC,但最好是在 JDBC 的帮助下以 JDBC-ODBC 桥的形式使用,这一点我们稍后再说。现在的问题已变成:"为什么需要 JDBC"?答案是显然的:ODBC 不适合直接在 Java 中使用,因为它使用 C 语言接口。从Java 调用本地 C 代码在安全性、实现、坚固性和程序的自动移植性方面都有许多缺点。从 ODBC C API 到 Java API 的字面翻译是不可取的。例如,Java 没有指针,而 ODBC 却对指针用得很广泛(包括很容易出错的指针"void *")。您可以将 JDBC 想象成被转换为面向对象接口的 ODBC,而面向对象的接口对 Java 程序员来说较易于接收。
ODBC 很难学。它把简单和高级功能混在一起,而且即使对于简单的查询,其选项也极为复杂。相反,JDBC 尽量保证简单功能的简便性,而同时在必要时允许使用高级功能。启用"纯 Java "机制需要象 JDBC 这样的 Java API。如果使用ODBC,就必须手动地将 ODBC 驱动程序管理器和驱动程序安装在每台客户机上。如果完全用 Java 编写 JDBC 驱动程序则 JDBC 代码在所有 Java 平台上(从网络计算机到大型机)都可以自 动安装、移植并保证安全性。
总之,JDBC API 对于基本的 SQL 抽象和概念是一种自然的 Java 接口。它建立在 ODBC 上而不是从零开始。因此,熟悉 ODBC 的程序员将发现 JDBC 很容易使用。JDBC 保留了 ODBC 的基本设计特征;事实上,两种接口都基于 X/Open SQL CLI(调用级接口)。它们之间最大的区别在于:JDBC 以 Java 风格与优点为基础并进行优化,因此更加易于使用。
目前,Microsoft 又引进了 ODBC 之外的新 API: RDO、 ADO 和OLE DB。这些设计在许多方面与 JDBC 是相同的,即它们都是面向对象的数据库接口且基于可在 ODBC 上实现的类。但在这些接口中,我们未看见有特别的功能使我们要转而选择它们来替代 ODBC,尤其是在 ODBC 驱动程序已建立起较为完善的市场的情况下。它们最多也就是在 ODBC 上加了一种装饰而已。
5. JDBC对B/S和C/S模式的支持
JDBC API 既支持数据库访问的两层模型(C/S),同时也支持三层模型(B/S)。在两层模型中,Java applet或应用程序将直接与数据库进行对话。这将需要一个JDBC驱动程序来与所访问的特定数据库管理系统进行 通讯。用户的SQL语句被送往数据库中,而其结果将被送回给用户。数据库可以位于另一台计算机上,用户通过网络连接到上面。这就叫做客户机/服务器配置,其中用户的计算机为客户机,提供数据库的计算机为服务器。网络可以是 Intranet(它可将公司职员连接起来),也可以是 Internet。
在三层模型中,命令先是被发送到服务的"中间层",然后由它将SQL 语句发送给数据库。数据库对 SQL 语句进行处理并将结果送回到中间层,中间层再将结果送回给用户。MIS 主管们都发现三层模型很吸引人,因为可用中间层来控制对公司数据的访问和可作的的更新的种类。中间层的另一个好处是,用户可以利用易于使用的高级API,而中间层将把它转换为相应的低级调用。最后,许多情况下三层结构可提供一些性能上的好处。
到目前为止,中间层通常都用 C 或 C++ 这类语言来编写,这些语言执行速度较快。然而,随着最优化编译器(它把 Java 字节代码转换为高效的特定于机器的代码)的引入,用 Java 来实现中间层将变得越来越实际。这将是一个很大的进步,它使人们可以充分利用 Java 的诸多优点(如坚固、多线程和安全等特征)。JDBC 对于从Java的中间层来访问数据库非常重要。
6. SQL 的一致性
结构化查询语言 (SQL) 是访问关系数据库的标准语言。困难之处在于:虽然大多数的 DBMS (数据库管理系统)对其基本功能都使用了标准形式的 SQL,但它们却不符合最近为更高级的功能定义的标准 SQL 语法或语义。例如,并非所有的数据库都支持储存程序或外部连接,那些支持这一功能的数据库又相互不一致。人们希望 SQL 中真正标准的那部份能够进行扩展以包括越来越多的功能。但同时 JDBC API 又必须支持现有的 SQL。
JDBC API 解决这个问题的一种方法是允许将任何查询字符串一直传到所涉及的 DBMS 驱动程序上。这意味着应用程序可以使用任意多的 SQL 功能,但它必须冒这样的风险:有可能在某些 DBMS 上出错。事实上,应用程序查询甚至不一定要是 SQL,或者说它可以是个为特定的 DBMS 设计的 SQL 的专用派生物(例如,文档或图象查询)。
JDBC 处理 SQL 一致性问题的第二种方法是提供 ODBC 风格的转义子句,这将在后续部分中讨论。转义语法为几个常见的 SQL 分歧提供了一种标准的 JDBC 语法。例如,对日期文字和已储存过程的调用都有转义语法。
对于
JSP数据库编程指南
这本书主要讲述基于oracle的jsp编码查询实现。有目录清晰字体哦。
dos实例应用演示手册
一份讲述dos命令用法实例的chm文档。
高手之路,dos起步 chm格式
dos的由入门到精通。chm格式字体清晰。