Maven jar plugin

Maven jar plugin 1.修改pom.xml增加如下内容 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.4</version> <configuration> <manifest> true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.sysware.HelloWorld</mainClass> </manifest> </archive> </configuration> </plugin> 运行mvn clean package即可 html …src/main/java src/main/resources ...

2015-08-24 · 1 min · 81 words · -

Java读 环境变量

Java读 环境变量 http://ling091.iteye.com/blog/354052 读取环境变量时可以使用 System.getProperty 或 System.getenv 方法。 System.getProperty 方法 ( JDK1.4 ) 用来读取针对 JVM 的属性,如程序当前的运行路径、路径分隔符、 Java 版本等, ( 见 System.getProperty() 参数大全 ) ,它也可以读取在运行程序时设置的自定义属性。 获取一个JVM已定义属性 //获取系统当前的运行路径 System.out.println(“current path = " + System.getProperty(“user.dir”) ); 输出: current path = E:\program\java\test\Test 获取应用程序的属性: 在命令中输入下面的命令,其中的-D用于设置一个属性 -D= SET myvar=Hello world SET myothervar=nothing java -Dmyvar="%myvar%” -Dmyothervar="%myothervar%" myClass myClass中读取这些属性 String myvar = System.getProperty(“myvar”); String myothervar = System.getProperty(“myothervar”); 如果要读取操作系统的环境变量 (如 Path 、 TEMP 或 TMP 、 JAVA_HOME 等。) 则可以使用 System.getenv 方法,但是由于某些原因,该方法被去掉了,直到 JDK1.5 后,该方法又被加进去 [3] 。 ...

2015-08-14 · 1 min · 119 words · -

java ssh

java ssh http://www.rigongyizu.com/java-ssh-copy-remote-file/ http://www.rigongyizu.com/tag/java/ jsch http://www.jcraft.com/jsch/ http://www.rigongyizu.com/tag/java/ Ganymed SSH-2 for Java http://www.cleondris.ch/opensource/ssh2/ 也是纯java实现了ssh2协议,这个库代码比较老,一直没更新了,只在J2SE 1.4.2 和 5.0上测试过。网上有些例子。 sshj https://github.com/shikhar/sshj API封装的很友好,功能齐全。 sshd http://mina.apache.org/sshd-project/index.html 基于mina,可以同时支持ssh服务端和客户端。

2015-08-14 · 1 min · 22 words · -

Maven

