首页 文章 精选 留言 我的

精选列表

搜索[学习],共10003篇文章
优秀的个人博客,低调大师

Flume学习笔记

Flume [fluːm] (引水槽、运河) 王洪亮 2021/05/07 15:05 1. 简介 大数据技术解决的三个问题,海量数据的传输、存储和计算。Flume属于传输框架。专门传输日志的,多媒体不行。 2.安装 官网 http://flume.apache.org/ 下载apache-flume-1.9.0-bin.tar.gz,下载后解压即可,类似tomcat中间件,需要改配置文件 , 把apache-flume-1.9.0-bin/conf/flume-env.sh.template改成flume-env.sh,里面配置jdk地址,安装完毕。 export JAVA_HOME=D:\sde\Java\jdk1.8.0_131 3.Hello Flume样例 flume是按任务启动的,这个任务在flume这里叫agent,每个agent分为三块,source(对接数据来源)、channel(中间缓冲区)、sink(数据去向)。任务过程简述就是从一个地方采集数据后送到其他地方。 此次案例source数据采集自端口,通过channel再经过sink将数据输出到终端屏幕上。 开始编写Hello Flume样例(win环境) 编写配置文件,参考官网例子 习惯上把任务的配置文件和conf区分开,这里新建jobs目录下新建netcat-flume-logger.conf,命名格式最好区分出source和sink的类型 #完整的conf分几块,变量声明区、source区、interceptor区、channelSelector区、channel区、sink区、关系绑定区 #变量声明区(必须) a1指的是agent的变量名,启动时指定 #分别声明 sources、channels、sinks、sinkgroups等 a1.sources = r1 a1.channels = c1 a1.sinks = k1 #source区(必须) 指定source类型 具体类型需要看官网文档source 部分 a1.sources.r1.type = netcat a1.sources.r1.bind = localhost a1.sources.r1.port = 44444 #interceptor区(可选),代码自写,配合multiplexing channelSelector使用 #channelSelector区(可选),不写默认是replicating,把数据发给每个sink a1.sources.r1.selector.type=replicating #channel区(必须) 指定channel类型 具体类型需要看官网文档channel部分 a1.channels.c1.type = memory #sink处理器区,声明sink组,选择处理器是故障转移还是负载均衡,不写就是默认 #sink区(必须) 指定sink类型 具体类型需要看官网文档sink部分 a1.sinks.k1.type = logger #关系绑定区(必须) a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1 启动flume的agent #win环境启动命令 进入到bin目录 cmd flume-ng agent --conf ../conf --conf-file ../jobs/netcat-flume-logger.conf --name a1 -property flume.root.logger=INFO,console #简写 flume-ng agent -c ../conf -f ../jobs/netcat-flume-logger.conf -n a1 -property flume.root.logger=INFO,console #linux环境启动命令 那个logger不一样 #-Dflume.root.logger=INFO,console 启动结果显示端口已监听 [INFO - org.apache.flume.source.NetcatSource.start(NetcatSource.java:166)] Created serverSocket:sun.nio.ch.ServerSocketChannelImpl[/127.0.0.1:44444] 通过netcat工具向端口发送数据 没有netcat telnet 也可以 nc localhost 44444 > Hello Flume OK 查看flume的日志输出 [INFO - org.apache.flume.sink.LoggerSink.process(LoggerSink.java:95)] Event: { headers:{} body: 48 65 6C 6C 6F 20 46 6C 75 6D 65 Hello Flume } 4.Source种类 拉出几个常用的。其他的查看官方文档 1.Avro Source Flume集群使用,多个Fulme连接需要使用Avro的source和sink连接,自身相当于服务端,需要优先启动 #相关source区 写法 a1.sources.r1.type=avro a1.sources.r1.bind=0.0.0.0 a1.sources.r1.port=4141 2. Exec Source 用命令监控某个文件的变化,将变化的内容传送走,适用于监控一个实时变化的日志文件,缺点是不能断点续传,容易数据丢失或是数据重复 #相关source区 写法 a1.sources.r1.type=exec #后跟 监控文件的命令 a1.sources.r1.command=tail -F /var/log/secure 3. Spooling Directory Source 监控本地文件夹,文件夹中新增文件时,会将整个文件内容取走,并加后缀做标记(.COMPLETED),表示已经取过了,标记后的文件不在处理,内容变化也不管。适用于批量上传,缺点是不能适应动态变化的文件 #相关source区 写法 a1.sources.r1.type=spooldir #后跟监控文件的目录 a1.sources.r1.spoolDir=/var/log/apache/flumeSpool 4. Taildir Source 可以监控不同文件夹下的不同文件。支持断点续传 #相关source区 写法 a1.sources.r1.type = TAILDIR #指定保存断点续传的文件 a1.sources.r1.positionFile = /var/log/flume/position.json #指定文件组 可以多个 a1.sources.r1.filegroups = f1 f2 #指定 单个文件 a1.sources.r1.filegroups.f1 = /var/log/test1/example.log #指定多个文件 * 不能出现在第一位 a1.sources.r1.filegroups.f2 = /var/log/test2/.*log.* 5. NetCat TCP Source 监听TCP端口用的,还有个UDP Source 就type不一样 #相关source区 写法 udp 的type是netcatudp a1.sources.r1.type=netcat a1.sources.r1.bind=0.0.0.0 a1.sources.r1.port=6666 5.Channel种类 常用的Memory Channel和File Channel 1. Memory Channel 将数据缓存在内存中,快,闪断丢数据 #channel区 a1.channels.c1.type=memory 2. File Channel 将数据缓存在本地文件中,慢点,稳定 #channel区 a1.channels.c1.type=file #数据存放的目录,可以有多个目录,逗号分割 a1.channels.c1.dataDirs=/mnt/flume/data 6.Sink种类 常用的拉出 1. Avro Sink Flume集群收尾连接,相对source 而言这个算客户端,去绑定服务端IP和端口 #sink 区 a1.sinks.k1.type = avro a1.sinks.k1.hostname = 10.10.10.10 a1.sinks.k1.port = 4545 2. Logger Sink 日志打印在终端屏幕上,需要agent启动的时候搭配对应命令 问题:中文没打出来;maxBytesToLog这玩意不好使 #sink区 #-property flume.root.logger=INFO,console #-Dflume.root.logger=INFO,console a1.sinks.k1.type=logger 3. File Roll Sink 日志输出到本地文件,问题是就算没有接收到数据,也会不停的生成新的空文件 #sink区 a1.sinks.k2.type = file_roll #指定生成文件夹路径,文件名会自动生成 a1.sinks.k2.sink.directory = ../data/ #指定新文件生成频率,30s a1.sinks.k2.sink.rollInterval = 30 7.Channel Selector 这个就俩,算自定义的三个 1. Replicating Channel Selector (default) 默认的,可以不写,把数据发给所有sink #channel selector 区 a1.sources.r1.selector.type=replicating 2. Multiplexing Channel Selector 根据拦截器规则,选择发送到哪个sink #channel selector 区 a1.sources.r1.selector.type = multiplexing #这个关键变量,拦截器里写的,写什么是什么,不一定是state a1.sources.r1.selector.header = state #根据这个state的值选择sink,如果header中的state=CZ就发个c1 a1.sources.r1.selector.mapping.CZ = c1 # 等于US就给c2 c3 a1.sources.r1.selector.mapping.US = c2 c3 8.Sink Processor 目前算默认的三种,默认的数据给谁,谁就发走 1. Failover Sink Processor 故障转移,根据优先级,可着最高优先级的用,挂了再用优先级低的 #sink处理器区 #这个算声明,可以拿到声明区 a1.sinkgroups = g1 a1.sinkgroups.g1.sinks = k1 k2 #选择处理器类型为 故障转移 a1.sinkgroups.g1.processor.type = failover #指定sink组成员优先级 a1.sinkgroups.g1.processor.priority.k1 = 5 #最高等级k2一直使用,直到挂了为止,才能轮到k1 a1.sinkgroups.g1.processor.priority.k2 = 10 2. Load balancing Sink Processor 负载均衡,可选随机或是均衡发送 #sink处理器区 #这个算声明,可以拿到声明区 a1.sinkgroups = g1 a1.sinkgroups.g1.sinks = k1 k2 #选择处理器类型为 负载均衡 a1.sinkgroups.g1.processor.type = load_balance #指定模式为随机发送,还可以选round_robin均衡发送 a1.sinkgroups.g1.processor.selector = random 9.自定义Inteceptor idea新建maven项目开整 \> hello 1. 引入依赖 <dependency> <groupId>org.apache.flume</groupId> <artifactId>flume-ng-core</artifactId> <version>1.9.0</version> </dependency> 2. 写自己的拦截器 package com.flume; import org.apache.flume.Context; import org.apache.flume.Event; import org.apache.flume.interceptor.Interceptor; import java.util.HashMap; import java.util.List; import java.util.Map; public class MyInterceptor implements Interceptor { @Override public void initialize() { System.out.println("---------initialize---------"); } @Override public Event intercept(Event event) { String body = new String(event.getBody()); Map<String, String> map = new HashMap<>(); if(body.contains("hello")){ map.put("myStatus","up"); event.setHeaders(map); }else{ map.put("myStatus","down"); event.setHeaders(map); } return event; } @Override public List<Event> intercept(List<Event> list) { return null; } @Override public void close() {} public static class MyBuilder implements Interceptor.Builder{ @Override public Interceptor build() { return new MyInterceptor(); } @Override public void configure(Context context) {} } } 3. 项目打个jar包放到Flume的lib目录下 4. 编写Flume配置文件 netcat-flume-doubleLogger.conf,本来想两个sink都发到logger的,后来发现终端上分不出哪个是哪个,把其中一个sink改到落到本地文件了 #变量区 a1.sources = r1 a1.channels = c1 c2 a1.sinks = k1 k2 #source区 a1.sources.r1.type = netcat a1.sources.r1.bind = localhost a1.sources.r1.port = 44444 #intercetor区 a1.sources.r1.interceptors = i1 a1.sources.r1.interceptors.i1.type = com.flume.MyInterceptor$MyBuilder #channel selector 区 a1.sources.r1.selector.type = multiplexing #我代码里定义的是 myStatus a1.sources.r1.selector.header = myStatus #myStatus=up就发个c1 a1.sources.r1.selector.mapping.up = c1 # 等于down就给c2 a1.sources.r1.selector.mapping.down = c2 #channel区 a1.channels.c1.type = memory a1.channels.c2.type = memory #sink区 a1.sinks.k1.type = logger a1.sinks.k2.type = file_roll a1.sinks.k2.sink.directory = ../data/ #绑定区 a1.sources.r1.channels = c1 c2 a1.sinks.k1.channel = c1 a1.sinks.k2.channel = c2 5. 启动 flume-ng agent --conf ../conf --conf-file ../jobs/netcat-flume-doubleLogger.conf --name a1 -property flume.root.logger=INFO,console 6. 测试效果 启动netcat发送命令 > nc localhost 44444 6351 OK hello OK 一个在终端屏幕上有显示,一个在本地文件中有显示。 10自定义Source 1. 依赖 <dependency> <groupId>org.apache.flume</groupId> <artifactId>flume-ng-core</artifactId> <version>1.9.0</version> </dependency> 2. 代码 package com.flume; import org.apache.flume.Context; import org.apache.flume.Event; import org.apache.flume.PollableSource; import org.apache.flume.conf.Configurable; import org.apache.flume.event.SimpleEvent; import org.apache.flume.source.AbstractSource; public class MySource extends AbstractSource implements Configurable, PollableSource { private String aaa; private String bbb; /** * 定义配置文件中的变量 * @param context */ @Override public void configure(Context context) { aaa = context.getString("aaa"); //没取到值 就给默认值 bbb = context.getString("bbb", "GangZi"); } @Override public Status process(){ Status status = null; try { //创建个事件 Event e = new SimpleEvent(); String content = aaa+"->"+bbb+": "+Math.random(); e.setBody(content.getBytes("utf-8")); //把event传给channel getChannelProcessor().processEvent(e); status = Status.READY; } catch (Throwable t) { status = Status.BACKOFF; if (t instanceof Error) { throw (Error)t; } } try { //睡两秒 要不刷的太快了 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return status; } @Override public long getBackOffSleepIncrement() { return 0; } @Override public long getMaxBackOffSleepInterval() { return 0; } } 3. 写配置文件custom-flume-logger.conf #变量区 a1.sources = r1 a1.channels = c1 a1.sinks = k1 #source区 a1.sources.r1.type = com.flume.MySource a1.sources.r1.aaa = LiLei #a1.sources.r1.bbb = HanMeiMei #channel区 a1.channels.c1.type = memory #sink区 a1.sinks.k1.type = logger a1.sinks.k1.maxBytesToLog = 18 #绑定区 a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1 4. 启动命令 flume-ng agent --conf ../conf --conf-file ../jobs/custom-flume-logger.conf --name a1 -property flume.root.logger=INFO,console 5. 查看效果 [INFO - org.apache.flume.sink.LoggerSink.process(LoggerSink.java:95)] Event: { headers:{} body: 4C 69 4C 65 69 2D 3E 47 61 6E 67 5A 69 3A 20 30 LiLei->GangZi: 0 } 11自定义Sink 1. 依赖 <dependency> <groupId>org.apache.flume</groupId> <artifactId>flume-ng-core</artifactId> <version>1.9.0</version> </dependency> 2. 代码 package com.flume; import org.apache.flume.*; import org.apache.flume.conf.Configurable; import org.apache.flume.sink.AbstractSink; public class MySink extends AbstractSink implements Configurable { private String ccc; private String ddd; @Override public void configure(Context context) { ccc = context.getString("ccc"); ddd = context.getString("ddd","xxxxxxxx"); } @Override public Status process() throws EventDeliveryException { Status status = null; Channel ch = getChannel(); Transaction txn = ch.getTransaction(); txn.begin(); try { Event event = ch.take(); if(event == null){ txn.rollback(); status = Status.BACKOFF; }else { byte[] body = event.getBody(); String content = new String(body); System.out.println("ccc="+ccc); System.out.println("content="+content); System.out.println("ddd="+ddd); txn.commit(); status = Status.READY; } } catch (Exception e) { e.printStackTrace(); txn.rollback(); status = Status.BACKOFF; }finally { txn.close(); } return status; } } 3. flume配置文件netcat-flume-custom.conf #变量区 a1.sources = r1 a1.channels = c1 a1.sinks = k1 #source区 a1.sources.r1.type = netcat a1.sources.r1.bind = localhost a1.sources.r1.port = 44444 #channel区 a1.channels.c1.type = memory #sink区 a1.sinks.k1.type = com.flume.MySink a1.sinks.k1.ccc =--hello-- a1.sinks.k1.ddd =--moto-- #绑定区 a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1 4. 启动agent flume-ng agent --conf ../conf --conf-file ../jobs/netcat-flume-custom.conf --name a1 -property flume.root.logger=INFO,console 5. 客户端发送命令 telnet localhost 44444 > 1 OK 6. flume终端打印 ccc=--hello-- content=1 ddd=--moto-- 12.Flume监控工具 下面的实验,windows环境下怎么跟多个参数 不知道 1.Http监控,json形式文本 使用这种监控方式,只需要在启动flume的时候在启动参数上面加上监控配置,例如这样: bin/flume-ng agent --conf conf --conf-file conf/flume_conf.properties --name collect -Dflume.monitoring.type=http -Dflume.monitoring.port=1234 其中-Dflume.monitoring.type=http表示使用http方式来监控,后面的-Dflume.monitoring.port=1234表示我们需要启动的监控服务的端口号为1234,这个端口号可以自己随意配置。然后启动flume之后,通过http://ip:1234/metrics就可以得到flume的一个json格式的监控数据。 2.ganglia监控,图形化界面 这种监控方式需要先安装ganglia然后启动ganglia,然后再启动flume的时候加上监控配置,例如: bin/flume-ng agent --conf conf --conf-file conf/producer.properties --name collect -Dflume.monitoring.type=ganglia -Dflume.monitoring.hosts=ip:port 其中-Dflume.monitoring.type=ganglia表示使用ganglia的方式来监控,而-Dflume.monitoring.hosts=ip:port表示ganglia安装的ip和启动的端口号。 flume监控还可以使用zabbix,但是这种方式需要在flume源码中添加监控模块,相对比较麻烦,由于不是flume自带的监控方式,这里不讨论这种方式。 因此,flume自带的监控方式其实就是http、ganglia两种,http监控只能通过一个http地址访问得到一个json格式的监控数据,而ganglia监控是拿到这个数据后用界面的方式展示出来了,相对比较直观。