Maven http://juvenshun.iteye.com/blog/376422 什么是版本管理 首先,这里说的版本管理 (version management) 不是指版本控制 (version control) ,但是本文假设你拥有基本的版本控制的知识,了解subversion的基本用法。版本管理中说得版本是指构件 (artifact) 的版本,而非源码的版本 (如subversion中常见的rXXX,或者git中一次提交都有个sha1的commit号) 。 比如我有一个项目,其artifactId为myapp,随着项目的进展,我们会生成这样一些jar: myapp-1.0-SNAPSHOT.jar,myapp-1.0.jar,myapp-1.1-SNAPSHOT.jar,myapp-1.0.1.jar等等。你可能会说,这很简单啊,我在POM中改个version,mvn clean install不就完了?但这只是表面,本文我将讲述,snapshot和release版本的区别,如何自动化版本发布 (如果你的项目有几十个module,你就会觉得手工改POM来升级版本是很痛苦的事情) ,结合自动化发布的过程,这里还会介绍maven-release-plugin。此外,一些scm概念也会被涉及到,比如tag和branch。 前提: 版本控制 不管怎样,我们都需要建立一个项目并提交到SCM中,这里我以subversion为例。你得有一个配置好的subversion repository,这里我建立了一个空的svn仓库,其地址为: https://192.168.1.100:8443/svn/myapp/ 现在,该目录下只有三个空的典型的子目录: /trunk/, branches/, tags/。分别用来存放主干,分支,以及标签。 接着将项目导入到svn仓库中,到项目根目录,运行如下命令: svn import -m 'project initialization' https://192.168.1.100:8443/svn/myapp/trunk (注意,这么做你会将目录下所有文件导入到svn库中,但是这其中某些目录和文件是不应该被导入的,如/target目录,以及eclipse相关的项目文件) 目前,我们将项目的版本设置为1.0-SNAPSHOT。 为什么用SNAPSHOT? 我先说说如果没有SNAPSHOT会是什么样子。假设你的项目有2个模块,A,B,其中A依赖B。这两个模块分别由甲,乙两个个人负责开发。在开发过程中,因为A是依赖于B的,因此乙每次做一个改动都会影响到甲,于是,乙提交了一些更改后,需要让甲看到。这个时候,怎么做呢?乙对甲说,"你签出我的代码,build一下就OK了",甲有点不情愿,但还是照做了,签出代码,svn clean install,然后,发现build出错了,有个测试没有pass。甲郁闷了,对乙说,"你的代码根本不能用,我不想build,你build好了给我",乙看了看确实自己的代码build不过,于是回去解决了,然后打了个jar包,扔给甲,甲对了对groupId,artifactId,放到了自己的.m2/repository/目录下,OK,能用了。 于是乙每次更新都这样做,打包,复制,然后甲粘贴,使用……渐渐的,大家发现这是个很笨的办法,这是纯手工劳动阿,程序员最BS的就是重复劳动。一天,甲对乙说,"你知道nexus么?你把你的jar发布到nexus上就可以了,我要用就自动去下载,这多棒!"乙说"哦?有这好东西,我去看看"于是乙发现了nexus这块新大陆,并成功的发布了B到nexus上。 (见,Nexus入门指南, (图文) ) 。 但是,请注意,我们这里的一切都假设没有SNAPSHOT,因此如果乙不更改版本,甲下载一次如B-1.0.jar之后,maven认为它已经有了正确的B的版本,就不会再重新下载。甲发现了这个问题,对乙说"你的更新我看不到,你更新了么?"乙说"不可能!我看看",于是检查一下甲下载的C-1.0.jar,发现那是几天前的。乙一拍脑袋,说"这简单,我更新一下我的版本就好了,我发布个B-1.1.jar上去,你更新下依赖版本",甲照做了,似乎这么做是可行的。 这里有一个问题,一次提交就更新一个版本,这明显不是正确的管理办法,此外,乙得不停的通知甲更新对B的依赖版本,累不累阿?1.0,或者说1.1,2.0,都代表了稳定,这样随随便便的改版本,能稳定么? 所以Maven有SNAPSHOT版本的概念,它与release版本对应,后者是指1.0,1.1,2.0这样稳定的发布版本。 现在乙可以将B的版本设置成1.0-SNAPSHOT,每次更改后,都mvn deploy到nexus中,每次deploy,maven都会将SNAPSHOT改成一个当前时间的timestamp,比如B-1.0-SNAPSHOT.jar到nexus中后,会成为这个样子: B-1.0-20081017-020325-13.jar。Maven在处理A中对于B的SNAPSHOT依赖时,会根据这样的timestamp下载最新的jar,默认Maven每天 更新一次,如果你想让Maven强制更新,可以使用-U参数,如: mvn clean install -U 。 现在事情简化成了这个样子: 乙做更改,然后mvn deploy,甲用最简单的maven命令就能得到最新的B。 从1.0-SNAPSHOT到1.0到1.1-SNAPSHOT SNAPSHOT是快照的意思,项目到一个阶段后,就需要发布一个正式的版本 (release版本) 。一次正式的发布需要这样一些工作: 在trunk中,更新pom版本从1.0-SNAPSHOT到1.0 对1.0打一个svn tag 针对tag进行mvn deploy,发布正式版本 更新trunk从1.0到1.1-SNAPSHOT 你可以手工一步步的做这些事情,无非就是一些svn操作,一些pom编辑,还有一些mvn操作。但是你应该明白,手工做这些事情,一来繁琐,而来容易出错。因此这里我介绍使用maven插件来自动化这一系列动作。 SCM 首先我们需要在POM中加入scm信息,这样Maven才能够替你完成svn操作,这里我的配置如下: ```xml 需要注意的是,很多windows使用的tortoiseSVN客户端,而没有svn命令行客户端,这会导致Maven所有svn相关的工作失败,因此,你首先确保svn -version能够运行。 分发仓库 想要让Maven帮我们自动发布,首先我们需要配置好分发仓库。关于这一点,见Maven最佳实践: Maven仓库——分发构件至远程仓库。 maven-release-plugin 紧接着,我们需要配置maven-release-plugin,这个插件会帮助我们升级pom版本,提交,打tag,然后再升级版本,再提交,等等。基本配置如下: ```xml <version>2.0-beta-7</version> <configuration> <tagBase>https://192.168.1.100:8443/svn/myapp/tags/</tagBase> </configuration> </plugin> GAV我就不多解释了,这里我们需要注意的是configuration元素下的tagBase元素,它代表了我们svn中的tag目录,也就是说,maven-release-plugin帮我们打tag的时候,其基础目录是什么。这里,我填写了svn仓库中的标准的tags目录。 提交代码 接着,确保你的所有代码都提交了,如果你有未提交代码,release插件会报错,既然你要发布版本了,就表示代码是稳定的,所以要么要么把代码提交了,要么把本地的更改抛弃了。 开始工作 现在,屏住呼吸,执行: mvn release:prepare 执行过程中,你会遇到这样的提示: What is the release version for "Unnamed - org.myorg:myapp:jar:1.0-SNAPSHOT"? (org.myorg:myapp) 1.0: : ——"你想将1.0-SNAPSHOT发布为什么版本?默认是1.0。"我要的就是1.0,直接回车。 What is SCM release tag or label for "Unnamed - org.myorg:myapp:jar:1.0-SNAPSHOT"? (org.myorg:myapp) myapp-1.0: : ——"发布的tag标签名称是什么?默认为myapp-1.0。"我还是要默认值,直接回车。 What is the new development version for "Unnamed - org.myorg:myapp:jar:1.0-SNAPSHOT"? (org.myorg:myapp) 1.1-SNAPSHOT: : ——"主干上新的版本是什么?默认为1.1-SNAPSHOT。"哈,release插件会自动帮我更新版本到1.1-SNAPSHOT,很好,直接回车。 然后屏幕刷阿刷,maven在build我们的项目,并进行了一些svn操作,你可以仔细查看下日志。 那么结果是什么呢?你可以浏览下svn仓库: 我们多了一个tag: https://192.168.1.100:8443/svn/myapp/tags/myapp-1.0/,这就是需要发布的版本1.0。 再看看trunk中的POM,其版本自动升级成了1.1-SNAPSHOT。 这不正是我们想要的么?等等,好像缺了点什么,对了,1.0还没有发布到仓库中呢。 再一次屏住呼吸,执行: mvn release:perform maven-release-plugin会自动帮我们签出刚才打的tag,然后打包,分发到远程Maven仓库中,至此,整个版本的升级,打标签,发布等工作全部完成。我们可以在远程Maven仓库中看到正式发布的1.0版本。 这可是自动化的 ,正式的 版本发布! Maven的版本规则 前面我们提到了SNAPSHOT和Release版本的区别,现在看一下,为什么要有1.0,1.1,1.1.1这样的版本,这里的规则是什么。 Maven主要是这样定义版本规则的: <主版本>.<次版本>.<增量版本> 比如说1.2.3,主版本是1,次版本是2,增量版本是3。 主版本一般来说代表了项目的重大的架构变更,比如说Maven 1和Maven 2,在架构上已经两样了,将来的Maven 3和Maven 2也会有很大的变化。 次版本一般代表了一些功能的增加或变化,但没有架构的变化,比如说Nexus 1.3较之于Nexus 1.2来说,增加了一系列新的或者改进的功能 (仓库镜像支持,改进的仓库管理界面等等) ,但从大的架构上来说,1.3和1.2没什么区别。至于增量版本,一般是一些小的bug fix,不会有重大的功能变化。 一般来说,在我们发布一次重要的版本之后,随之会开发新的版本,比如说,myapp-1.1发布之后,就着手开发myapp-1.2了。由于myapp-1.2有新的主要功能的添加和变化,在发布测试前,它会变得不稳定,而myapp-1.1是一个比较稳定的版本,现在的问题是,我们在myapp-1.1中发现了一些bug (当然在1.2中也存在) ,为了能够在段时间内修复bug并仍然发布稳定的版本,我们就会用到分支 (branch) ,我们基于1.1开启一个分支1.1.1,在这个分支中修复bug,并快速发布。这既保证了版本的稳定,也能够使bug得到快速修复,也不同停止1.2的开发。只是,每次修复分支1.1.1中的bug后,需要merge代码到1.2 (主干) 中。 上面讲的就是我们为什么要用增量版本。 实战分支 目前我们trunk的版本是1.1-SNAPSHOT,其实按照前面解释的版本规则,应该是1.1.0-SNAPSHOT。 现在我们想要发布1.1.0,然后将主干升级为1.2.0-SNAPSHOT,同时开启一个1.1.x的分支,用来修复1.1.0中的bug。 首先,在发布1.1.0之前,我们创建1.1.x分支,运行如下命令: mvn release:branch -DbranchName=1.1.x -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false 这是maven-release-plugin的branch目标,我们指定branch的名称为1.1.x,表示这里会有版本1.1.1, 1.1.2等等。updateBranchVersions=true的意思是在分支中更新版本,而updateWorkingCopyVersions=false是指不更改当前工作目录 (这里是trunk) 的版本。 在运行该命令后,我们会遇到这样的提示: What is the branch version for "Unnamed - org.myorg:myapp:jar:1.1-SNAPSHOT"? (org.myorg:myapp) 1.1-SNAPSHOT: : ——"分支中的版本号是多少?默认为1.1-SNAPSHOT" 这时我们想要的版本是1.1.1-SNAPSHOT,因此输入1.1.1-SNAPSHOT,回车,maven继续执行直至结束。 接着,我们浏览svn仓库,会看到这样的目录: https://192.168.1.100:8443/svn/myapp/branches/1.1.x/,打开其中的POM文件,其版本已经是1.1.1-SNAPSHOT。 分支创建好了,就可以使用release:prepare和release:perform为1.1.0打标签,升级trunk至1.2.0-SNAPSHOT,然后分发1.1.0。 至此,一切OK。 小结 本文讲述了如何使用Maven结合svn进行版本管理。解释了Maven中SNAPSHOT版本的来由,以及Maven管理版本的规则。并结合SCM的tag和branch概念展示了如何使用maven-release-plugin发布版本,以及创建分支。本文涉及的内容比较多,且略显复杂,不过掌握版本管理的技巧对于项目的正规化管理来说十分重要。Maven为我们提供了一些一套比较成熟的机制,值得掌握。

2015-08-14 · 1 min · 210 words · -

MySQL replace into

MySQL replace into http://my.oschina.net/junn/blog/110213 Replace into是Insert into的增强版。在向表中插入数据时,我们经常会遇到这样的情况: 1、首先判断数据是否存在;2、如果不存在,则插入;3、如果存在,则更新。 在SQL Server中可以这样处理: if not exists (select 1 from t where id = 1) insert into t(id, update_time) values(1, getdate()) else update t set update_time = getdate() where id = 1 那么 MySQL 中如何实现这样的逻辑呢?MySQL 中有更简单的方法: replace into replace into t(id, update_time) values(1, now()); 或 replace into t(id, update_time) select 1, now(); replace into 跟 insert 功能类似,不同点在于: replace into 首先尝试插入数据到表中, 1. 如果发现表中已经有此行数据 (根据主键或者唯一索引判断) 则先删除此行数据,然后插入新的数据。 2. 否则,直接插入新数据。 ...

2015-08-14 · 2 min · 216 words · -

语义化版本, semantic versioning

语义化版本, semantic versioning 版本号格式为v<major>.<minor>.<patch>,如v1.2.3。当有不兼容的改变时,需要增加 major 版本号,如v2.1.0。 MAJOR.MINOR.PATCH 版本格式: 主版本号.次版本号.修订号,版本号递增规则如下: 主版本号: 当你做了不兼容的API 修改, 次版本号: 当你做了向下兼容的功能性新增, 修订号: 当你做了向下兼容的问题修正。 先行版本号及版本编译信息可以加到"主版本号.次版本号.修订号"的后面,作为延伸。 semantic versioning https://semver.org/lang/zh-CN/