优秀的个人博客,低调大师

HTML 学习笔记

基本框架 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>标题</title> </head> <body> </body> </html> 可打开 .html 文件,直接输入 html:5 调出 语句 一些规范: 标签使用小写,元素必须闭合 空元素要加斜杠以闭合 eg. <br /> 不使用语义化,所有样式都存放于 CSS 中,内容与样式分离 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>标题</title> </head> <body> <h1>一级标题</h1> <h2>二级标题</h2> <p>段落</p> <!--换行符--> <br /> <!--分割线--> <hr /> <!--列表,可嵌套--> <!--有序列表--> <ol> <li>第一项</li> <li>第二项</li> </ol> <!--无序列表--> <ul> <li>第一项</li> <li>第二项</li> </ul> <!--链接--> <a href="https://www.google.com/">链接显示的文本</a> <!--链接到页面特定位置,使用 ID 特性--> <a href="#top">回到顶部</a> <p id="top">顶部</p> <!--链接到其他页面的特定位置--> <a href="http://wiki-power.com/#top">跳转到站外页面的某个位置</a> <!--图像--> <img src="/xx.png" alt="无法加载时的文字说明" /> <!--表格--> <table> <!--第一行--> <tr> <!--第一列--> <th></th> <!--第二列--> <th scope="col">周六</th> <!--第三列--> <th scope="col">周日</th> </tr> <!--第二行--> <tr> <th scope="row">数量</th> <td>120</td> <td>135</td> </tr> <!--第三行--> <tr> <th scope="row">收益</th> <!--跨列 colspan,跨行 rowspan--> <td colspan="2">500</td> </tr> </table> <!--表单,待补充--> <!--iframe,待补充--> <!--flash/视频/音频,待补充--> </body> </html> 参考与致谢 HTML 教程 | 菜鸟教程 HTML 30 分钟入门教程 HTML - head 头部浅析 文章作者:Power Lin 原文地址:https://wiki-power.com 版权声明:文章采用 CC BY-NC-SA 4.0 协议,转载请注明出处。