2015-08-13 · 1 min · 20 words · -

java 字符串, 比较

java 字符串, 比较 java简单的字符串大小比较——compareTo()方法 在java编程中,我们会偶尔遇到字符串大小比较的问题,compareTo()方法很简单就实现这种功能。该方法用于判断一个字符串是大于、等于还是小于另一个字符串。判断字符串大小的依据是根据它们在字典中的顺序决定的。 语法: Str1.compareTo(Str2); 其返回的是一个int类型值。若Str1等于参数字符串Str2字符串,则返回0;若该Str1按字典顺序小于参数字符串Str2,则返回值小于0;若Str1按字典顺序大于参数字符串Str2,则返回值大于0。 java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码 String a="a",b="b"; System.out.println(a.compareto.b); 则输出-1; 若a="a",b="a"则输出0; 若a="b",b="a"则输出1; 单个字符这样比较,若字符串比较长呢?? 若a=“ab”,b=“b”,则输出-1; 若a=“abcdef”,b=“b"则输出-1; 也就是说,如果两个字符串首字母不同,则该方法返回首字母的asc码的差值; 如果首字母相同呢?? 若a=“ab”,b=“a”,输出1; 若a=“abcdef”,b=“a"输出5; 若a=“abcdef”,b=“abc"输出3; 若a=“abcdef”,b=“ace"输出-1; 即参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的asc码差值,如果两个字符串不一样长,可以参与比较的字符又完全一样,则返回两个字符串的长度差值 参考: http://blog.sina.com.cn/s/blog_8a7200cd010104nx.html http://www.blogjava.net/hgc-ghc/archive/2013/03/28/397084.html //char 转String String str = String.valueOf(c); //判断字符大小写 if( Character.isUpperCase(c)) 1、字节数组转换为字符串 byte[] byBuffer = new byte[20]; … … String strRead = new String(byBuffer); strRead = String.copyValueOf(strRead.toCharArray(), 0, byBuffer.length]); 2、字符串转换成字节数组 byte[] byBuffer = new byte[200]; String strInput=“abcdefg”; byBuffer= strInput.getBytes(); ...

2015-08-13 · 1 min · 76 words · -

Fastjson

Fastjson // 序列化 String text = JSON.toJSONString(obj); // 反序列化 Map<String, Object> foo = JSON.parseObject(jsonStr0, Map.class); fastjson 对象转换时重命名字段名 @JSONField(name="total_count") private int totalCount; @JSONField(name="incomplete_results") private boolean incompleteResults = false; Map<String, Object> userMap = JSON.parseObject(o, new TypeReference<Map<String, Object»() {}); 使用Fastjson序列化与反序列化对象 public class JSONobject { private String obj; private String color; public String getObj() { return obj; } public void setObj(String obj) { this.obj = obj; } public String getcolor() { return color; } public void setcolor(String color) { this.color = color; } ...

2015-08-13 · 2 min · 325 words · -

Mockito

Mockito 部分mock (partial mock) 部分mock是说一个类的方法有些是实际调用,有些是使用mockito的stubbing (桩实现) 。 为什么需要部分mock 当需要测试一个组合方法 (一个方法需要其它多个方法协作) 的时候,某个叶子方法 (只供别人调用,自己不依赖其它反复) 已经被测试过,我们其实不需要再次测试这个叶子方法,so,让叶子打桩实现返回结果,上层方法实际调用并测试。 mockito实现部分mock的两种方式: spy和 callRealMethod() spy的原理是,如果不打桩默认都会执行真实的方法,如果打桩则返回桩实现。可以看出spy.size()通过桩实现返回了值100,而spy.get(0)则返回了实际值 List<String> list = new LinkedList<String>(); List<String> spy = spy(list); when(spy.size()).thenReturn(100); spy.add("one"); spy.add("two"); assertEquals(spy.get(0), "one"); assertEquals(100, spy.size()); Channel channel = mock(Channel.class); when(channel.writeAndFlush(obj)).thenReturn(null); // 重置 spy 对象,让 add(1,2) 调用真实方法,返回 3 when(exampleService.add(1, 2)).thenCallRealMethod(); Assert.assertEquals(3, exampleService.add(1, 2)); 一、什么是mock测试,什么是mock对象? 一种替代方案就是使用mocks 从图中可以清晰的看出 mock对象就是在调试期间用来作为真实对象的替代品。 mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。 知道什么是mock测试后,那么我们就来认识一下mock框架—Mockito 二、什么是Mockito ...

2015-08-13 · 2 min · 352 words · -

powermock

powermock PowerMock LinkageError: MockClassLoader javax/management/MBeanServer{.question-hyperlink} http://stackoverflow.com/questions/20400574/powermock-linkageerror-mockclassloader-javax-management-mbeanserver @RunWith(PowerMockRunner.class) @PowerMockIgnore({“javax.management.*”}) @PrepareForTest(ClassName.class) http://blog.csdn.net/jackiehff/article/details/14000779

2015-08-12 · 1 min · 10 words · -

ConcurrentHashMap