优秀的个人博客,低调大师

Java 学习杂记

Java 杂记 mybatis 的查询 mybatis 查询没有数据的时候,会返回什么? 返回类是基本数据类型的包装类型和对象,返回为空 null 返回List或Map时,返回结果时是为空的集合 返回结果是基本数据类型时,没有数据时会抛出异常 Guava 强大的集合工具Lists Guava的Lists类中提供了许多实用的方法和静态函数,可以帮助我们优雅的编码。 集合分区方法 - partition() 集合转换方法 - transform() 获取笛卡尔积方法 - cartesianProduct() Lists.newLinkedList() Lists.newArrayList();参考文档:Guava - 强大的集合工具Lists maven相关 maven 依赖问题 项目使用maven管理jar包,很容易因为各种原因(网速慢、断网)导致jar包下载不下来,出现很多.lastUpdated文件。这些不完全下载的包,会导致maven不会去远程下载,需要到仓库的目录下去清除。 maven项目pom.xml中scope类型 scope的分类 compile:默认值 他表示被依赖项目需要参与当前项目的编译,还有后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去 test:依赖项目仅仅参与测试相关的工作,包括测试代码的编译和执行,不会被打包,例如:junit runtime:表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过了编译而已。例如JDBC驱动,适用运行和测试阶段 provided:打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是打包阶段做了exclude操作 system:从参与度来说,和provided相同,不过被依赖项不会从maven仓库下载,而是从本地文件系统拿。需要添加systemPath的属性来定义路径 maven 仓库 repository 参考文档仓库 repository

优秀的个人博客,低调大师

JDBC学习:事务