ConcurrentHashMap ConcurrentHashMap 是一个线程安全的Hash Table,它的主要功能是提供了一组和HashTable功能相同但是线程安全的方法。ConcurrentHashMap可以做到读取数据不加锁,并 且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持地尽量地小,不用对整个ConcurrentHashMap加锁。 jdk1.7 由 Segment 数组、HashEntry 组成,和 HashMap 一样,仍然是数组加链表。 它的核心成员变量: /** * Segment 数组,存放数据时首先需要定位到具体的 Segment 中。 */ final Segment<K,V>[] segments; transient Set<K> keySet; transient Set<Map.Entry<K,V>> entrySet; Segment 是 ConcurrentHashMap 的一个内部类,主要的组成如下: static final class Segment<K,V> extends ReentrantLock implements Serializable { private static final long serialVersionUID = 2249069246763182397L; // 和 HashMap 中的 HashEntry 作用一样,真正存放数据的桶 transient volatile HashEntry<K,V>[] table; transient int count; transient int modCount; transient int threshold; final float loadFactor; } 和 HashMap 非常类似,唯一的区别就是其中的核心数据如 value ,以及链表都是 volatile 修饰的,保证了获取时的可见性。 ...

2015-08-12 · 8 min · 1510 words · -

A cycle was detected in the build path of project

A cycle was detected in the build path of project 解决Eclipse中Java工程间循环引用而报错的问题 如果我们的项目包含多个工程 (project) ,而它们之间又是循环引用的关系,那么Eclipse在编译时会抛出如下一个错误信息: “A cycle was detected in the build path of project: XXX” 解决方法非常简单: Eclipse Menu -> Window -> Preferences… -> Java -> Compiler -> Building -> Building path problems -> Circular dependencies -> 将Error改成Warning http://blog.csdn.net/kcai678/article/details/4668993

2015-08-10 · 1 min · 48 words · -

archlinux hibernate

archlinux hibernate edit config file /etc/mkinitcpio.conf add resume field sudo vim /etc/mkinitcpio.conf HOOKS=(base udev resume autodetect modconf block filesystems keyboard fsck) Configure the initramfs When an initramfs with the base hook is used, which is the default, the resume hook is required in /etc/mkinitcpio.conf. Whether by label or by UUID, the swap partition is referred to with a udev device node, so the resume hook must go after the udev hook. This example was made starting from the default hook configuration: ...

2015-08-08 · 1 min · 155 words · -

MySQL 实现 row_number() over(partition by) 分组排序功能

MySQL 实现 row_number() over(partition by) 分组排序功能 mysql 8 MySQL ROW_NUMBER()从8.0版开始引入了功能。这ROW_NUMBER()是一个窗口函数或分析函数,它为从1开始应用的每一行分配一个序号。 mysql 8 之前的替代方案 SELECT t.*, @rownum := @rownum + 1 AS rank FROM YOUR_TABLE t, (SELECT @rownum := 0) r http://mrcelite.blog.51cto.com/2977858/745913 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://mrcelite.blog.51cto.com/2977858/745913 由于MySQL没有提供类似ORACLE中OVER()这样丰富的分析函数. 所以在MySQL里需要实现这样的功能,我们只能用一些灵活的办法: 首先我们来创建实例数据: drop table if exists c; CREATE TABLE `heyf_t10` ( `empid` INT(11) NULL DEFAULT NULL, `deptid` INT(11) NULL DEFAULT NULL, `line` DECIMAL(10,2) NULL DEFAULT NULL ) COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB ; INSERT INTO `heyf_t10` (`empid`, `deptid`, `line`) VALUES (1,10,5500.00), (2,10,4500.00), (3,20,1900.00), (4,20,4800.00), (5,40,6500.00), (6,40,14500.00), (7,40,44500.00), (8,50,6500.00), (9,50,7500.00); 确定需求: 根据部门来分组,显示各员工在部门里按薪水排名名次. 显示结果预期如下: +——-+——–+———-+——+ | empid | deptid | line | rank | +——-+——–+———-+——+ | 1 | 10 | 5500.00 | 1 | | 2 | 10 | 4500.00 | 2 | | 3 | 20 | 1900.00 | 1 | | 4 | 20 | 4800.00 | 2 | | 5 | 40 | 6500.00 | 1 | | 6 | 40 | 14500.00 | 2 | | 7 | 40 | 44500.00 | 3 | | 8 | 50 | 6500.00 | 1 | | 9 | 50 | 7500.00 | 2 | +——-+——–+———-+——+ ...

2015-08-06 · 2 min · 394 words · -

MySQL Error 1093 – Can't specify target table for update in FROM clause

MySQL Error 1093 – Can’t specify target table for update in FROM clause http://stackoverflow.com/questions/45494/MySQL-error-1093-cant-specify-target-table-for-update-in-from-clause wrap the condition in one more select DELETE FROM story_category WHERE category_id NOT IN ( SELECT cid FROM ( SELECT DISTINCT category.id AS cid FROM category INNER JOIN story_category ON category_id=category.id ) AS c )```

2015-08-06 · 1 min · 49 words · -

SIM, eSIM

SIM, eSIM 香港手机流量 在支付宝搜索 “境外上网”, 打开境外上网小程序, 选择中国移动, 目的地选择 “中国香港” 选择 “4G 本地” – 使用香港本地 4G 网络, 能访问 Google 下载 “无忧行” APP, 可以查看流量激活情况和剩余流量. 选择套餐: 境外流量包 4G 本地, 5 天15G: 40RMB – 2024-11-09 泰国手机卡 在支付宝 “境外上网” 里选择目的地 泰国, 选择套餐, 点击预订, 等待实体卡邮寄. Happy 卡 7天 15G: 40RMB – 2024-11-09 Textr eSIM 覆盖全球 131 个国家或地区, 支持 eSIM 香港 10G/68.19RMB 泰国 10G/121.69RMB – 2024-11-09 IMSI, IMEI http://cuisuqiang.iteye.com/blog/2067254 IMSIIMEI网络码运营商MNC IMSI是相对手机卡而言的 国际移动用户识别码 (IMSI: International Mobile Subscriber Identification Number) ...

2015-08-05 · 1 min · 158 words · -

java.net.InetAddress

java.net.InetAddress http://www.cnblogs.com/hnrainll/archive/2012/01/09/2317515.html java.net.InetAddress类的使用 1.1. 简介 IP地址是IP使用的32位 (IPv4) 或者128位 (IPv6) 位无符号数字,它是传输层协议TCP,UDP的基础。InetAddress是Java对IP地址的封装,在java.net中有许多类都使用到了InetAddress,包括ServerSocket,Socket,DatagramSocket等等。 InetAddress的实例对象包含以数字形式保存的IP地址,同时还可能包含主机名 (如果使用主机名来获取InetAddress的实例,或者使用数字来构造,并且启用了反向主机名解析的功能) 。InetAddress类提供了将主机名解析为IP地址 (或反之) 的方法。 InetAddress对域名进行解析是使用本地机器配置或者网络命名服务 (如域名系统 (Domain Name System,DNS) 和网络信息服务 (Network Information Service,NIS) ) 来实现。对于DNS来说,本地需要向DNS服务器发送查询的请求,然后服务器根据一系列的操作,返回对应的IP地址,为了提高效率,通常本地会缓存一些主机名与IP地址的映射,这样访问相同的地址,就不需要重复发送DNS请求了。在java.net.InetAddress类同样采用了这种策略。在默认情况下,会缓存一段有限时间的映射,对于主机名解析不成功的结果,会缓存非常短的时间 (10秒) 来提高性能。 1.2. InetAddress对象的获取 InetAddress的构造函数不是公开的 (public) ,所以需要通过它提供的静态方法来获取,有以下的方法: static InetAddress[] getAllByName(String host) static InetAddress getByAddress(byte[] addr) static InetAddress getByAddress(String host,byte[] addr) static InetAddress getByName(String host) static InetAddress getLocalHost() 在这些静态方法中,最为常用的应该是getByName(String host)方法,只需要传入目标主机的名字,InetAddress会尝试做连接DNS服务器,并且获取IP地址的操作。代码片段如下,注意我们假设以下的代码,都是默认导入了java.net中的包,在程序的开头加上import java.net.*,否则需要指定类的全名java.net.InetAddress。 InetAddress address=InetAddress.getByName(“www.baidu.com”); 注意到这些方法可能会抛出的异常。如果安全管理器不允许访问DNS服务器或禁止网络连接,SecurityException会抛出,如果找不到对应主机的IP地址,或者发生其他网络I/O错误,这些方法会抛出UnknowHostException。所以需要写如下的代码: try { InetAddress address=InetAddress.getByName(“www.baidu.com”); System.out.println(address); } catch(UnknownHostException e) { e.printStackTrace(); } 下面是一则完整的例子: package org.dakiler.javanet.chapter1; import java.net.InetAddress; ...

2015-08-05 · 1 min · 153 words · -

java ByteBuffer

java ByteBuffer ByteBuffer 是 NIO 里用得最多的 Buffer, 它包含两个实现方式: HeapByteBuffer 是基于Java堆的实现, 而 DirectByteBuffer 则使用了 unsafe 的 API 进行了堆外的实现。这里只说 HeapByteBuffer。 Buffer 类 定义了一个可以线性存放primitive type数据的容器接口。Buffer主要包含了与类型 (byte, char…) 无关的功能。 值得注意的是Buffer及其子类都不是线程安全的。 每个Buffer都有以下的属性: capacity 这个Buffer最多能放多少数据。capacity一般在buffer被创建的时候指定。 limit 在Buffer上进行的读写操作都不能越过这个下标。当写数据到buffer中时,limit一般和capacity相等,当读数据时, limit代表buffer中有效数据的长度。 position 读/写操作的当前下标。当使用buffer的相对位置进行读/写操作时,读/写会从这个下标进行,并在操作完成后, buffer会更新下标的值。 mark 一个临时存放的位置下标。调用mark()会将mark设为当前的position的值,以后调用reset()会将position属性设 置为mark的值。mark的值总是小于等于position的值,如果将position的值设的比mark小,当前的mark值会被抛弃掉。 这些属性总是满足以下条件: 0 <= mark <= position <= limit <= capacity limit和position的值除了通过limit()和position()函数来设置,也可以通过下面这些函数来改变: Buffer clear() 把position设为0,把limit设为capacity,一般在把数据写入Buffer前调用。 Buffer flip() 把limit设为当前position,把position设为0,一般在从Buffer读出数据前调用。 Buffer rewind() 把position设为0,limit不变,一般在把数据重写入Buffer前调用。 Buffer 对象有可能是只读的, 这时, 任何对该对象的写操作都会触发一个 ReadOnlyBufferException isReadOnly()方法可以用来判断一个Buffer是否只读。 Buffer是一个抽象的基类 派生类: ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer ...

2015-08-05 · 4 min · 754 words · -

IP,TCP 和 HTTP

IP,TCP 和 HTTP 172.16.128.0/24 经常看到这类IP地址"/24"表示什么意思? 子网掩码, 代表多少个1 子网掩码是4个8位2进制数组成的, 换化成10进制是就是现在这样的, 如255.255.255.0, 换成2进制的话就是11111111 11111111 11111111 00000000, 前面有24个1, 也就是ip/24, 192.168.1.1/24 就表示ip是192.168.1.1, 子网掩码是255.255.255.0 http://objccn.io/issue-10-6/ 当 app 和服务器进行通信的时候,大多数情况下,都是采用 HTTP 协议。HTTP 最初是为 web 浏览器而定制的,如果在浏览器里输入 http://www.objc.io ,浏览器会通过 HTTP 协议和 www.objc.io 所对应的服务器进行通信。 HTTP是运行在应用层上的应用协议,而不同的层级上都有相应的协议在运行。层级的堆栈关系一般可以这么描述: Application Layer - e.g. HTTP – Transport Layer - e.g. TCP – Internet Layer - e.g. IP – Link Layer - e.g. IEEE 802.2 所谓的 OSI (Open Systems Interconnection,开放式系统互联) 模型定义了七层结构。本文会关注应用层 (application layer)、传输层 (transport layer) 和网络层 (internet layer),它们分别代表了典型的 HTTP 的应用的 HTTP,TCP 以及 IP。在 IP 之下的是数据连接和物理层级,比如像 Ethernet 的实现之类的东西 (Ethernet 拥有一个数据连接部分以及一个物理部分) 。 ...

2015-07-29 · 11 min · 2216 words · -

redis hash

redis hash Redis hash 是一个 string 类型的 field和 value的映射表.一个 key可对应多个 field, 一个 field对应一个 value。将一个对象存储为 hash类型,较于每个字段都存储成string类型更能节省内存。新建一个 hash对象时开始是用 zipmap(又称为small hash)来存储的。这个 zipmap其实并不是 hash table,但是zipmap 相比正常的 hash实现可以节省不少 hash本身需要的一些元数据存储开销。尽管 zipmap的添加, 删除,查找都是O(n),但是由于一般对象的field数量都不太多。所以使用zipmap也是很快的,也就是说添加删除平均还是O(1)。如果field或者value的大小超出一定限制后,Redis会在内部自动将zipmap替换成正常的hash实现。 hash操作命令如下: 删除 key del key hset 向名称为 key 的 hash 中添加元素 hset key field value hget hget(key, field) 返回名称为key的hash中field对应的value hsetnx HSETNX key field value 将哈希表key中的域field的值设置为value,当且仅当域field不存在。若域field已经存在,该操作无效。 如果key不存在,一个新哈希表被创建并执行h#setnx命令。 hmget hmget(key, field1, …,field N) 返回名称为key的hash中field i对应的value hmset hmset(key, field1, value1,…,field N, value N) 向名称为key的hash中添加元素field i<—>value i ...

2015-07-28 · 1 min · 177 words · -