什么是事务 数据库中一些操作的集合是一个独立的单元,事务就是构成单一逻辑工作单位的集合。 为什么需要事务 事务是为解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问。比如:银行转帐业务,账户A给账户B转帐100元,需要账户A余额减100元,账户B余额加100元,两个需要同时发生。完成这种操作需要保证要么全部成功,要么全部失败。 什么是回滚 未能成功完成的事务成为中止事务,对中止事务造成的变更需要进行撤销处理,称为事务回滚。 事务的特性(ACID 原则) 原子性(atomicity):对事务中的全部操作是不可分割的,要么全部完成,要么都不执行。 一致性(consistency):事务执行之前和执行之后,数据库都必须处于一致性状态。 隔离性(isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。 持久性(durability):对于任意已提交的事务,系统必须保证该对数据库的改变不丢失,即使数据库出现故障。 Java JDBC 事务机制比如有个业务:当我们修改一个信息后再去查询这个信息。这是一个简单的业务,实现起来也非常容易,但是当这个业务放在多线程高并发的平台下,问题自然就出现了。比如当执行了一个修改后,在查询之前有一个线程也执行了修改语句,这时再执行查询,看到的信息就有可能和我们修改的不同。为了解决这一问题,就引入了引入JDBC事务机制。 如何操作 把事务操作设置为不自动提交,通过手动提交就能实现事务的处理。 搭建实验环境实验,在当前数据库中创建一个测试表: CREATE TABLE tb ( id INT UNSIGNED NOT NULL AUTO_INCREMENT KEY COMMENT '编号', name VARCHAR(20) NOT NULL COMMENT '姓名', sex VARCHAR(4) NOT NULL COMMENT '性别', phone VARCHAR(11) NOT NULL COMMENT '手机号码' ); 插入几条测试数据: INSERT INTO tb (name, sex, phone) VALUES ("张三", "男", "139****2234"), ("李四", "女", "130****3239"), ("王二", "男", "136****1234"), ("小王", "女", "137****1735"), ("赵云", "男", "131****1255"), ("关羽", "男", "139****1930"); 实验代码 相关延伸 事务并发处理可能引起的问题 脏读(dirty read):一个事务读取了另一个事务尚未提交的数据。 不可重复读(non-repeatable read):一个事务的操作导致另一个事务前后两次读取到不同的数据。 幻读(phantom read):一个事务的操作导致另一个事务前后两次查询到的结果数据量不同。 举例: 事务A、B并发执行,当A事务update后,B事务select读取到A尚未提交的数据,此时A事务rollback,则B读取到的数据是无效的“脏”数据。 当B事务select读取数据后,A事务update操作更改B事务select到的数据,此时B事务再次读取该数据,发现前后两次的数据不一样。 当B事务select读取数据后,A事务insert或delete了一条满足A事务的select条件的记录,此时B事务再次select,发现查询到前不存在的数据(“幻影”),或者前面的某个记录不见了。 JDBC的事务支持 JDBC对事务的支持体现在三个方面: 1.自动提交模式(Auto-commit mode) Connection提供了一个auto-commit的属性来指定事务何时结束。 a.当auto-commit为true时,当每个独立的SQL操作执行完毕,事务立即自动提交,也就是说每个SQL操作都是一个事务的。auto-commit默认为true。 一个独立SQL操作什么时候什么执行完毕呢?JDBC规范这样规定 对数据操作语言(DML如insert,update,delete)和数据定义语言(DDL如create,drop),语句一执行完就视为执行完毕。 对select语句,当与它关联的ResultSet对象关闭时,视为执行完毕。对存储过程或者其他返回多个结果的语句,当与它关联的所有ResultSet对象全部关闭,所有update count(update,delete等语句操作影响的行数)和output parameter(存储过程的输出参数)都已经获取之后,视为执行完毕。 b.当auto-commit为false时,每个事务都必须显式调用commit方法进行提交,或者显式调用commit方法进行回滚。 2.事务隔离级别(Transaction Isolation Levels) JDBC提供了5种不同的事务隔离级别。在Connection中进行了定义。 TRANSACTION_NONE:JDBC不支持事务 TRANSACTION_READ_UNCOMMITTED:允许脏读、不可重复读和幻读 TRANSACTION_READ_COMMITTED:禁止脏读,但允许不可重复读和幻读 TRANSACTION_REPEATABLE_READ:禁止脏读和不可重复读,单可以幻读 TRANSACTION_SERIALIZABLE:禁止脏读、不可重复读和幻读 3.保存点(SavePoint) JDBC定义了SavePoint接口,提供在一个更细粒度的事务控制机制。当设置了一个保存点后,可以rollback到该保存点处的状态,而不是rollback整个事务。 连接对象获取和关闭的时机 现状: 连接对象的获取和销毁比较浪费时间 一个事务中多个操作,若每个操作都生成一个连接对象,多用户同时连接数据库时,访问效率会非常的低。 需求: 一个事务中的多个操作应该用同一个连接对象控制,不然无法实现提交和回滚。一个事务开始时获得连接对象,一个事务结束时关闭连接。 解决: 将连接对象的申请交给专门的连接管理类 事务申请连接对象时,通过连接管理类申请,而不再通过DriverManager申请 一个事务一定是由一个线程完成的,使用线程局部变量获得同一个连接对象 接口DataSource 该工厂用于提供到此 DataSource 对象所表示的物理数据源的连接。 作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法。 DataSource接口由驱动程序供应商实现。共有三种类型的实现: 基本实现:生成标准的 Connection 对象 连接池实现:生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用。 分布式事务实现:生成一个 Connection 对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。 方法: getConnection():尝试建立与此 DataSource 对象所表示的数据源的连接。 getConnection(String username, String password):尝试建立与此 DataSource 对象所表示的数据源的连接。 实例:先在src目录下新建配置文件config.properties: driver=com.mysql.jdbc.Driver url=jdbc\:mysql\://127.0.0.1\:3306/empmgs?useUnicode\=true&characterEncoding\=utf-8 username=root password=root 实例代码: import java.io.FileInputStream; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; public class demo4 { static Properties prop = new Properties(); static DataSource ds = null; static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); private static Connection conn = null; private static Statement sm = null; /** * 静态初始化块加载注册驱动 */ static { try { prop.load(new FileInputStream("src/config.properties")); ds = BasicDataSourceFactory.createDataSource(prop); } catch (Exception e) { e.printStackTrace(); } } static public Connection getConnection(){ try { //先看线程局部变量 conn = threadLocal.get(); if(conn == null){//线程局部变量中没有保存连接对象 conn = ds.getConnection(); threadLocal.set(conn);//设置连接对象到线程局部变量 } } catch (SQLException e) { e.printStackTrace(); } return conn; } public static void main(String[] args) { try{ conn = getConnection (); sm = conn.createStatement(); // 关闭自动提交 conn.setAutoCommit(false); sm.executeUpdate("UPDATE tb SET name = '老王' WHERE id = 3 "); sm.executeUpdate("INSERT INTO tb (name, sex, phone) VALUES ('美丽','女','132****5555')"); conn.commit(); System.out.println("运行结束"); } catch (Exception e) { try { conn.rollback(); } catch (Exception ex) { e.printStackTrace(); } } finally { if (sm != null) { try { sm.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); conn = null; } catch (SQLException e) { e.printStackTrace(); } } } } }

优秀的个人博客,低调大师

Java学习:反射

反射 使用反射可以直接获取class字节码文件中的类型、属性、方法。 演示代码: 新建一个名为User的类作为反射的操作对象 public class User { private int id; private String name; private String password; public User() { } /** * @return the id */ public int getId() { return id; } /** * @return the name */ public String getName() { return name; } /** * @return the password */ public String getPassword() { return password; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @param password the password to set */ public void setPassword(String password) { this.password = password; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "User [id=" + id + ", name=" + name + ", password=" + password + "]"; } } 演示 类 获取类 Object u = new User(); Class class1 = u.getClass(); 获取类名 class1.getName() 获取类访问权限 int modifier = class1.getModifiers(); boolean flag = Modifier.isPublic(modifier); System.out.println("是public?: "+flag); 属性 获取类所有属性访问权限私有的也可以获取到 Field[] arr = class1.getDeclaredFields(); for (Field field:arr) { System.out.println ("类中的属性:" + field); } 获取类所有属性的值私有属性默认无法获取,但是可以通过不检查访问权限来直接获取。 // 获取所有属性的值 for (Field field:arr) { // 不检查访问权限 field.setAccessible(true); // 获取u对象中field的值 Object o = field.get(u); System.out.println("类中的属性值:" +o); } 指定属性名获取属性 Field f = class1.getDeclaredField("name"); f.setAccessible(true); f.set(u, "张三"); Object o = f.get(u); System.out.println("name: " + o); 方法 获取所有方法(包含从父类继承的方法) Method[] allMethods = class1.getMethods(); System.out.println("类的所有方法:"); for (Method method:allMethods) { System.out.println(method); } 获取类自己的方法 Method[] onlyMethods = class1.getDeclaredMethods(); for (Method method:onlyMethods) { System.out.println(method); } 调用无参带返回值方法 Method method2 = class1.getDeclaredMethod("getName"); String str = (String)(method2.invoke(u)); System.out.println ("返回值:"+ str); 调用有参无返回值方法 Method method = class1.getDeclaredMethod("setName", String.class); method.invoke(u, "李四"); 完整演示代码: import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class ReflectTest { public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, InvocationTargetException { Object u = new User(); // 获取到User的类 Class class1 = u.getClass(); System.out.println("类名:"+class1.getName()); // 获取类访问权限 int modifier = class1.getModifiers(); boolean flag = Modifier.isPublic(modifier); System.out.println("是public?: "+flag); // 获取所有属性 Field[] arr = class1.getDeclaredFields(); for (Field field:arr) { System.out.println ("类中的属性:" + field); } // 获取所有属性的值 for (Field field:arr) { // 不检查访问权限 field.setAccessible(true); // 获取u对象中field的值 Object o = field.get(u); System.out.println("类中的属性值:" +o); } // 指定字段名称获取属性 Field f = class1.getDeclaredField("name"); f.setAccessible(true); f.set(u, "张三"); Object o = f.get(u); System.out.println("name: " + o); // 获取所有方法 (包含继承方法) Method[] allMethods = class1.getMethods(); System.out.println("类的所有方法:"); for (Method method:allMethods) { System.out.println(method); } // 获取当前类的自己的方法 Method[] onlyMethods = class1.getDeclaredMethods(); for (Method method:onlyMethods) { System.out.println(method); } // 调用有参方法 Method method = class1.getDeclaredMethod("setName", String.class); method.invoke(u, "李四"); // 调用无参有返回值方法 Method method2 = class1.getDeclaredMethod("getName"); String str = (String)(method2.invoke(u)); System.out.println ("返回值:"+ str); } }

优秀的个人博客,低调大师

JavaScript学习(十)

目录 练习: String对象的方法 1.查找字符串 (1)charAt()方法 (2)indexOf()方法 (3)lastIndexOf()方法 2.截取字符串 (1)silce()方法 (2)substr()方法 (3)substring()方法 3.连接和拆分 (1)concat()方法 (2)split()方法 4.格式化字符串 练习: 在text文档中输入英文小写字母,点击按钮之后把文本框中的小写字母变成大写。 <head> <meta charset="utf-8"> <title>对象</title> <script type="text/javascript" language="JavaScript"> function c(){ var t=document.getElementById("text1"); t.value=t.value.toUpperCase(); } </script> </head> <body> <input type="text" id="text1"/> <button onclick="c()" type="button">big button</button> </body> String对象的方法 1.查找字符串 (1)charAt()方法 charAt()方法可以返回字符串中指定位置的字符。 语法:stringObject.charAt(index) stringObject:string对象名或字符变量名。 index:必选参数。表示字符串中某个位置的数字,即字符在字符串中的下标。 例子:var str="你好 JavaScript"; alert(str.charAt(1)); (2)indexOf()方法 indexOf()方法可以返回某个子字符串在字符串中首次出现的位置。 语法:stringobject.indexOf(substring.startindex) substring:必选参数。要在字符串中查找的子字符串 startindex:可选参数。用于指定在字符串中开始查找位置,取值范围是0—stringobject.length-1. 例子: <script type="text/javascript" language="JavaScript"> var str="四十四,四是四"; var position=0; var num=-1; var index=0; while(position!=-1){ position=str.indexOf("四",index); num+=1; index=position+1; } document.write("定义的字符串:"+str+"<br />"); document.write("字符串中有"+num+"个四"); </script> (3)lastIndexOf()方法 lastIndexOf()方法可以返回某个字符串在字符串中最后出现的位置。 语法:stringobject.lastIndexOf(substring.startindex) 2.截取字符串 (1)silce()方法 silce()方法可以提取字符串的片段,并在新的字符串中返回被提取部分。 语法:stringobject.silce(startindex,endindex) 例子: var str="你好 JavaScript"; console.log(str.slice(0,7)); (2)substr()方法 substr()方法可以从字符串指定位置提取指定长度的字符串。 语法:stringobject.substr(startindex,length) startindex:必选参数。指定要提取的字符串的位置。该参数可以是负数,如果是负数,则从该字符串的尾部开始算起。 length:可选参数。用于指定提取的字符串的长度。 例子:字符串截取 var str="你好 JavaScript"; document.write(str.substr(0,4)); (3)substring()方法 substring方法用于提取字符串中两个指定的索引号之间的字符。 语法:stringobject.substring(startindex,endindex) 3.连接和拆分 (1)concat()方法 concat()方法用于连接两个或多个字符串。 语法:stringobject.concat(string1,string2...) stringobject:string对象名或字符变量名 string:必选参数。将被连接的字符串,可以是一个,或者多个。 例子: var str1="affa"; var str2="dgaf0"; document.write(str1.concat(str2)); (2)split()方法 split()方法用于把一个字符串分割成字符串数组。 语法:stringobject.split(separator,limit) separator:必选参数。指定的分割符。该参数可以是字符串,也可以是正则表达式。如果把空字符串("")作为分割符,那么字符串的每个字符都会被分割。 limit:可选参数。该参数可指定返回数组的最大长度。如果设置了该参数,返回的数组元素个数都不会多于这个参数。 例子:在文本框中输入数字,生成这个位数的随机字符串。 <script type="text/javascript" language="JavaScript"> function ran(digit){ if(isNaN(digit)){ alert("请输入数字"); }else{ var source="0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G"; arrstr=source.split(","); /*分割方法:以逗号为分割符*/ var result=""; var index=0; for(i=0;i<digit;i++){ index=parseInt(Math.random()*arrstr.length); result=arrstr[index]+result; } alert(result); } } </script> <form name="form"> <input type="text" name="digit" /> <input type="button" value="生成" onclick="ran(form.digit.value)"/> </form> 4.格式化字符串 anchor() : 创建HTML锚 big() : 使用大号字体显示字符串 small() : 使用小号字体显示字符串 fontsize() : 使用指定的字体大小显示字符串 bold() : 使用粗体的字体显示字符串 italics() : 使用斜体显示字符串 link() : 将字符串显示为超链接 strike() : 使用删除线来显示字符串 blink() : 显示闪动字符串,此方法并不支持IE浏览器 fixed() : 以打字机文本显示字符串,相当于在字符串两端增加<tt>标记 fontcolor() : 使用指定的颜色来显示字符串 sub() : 把字符串显示为下标 sup() : 把字符串显示为上标

优秀的个人博客,低调大师

JavaScript学习(九)

对象访问语句 for...in循环语句 for...in循环语句和for循环语句十分相似,for...in语句用来遍历对象的每一个属性。每次都将属性名作为字符串保存在变量里。 语法:for(variable in object){ ...statement } variable是一个变量名,声明一个变量的var语句、数组的一个元素或者对象的一个属性; object是一个对象名,或者是计算结果为对象的表达式; statement通常是一个原始语句或者语句块,由它构成循环的主体。 例子1: <script type="text/javascript" language="JavaScript"> var objectes={uesr:"afa", age:"21", QQ:"15625462", email:"54849@123.com", pwd:"4as4fa4f"}; for(var example in objectes){ document.write("属性:"+example+"="+objectes[example]+"<br />") } </script> 例子2: var objectes=document; var object0=""; for(var example in objectes){ object0=example+"="+objectes[example]; document.write(object0+"<br />") } with语句 with语句被用于在访问一个对象的属性或方法时避免重复使用指定对象引用。 语法:with(object){ statements } object:指定在statement块中没有引用的情况下使用那个对象引用。 在一个连续的程序代码中,如果多次使用某个对象的多个属性或方法,那么只要在with关键字后的括号()中写出该对象的名称,就可以在随后的大括号{ }中的程序语句中直接引用该对象的属性名或方法名。 JavaScript中的数组 创建array对象 可以用静态array对象创建一个数组对象,已记录不同类型的数据。 语法:arrayObj=new Array() arrayObj=new Array([size]) arrayObj=new Array([element0[,element1[,...[elementN]]]]) arrayObj:必选项。要赋值为Array对象的变量名 size:可选项。设置数组的大小。由于数组的下标是从零开始,创建元素的下标为0-size-1. elementN:可选项。存入数组的元素。使用该语法时必须有一个以上的元素。 例子: <script type="text/javascript" language="JavaScript"> arrayobj=new Array(1,2,3,"a","b"); console.log(arrayobj); </script> Array对象的输入/输出 1.array对象的输入 向array对象中输入数组元素有三种方法。 (1)在定义array对象时直接输入数组元素 arrayobj=new Array("a","b","c") (2)利用array对象的元素下标向其输入数组元素 arrayobj=new Array(7) arrayobj[3]="a"; arrayobj[4]="b"; (3)利用for语句向array对象中输入数组元素 var n=7; arrayobj=new Array(); for(var i=0;i<n;i++){ arrayobj[i]=i } 2.array对象的输出 将array对象的元素值输出有三种方法 (1)用下标获取指定元素值 arrayobj=new Array("a","b","c") var s=arrayobj[1]; (2)用for语句获取数组中的元素值 arrayobj=new Array("a","b","c") for(var i=0;i<arrayobj.length;i++){ str=str+arrayobj[i].toString(); } document.write(str); (3)用数组对象名输出所有元素值 Array对象的方法 数组的添加和删除 数组的添加和删除可以使用concat()、shift()、pop()、push()、unshift()方法实现。 1.concat()方法 concat()方法用于将其他数组连接到当前数组的尾端 语法:arrayobject.concat(arrayX,arrayX,arrayX,...,arrayX) arrayobject:必选项。数组名称。 arrayX:必选项。该参数可以是具体的值,也可以是数组对象。 例子:var arr=new Array(1,2,3,4,5,6,7,8); document.write(arr.concat(9,10)); 2.shift()方法 shift()方法用于把数组中的第一个元素从数组中删除,并返回删除元素的值。 语法:arrayobject.shift() arrayobject:必选项。数组名称。 返回值:在数组中删除的第一个元素的值。 例子: var arr=new Array(1,2,3,4,5,6,7,8); var del=arr.shift(); console.log("删除的元素是:"+del+"删除后的数组为:"+arr); 3.pop()方法 pop()方法用于删除返回数组中的最后一个元素。 语法:arrayobject.pop() 返回值:array对象的最后一个元素。 var arr=new Array(1,2,3,4,5,6,7,8); var del=arr.pop(); console.log("删除的元素是:"+del+"删除后的数组为:"+arr); 4.push()方法 push()方法向数组的末尾添加一个或多个元素,并返回添加后的数组长度。 语法:arrayobject.push(newelement1,newelement2,...newelementN,) 返回值:把指定的值添加到数组后的新长度。 5.unshift()方法 unshift()方法向数组的开头添加一个或多个元素。 语法:arrayobject.unshift(newelement1,newelement2,...newelementN,) 设置数组的排列顺序 1.reverse()方法 reverse()方法用于颠倒数组中元素的顺序。 语法:arrayobject.reverse() 例子: var arr=new Array(1,2,3,4,5,6,7,8); console.log(arr); arr.reverse(); console.log("删除后的数组为:"+arr); 2.sort()方法 sort()方法用于对数组的元素进行排序。 语法:arrayobject.sort(sortby) sortby:可选项。规定排序的顺序,必须是函数。 例子: var arr=new Array(5,4,2,3,1,6,7,8); console.log(arr); arr.sort(); console.log("删除后的数组为:"+arr); 获取数组中的某段数组元素 获取数组中的某段数组元素主要用slice()方法实现。 slice()方法可从已有的数组中返回选定的元素。 语法:arrayobject.slice(start,end) start:必选项。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说-1指最后一个元素,-2指倒数第二个元素。 end:可选项。规定从何处结束选取。 返回值:返回截取后的数组元素,该方法返回的数据中不包括end索引所对应的数据。 var arr=new Array(5,4,2,3,1,6,7,8); console.log("从数组第3个元素开始选择:"+arr.slice(3)); console.log("从数组第2个元素到5个元素开始选择:"+arr.slice(2,5));

优秀的个人博客,低调大师

JavaScript学习(八)

目录 对象分类: 1.内建对象: 2.宿主对象: 3.自定义对象: javascript内部对象 FileSystemObject对象 动态创建FileSystemObject对象 FileSystemObject对象的方法 In 运算符 JS数据类型 对象字面量 函数: 对象分类: 1.内建对象: 由ES标准中定义的对象,在任何ES中都可以使用 ----比如:math,string,number,Boolean 2.宿主对象: 由JS的运行环境提供的对象,目前来讲主要指浏览器提供的对象 比如:BOM,DOM 3.自定义对象: 由开发人员自己创建的对象 javascript内部对象 对象属于复合的数据类型。 FileSystemObject对象 在javascript中实现文件操作功能,主要是依靠FileSystemObject对象。该对象用来创建、删除和获得有关信息,还可以用来操作驱动器、文件夹和文件的方法和属性。 动态创建FileSystemObject对象 要想对文件进行相应的操作,首先需要对FileSystemObject对象进行实例化,也就是动态创建FileSystemObject对象。 语法:fso =new ActiveXObject("Scripting.FileSystemObject"); fso =new ActiveXObject("Scripting.FileSystemObject");只能在IE上使用 参数说明:fso:是FileSystemObject对象的一个实例。 FileSystemObject对象的方法 (1)GetAbsolutePathName()方法 GetAbsolutePathName()方法根据提供的路径返回完整的路径。如果路径提供了从指定驱动器的根开始的完整的引用,那么它就是完整的。如果路径指定的是映射驱动器的根文件夹,那么完整的路径只能由一个路径分隔符“\”结束。 语法:object.GetAbsolutePathName(pathspec) object:必选项。FileSystemObject对象的名称 pathspec:必选项。要变成完整路径的路径说明。该参数的相应设置如下表 (2)GetBaseName()方法 GetBaseName() 方法将以字符串的形式返回指定路径中最后成分中的基本名称,不包含文件扩展名。 语法:object.GetBaseName(path) object:必选项。FileSystemObject对象的名称 path:必选项。返回其最后成分中的基本名称的指定路径。当路径与path参数不匹配时,GetBaseName()方法将返回长度为0的空字符串。 (3)GetDriveName()方法 GetDriveName()方法根据指定路径返回包含驱动器名称的字符串。 语法:object.GetDriveName(path) (4)GetDrive()方法 GetDrive()方法用于返回指定路径中驱动器的Drive对象。 语法:object.GetDrive(drivespec); drivespec:必选项。该参数可以是驱动器号(c)、带冒号的驱动器号(c:)、带冒号和路径分隔符的驱动器号(c:\),或者任意网络共享的说明(\\computer2\share1). (5)GetExtensionName()方法 GetExtensionName()方法用于返回指定路径中最后成分扩展名的字符串。 语法:object.GetExtensionName(path) (6)GetFileName()方法 GetFileName()方法返回指定路径的最后成分,但指定的路径不能只是驱动器说明,也可以是共享路径。 语法:object.GetFileName(pathspec) pathspec:必选项。指定文件的路径(绝对或相对路径) (7)GetParentFolderName()方法 GetParentFolderName()方法根据指定路径中的最后成分返回其父文件夹名称的字符串。 语法:object.GetParentFolderName(path) path;必选项。文件名所在的完整路径 (8)GetTempName()方法 GetTempName()方法返回一个随机产生的临时文件或文件夹名,有助于执行那些需要临时文件或文件夹的操作 语法:object.GetTempName(); In 运算符 通过该运算符可以检测一个对象中是否含有指定的属性。 var k=new Object(); k.name="s"; k.test=true; alert("s" in k); var k=new Object(); k.name="s"; k.test=true; alert("test" in k); JS数据类型 JS中的变量都是保存到栈内存当中的,基本数据类型的值直接在栈内存中存储。 值与值之间是独立存在的,修改一个变量不会影响其他变量 对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象的引用,当通过一个变量修改属性时,另一个也会受到影响。 对象字面量 可以使用对象字面量来创建一个对象:var obj={} 等价于var obj=new object(); 使用对象字面量,可以直接指定对象中的属性。 语法:{属性名:属性值,属性名:属性值...} 例子:var obj={name:"asfas",sex="男"} 对象字面量的属性名可以加引号也可以不加,属性名和属性值是一组一组的名值对结构。名和值之间使用:连接 函数: 函数也是一个对象。 函数中可以封装某一些功能(代码),在需要时执行这些功能(代码) 创建一个函数对象: var fun=new Function() 可以将要封装的代码以字符串形式传递给要封装的函数 封装到函数中的代码不会立即执行。 语法:function 函数名(){ }

优秀的个人博客,低调大师

JavaScript学习(五)

目录 条件判断语句: if语句: if...else语句 switch语句 while语句 do...while语句 for循环语句 跳转语句: continue语句 break语句 条件判断语句: if语句: if条件判断语句是最基本、最常用的流程控制语句,可以根据条件表达式的值执行相应的处理。 简单的if语句的语法格式如下: if(expression){ statement 1 } expression:必选项,用于指定条件表达式,可以使用逻辑运算符。 statement 1:用于指定要执行的语句序列。当expression的值为true时,执行该语句序列,简单if语句的执行流程如下图。 if...else语句 if...else语句是if语句的标准形式,在if语句简单形式的基础之上增加一个else从句,当expression的值是false时则执行else从句中的内容。 if...else语句格式如下: if(expression){ statement 1 } else{ statement2 } 在if语句的标准形式中,首先对expression的值进行判断,如果它的值是true,则执行statement1语句块的内容,否则执行statement2语句块中的内容。 switch语句 switch语句是典型的多路分支语句,其作用与嵌套使用if语句基本相同,但switch语句比if语句更具有可读性,而且switch语句允许在找不到一个匹配条件的情况下执行默认的一组语句。 switch语句语法格式如下: switch(expression){ case judgement 1; statement 1; break; case judgement 2; statement 2; break; case judgement n; statement n; break;.... } expression:任意的表达式或变量。 judgement:任意的常数表达式。当expression的值与某个judgement的值相等时,就执行此case后的statement语句。 break:用于结束switch语句,从而使javascript只执行匹配的分支。 while语句 while(expression){ statement } expression:一个包含比较运算符的条件表达式,用来指定循环条件。 statement:用来指定循环体,在循环条件的结果为true时,重复执行。 do...while语句 do{ statement }while(expression); statement:用来指定循环体,循环开始时首先被执行一次,然后在循环条件的结果为true时,重复执行。 expression:一个包含比较运算符的条件表达式,用来指定循环条件。 for循环语句 for(initialize;test;increment){ statement } initialize:初始化语句,用来对循环变量进行初始化赋值。 test:循环条件,一个包含比较运算符的表达式,用来限定循环变量的边限。如果循环变量超过了该边限,则停止该循环语句的执行。 increment:用来指定循环变量的步幅。 statement:用来指定循环体,在循环条件的结果为true时,重复执行。 跳转语句: continue语句 continue语句和break语句类似,不同之处在于,break语句退出循环,而continue语句用于中止本次循环,并开始下一次循环。其语法格式如下: continue; continue语句只能应用在while,for,do...while语句中。 break语句 break语句用于退出包含在最内层的循环或者退出一个switch语句。break语句语法格式如下: break; break语句通常用于for,while,do...while或switch语句中。

优秀的个人博客,低调大师

JavaScript学习(六)

目录 函数 函数的定义 函数的调用 函数的简单调用 在事件响应中调用函数 通过超链接定义函数 函数参数的使用 使用函数的返回值 嵌套函数 递归函数 javascript中的内置函数 (1)parseInt()函数: (2)parseFloat()函数 (3)isNaN()函数 (4)isFinite()函数 (5)encodeURI()函数 (6)decodeURI()函数 Function()构造函数与函数直接量 函数 函数的定义 在javascript中,函数是由关键字function 、函数名加一组参数以及置于大括号中需要执行的一段代码定义的。基本语法如下: function functionName(【parameter 1、parameter 2...】){ statement; [return expression;] } functionName:必选项。用于指定函数名。在同一个页面中,函数名必须是唯一的,并且区分大小写。 parameter:可选性。用于指定参数列表。当使用多个参数时,参数间使用逗号进行分隔。一个函数最多可以有255个参数。 statement:必选项。是函数体,用于实现函数功能的语句。 expression:可选项。用于返回函数值。expression为任意表达式变量或常量。 函数的调用 函数的简单调用 函数的定义语句通常会放在HTML文件的<head>段中,而函数的调用语句通常被放在<body>段中,如果在函数定义前调用函数,执行将会出错。函数的定义及调用语法如下: <html> <head> <script type="text/javascript"> function functionName(parameters){ some statement; } //定义函数 </script> </head> <body> functionName(parameter);//调用函数 </body> </html> functionName:函数名称 parameter:参数名称 在事件响应中调用函数 当用户单击某个按钮或选择某个复选框时都将触发事件,通过编写程序对事件做出反应的行为称为响应事件,在javascript语言中,将函数与事件相关联就完成了响应事件的过程。如当用户单击某个按钮时执行相应的函数。 <html> <head> <meta charset="utf-8"> <title>JS基本语法</title> <script type="text/javascript"> function test(){ //定义函数 alert("test"); } </script> </head> <body> <form action="" method="post" name="form1"> <input type="button" value="提交" onclick="test();"> //在按钮事件触发时调用自定义函数 </form> </body> </html> 通过超链接定义函数 函数除了可以在响应事件中被调用外,还可以在超链接中被调用。在<a>标记中的<href>标记中使用"javascript:关键字"超链接来调用函数,当用户单击该超链接时,相关函数将被执行。下面的代码实现了通过超链接接调用函数。 <html> <head> <meta charset="utf-8"> <title>JS基本语法</title> <script type="text/javascript"> function test(){ //定义函数 alert("test"); } </script> </head> <body> <a href="javascript:test()">test</a> <!--在超链接中调用自定义函数--> </body> </html> 函数参数的使用 function 自定义函数名(形参1,形参2...){ 函数体 } 定义函数时,在函数名后面的圆括号内可以指定一个或多个参数(参数之间用“,”分隔)。指定参数的作用在于,当调用函数时,可以为被调用函数传递一个或多个值。 在定义函数时指定的参数被称为形式参数,而把调用函数时实际传递的值称为实际参数。 使用函数的返回值 有时需要在函数中返回一个数值供在其他函数中使用,为了能够返回给变量一个值,可以在函数中添加return语句,将需要返回的值赋予变量,最后将此变量返回。 <script type="text/javascript"> function functionName(parameters){ //定义函数 var results=somestaments; return results; } </script> results:函数中的局部变量 return:函数中返回变量的关键字。(返回值在函数调用中不是必须的) 嵌套函数 所谓的嵌套函数就是在函数内部再定义一个函数,这样定义的优点在于可以使内部函数轻松获得外部函数的参数以及函数的全局变量等。 语法: <script type="text/javascript"> function functionName(parameter1,parameter2){ //定义函数 function innerFunction(){ somestatements; } } </script> functionName:外部函数名称 innerFunction:内部函数名称 递归函数 所谓递归函数就是函数在自身的函数体内调用自身,使用递归函数时一定要当心,处理不当将会使程序进入死循环,递归函数只能在特定的情况下使用,如处理阶乘问题。 语法: <script type="text/javascript"> function functionName(parameter1){ //定义函数 function functionName(parameter2){ } } </script> javascript中的内置函数 在使用javascript语言时,除了可以自定义函数之外,还可以使用javascript的内置函数,这些内置函数是由javascript语言自身提供的。 (1)parseInt()函数: 主要将首位为数字的字符串转换成数字,如果字符串不是以数字开头,那么将返回NaN. 语法:parseInt(StringNum,[n]) StringNum:需要转换成整型的字符串。 n:提供在2-36之间的数字表示所保存数字的进制数。这个参数在函数中不是必需的。 (2)parseFloat()函数 parseFloat()函数主要将首位为数字的字符串转换成浮点型数字,如果字符串不是以数字开头,那么将返回NaN. 语法:parseFloat(StringNum) StringNum:需要转换成浮点型的字符串。 (3)isNaN()函数 语法:isNaN(Num) Num:需要验证的数字。 (4)isFinite()函数 isFinite()函数主要用于检验某个表达式是否为无穷大。 语法:isFinite(Num) Num:需要验证的数字。 (5)encodeURI()函数 encodeURI()函数主要用于返回一个URI字符串编码后的结果。 语法:encodeURI(url) url:需要转换为网络资源地址的字符串。 (6)decodeURI()函数 decodeURI()函数主要用于将已编码为URI的字符串解码成最初的字符串并返回。 decodeURI(url) url:需要解码的网络资源地址。 Function()构造函数与函数直接量 除了使用基本的function语句定义函数之外,还可以使用另外两种方式来定义,即使用Function()构造函数和函数直接量定义。 构造函数Function()允许在运行时动态创建和编译javascript代码,而函数直接量却是程序结构的一个静态部分,就像函数语句一样。 每次调用构造函数Function()都会解析函数体,并且创建一个新的函数对象。 Function()创建的函数使用的不是静态作用域,相反的,该函数总是被当作顶级函数来编译。 function maskingKeyboard(){ if(event.keyCode==8){ //判断是否为Backspace键 event.keyCode=0; event.returnValue=false; aler("当前设置不允许使用Backspace键"); } if(event.keyCode==13){ //判断是否为Enter键 event.keyCode=0; event.returnValue=false; aler("当前设置不允许使用Enter键"); } if(event.keyCode==116){ //判断是否为F5键 event.keyCode=0; event.returnValue=false; aler("当前设置不允许使用F5刷新键"); } //判断是否为Alt+方向键←或方向键→ if((event.altKey)||((window.event.keyCode==37)||(window.event.keyCode==39)){ event.returnValue=false; aler("当前设置不允许使用Alt+方向键一或方向键→"); } if(event.ctrlKey)&&(eventkeyCode==78){ //判断是否为Ctrl+N快捷键 event.returnValue=false; alert("当前设置不允许使用Ctrl+N新建IE窗口") } if(event.shiftKey)&&(event.keyCode==121){ //判断是否为Ctrl+N快捷键 event.returnValue=false; alert("当前设置不允许使用Shift+F10"); } } function rightKey(){ if(event.button==2){ event.returnValue=false; alert("禁止使用鼠标右键! "); } } document.onmousedown=rightKey(); document.onkeydown=maskingKeyboard();

优秀的个人博客,低调大师

JavaScript学习(练习)

练习:用户登录界面 代码: <script type="text/javascript"> function check(){ var name=form1.user.value; //获取用户添加的用户名信息 var pwd=form1.pwd.value; //获取用户添加的密码信息 if((name=="")||(name=null)){ //判断用户名是否为空 alert("请输入用户名!"); form1.user.focus(); //用户名文本框获取焦点 return; }else if((pwd=="")||(pwd=null)){//判断密码是否为空 alert("请输入密码!"); form1.pwd.focus(); //密码文本框获取焦点 return; }else{ form1.submit(); //提交表单 } } </script> <body> <form name="form1" method="post" action=""> <table border="1" cellspacing="0" cellpadding="0" bordercolor="#FFFFFF" bordercolordark="#CCCCCC" bordercolorlight="#FFFFFF"> <tr> <td height="30" colspan="2" bgcolor="antiquewhite">用户登录</td> </tr> <tr> <td width="59" height="30">用户名:</td> <td width="162"><input name="user" type="text" class="user"></td> </tr> <tr> <td height="30">密 码</td> <td><input name="pwd" type="text" class="pwd"></td> </tr> <tr> <td height="30" colspan="2" align="center"> <input name="button" type="button" class="btn_grey" value="登录" onclick="check()"> &nbsp; <input name="Submit2" type="reset" class="btn_grey" value="重置"> </td> </tr> </table> </form> </body> 练习:星期获取系统 <script type="text/javascript"> var now=new Date(); var day=now.getDay(); var week; switch(day){ case 1: week="星期一"; break; case 2: week="星期二"; break; case 3: week="星期三"; break; case 4: week="星期四"; break; case 5: week="星期五"; break; case 6: week="星期六"; break; case 7: week="星期七"; break; } document.write("今天是"+week); </script>

优秀的个人博客,低调大师

JavaScript学习(四)

一元运算符:只需要一个操作数。 + 正号:正号不会对我们的数值产生任何影响 - 负号:负号可以对数值进行负号取反 正负号都可以将数值类型转换成number,原理和number()函数一样。 自增和自减: 自增:可以使变量在自身的基础上+1 运算符:++ 自增分为2种,a++和++a 对于原变量来说是没有区别的,都会使原变量的值+1 不同的是a++和++a的值不同:a++的值等于自增前的值,++a的值等于自增后的值 自减:可以使变量在自身的基础上-1 运算符:-- 逻辑运算符: !非 :可以用来对一个值进行非运算----------为任意数值进行两次非运算,可以转化为布尔值 &&与 :可以对符号两边的值进行与运算并返回结果---两个值中只要有一个为false就返回false ||或 :可以对符号两边的值进行或运算并返回结果---两个值中只要有一个为true就返回true 赋值运算符: =等于:可以将右侧数值赋值给左侧的变量 +=:a=a+5可以转变为a += 5 -=:a=a-5等价于a -= 5 *=:a=a*5等价于a *= 5 /=:a=a/5等价于a /= 5 %=:a=a%5等价于a %= 5 关系运算符: 通过关系运算符可以比较两个值之间的关系。 如果关系成立将会返回true,如果关系不成立将会返回false。 >大于号 <小于号 >=大于等于 <=小于等于 非数值比较时会将其转化为数值再进行比较 任何值和NaN做任何比较都返回false。 如果符号两侧的值都是字符串,它不会将其转换成数字进行比较,会分别比较字符串中字符的Unicode编码大小。 比较字符编码时是一个一个进行比较的,如果两位一样则比较下一位。 Unicode编码: 输出编码:console.log(" \u四位编码 "); 在网页中输入Unicode编码:&#编码,这里的编码需要转化为10进制的 相等运算符: 运算符:== 用来比较两个值是否相等,如果相等返回true,不相等返回false 当使用==来比较时,如果值的类型不同,则会自动进行转化成相同类型,然后再比较。 undefined衍生自null,两者做==判断将会返回true。 条件运算符(三元运算符): 语法:条件表达式?语句1:语句2 执行流程:首先对条件表达式进行求值,如果返回true,则执行语句1;如果返回false,则执行语句2

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Oracle

Oracle

Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的、适应高吞吐量的数据库方案。

Apache Tomcat

Apache Tomcat

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

JDK

JDK

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。