快乐就好

开心就好!平平淡淡才是真!

其实掌握MappedByteBuffer并不难,只要记住“三方三法三特性”(我自己总结的,呵呵~~不要扔鸡蛋哦。。。)这句话就可以轻松搞定!MappedByteBuffer 只是一种特殊的 ByteBuffer ,即是ByteBuffer的子类。 MappedByteBuffer 将文件直接映射到内存(这里的内存指的是虚拟内存,并不是物理内存,后面说证明这一点)。通常,可以映射整个文件,如果文件比较大的话可以分段进行映射,只要指定文件的那个部分就可以。而且,与ByteBuffer十分类似,没有构造函数(你不可new MappedByteBuffer()来构造一个MappedByteBuffer),我们可以通过 java.nio.channels.FileChannel 的 map() 方法来获取 MappedByteBuffer 。其实说的通俗一点就是Map把文件的内容被映像到计算机虚拟内存的一块区域,这样就可以直接操作内存当中的数据而无需操作的时候每次都通过I/O去物理硬盘读取文件,所以效率上有很大的提升!

三种方式:

              FileChannel提供了map方法来把文件影射为内存映像文件: MappedByteBuffer map(int mode,long position,long size); 可以把文件的从position开始的size大小的区域映射为内存映像文件,mode指出了 可访问该内存映像文件的方式:READ_ONLY,

DBCP(DataBase connection pool),数据库连接池。是apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。 

  DBCP 实现

  dbcp 连接池

  class JdbcUtil

  {

  private static BasicDataSource bds;

  static{

  if(bds==null){

  bds= new BasicDatasource();

  }

  //分别设置数据库的连接参数

  bds.setDriverClass

  bds.url

  bds.user

  bds.root

  }

  public staitc Connection getConnection(){

  return bds.getConnection();

  }

  在spring中配置dbcp:

  beans.xml:

  <bean

  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

  <property name="locations">

  <value>classpath:jdbc.properties</value>

  </property>

  </bean>

  <bean id="dataSource" destroy-method="close"

  class="org.apache.commons.dbcp.BasicDataSource">

  <property name="driverClassName"value="${jdbc.driverClassName}"

Demo

  下一步:我给出一个读取IP记录的程序片断,此片断摘录自LumaQQ源文件edu.tsinghua.lumaqq.IPSeeker.java,如果你有兴趣,可以下载源代码详细看看。

 /**

  * 给定一个ip国家地区记录的偏移,返回一个IPLocation结构

  * @param offset 国家记录的起始偏移

  * @return IPLocation对象

  */

private IPLocation getIPLocation(long offset) {

  try {

   // 跳过4字节ip

   ipFile.seek(offset + 4);

   // 读取第一个字节判断是否标志字节

   byte b = ipFile.readByte();

   if(b == REDIRECT_MODE_1) {

    // 读取国家偏移

    long countryOffset = readLong3();

    // 跳转至偏移处

    ipFile.seek(countryOffset);

    // 再检查一次标志字节,因为这个时候这个地方仍然可能是个重定向

    b = ipFile.readByte();

    if(b == REDIRECT_MODE_2) {

     loc.country = readString(readLong3());

     ipFile.seek(countryOffset + 4);

    } else

     loc.country = readString(countryOffset);

    // 读取地区标志

loc.area = readArea(ipFile.getFilePointer());

   } else if(b == REDIRECT_MODE_2) {

    loc.country = readString(readLong3());

    loc.area =

设计的理由

  在我们继续去了解索引区的结构之前,我们先来了解一下为何记录区的结构要如此设计。我想你可能想到了答案:字符串重用。没错,在这种结构下,对于一个国家名和地区名,我只需要保存其一次就可以了。我们举例说明,为了表示方便,我们用小写字母代表IP记录,C表示国家名,A表示地区名:

有两条记录a(C1, A1), b(C2, A2),如果C1 = C2, A1 = A2,那么我们就可以使用图3显示的结构来实现重用

有三条记录a(C1, A1), b(C2, A2), c(C3, A3),如果C1 = C2, A2 = A3,现在我们想存储记录b,那么我们可以用图6的结构来实现重用

有两条记录a(C1, A1), b(C2, A2),如果C1 = C2,现在我们想存储记录b,那么我们可以采用模式2表示C2,用字符串表示A2

  你可以举出更多的情况,你也会发现在这种结构下,不同的字符串只需要存储一次。

了解索引区

  在"了解文件头"部分,我们说明了文件头实际上是两个指针,分别指向了第一条索引和最后一条索引的绝对偏移。如图8所示:

图8. 文件头指向索引区图示

  实在是很简单,不是吗?从文件头你就可以定位到索引区,然后你就可以开始搜索IP了!每条索引长度为7个字节,前4个字节是起始IP地址,后三个字节就指向了IP记录。这里有些概念需要说明一下,什么是起始IP,那

二. 了解记录区

  每条IP记录都由国家和地区名组成,国家地区在这里并不是太确切,因为可能会查出来“清华大学计算机系”之类的,这里清华大学就成了国家名了,所以这个国家地区名和IP数据库制作的时候有关系。所以记录的格式有点像QName,有一个全局部分和局部部分组成,我们这里还是沿用国家名和地区名的说法。

  于是我们想象着一条记录的格式应该是: [IP地址][国家名][地区名],当然,这个没有什么问题,但是这只是最简单的情况。很显然,国家名和地区名可能会有很多的重复,如果每条记录都保存一个完整的名称拷贝是非常不理想的,所以我们就需要重定向以节省空间。所以为了得到一个国家名或者地区名,我们就有了两个可能:第一就是直接的字符串表示的国家名,第二就是一个4字节的结构,第一个字节表明了重定向的模式,后面3个字节是国家名或者地区名的实际偏移位置。对于国家名来说,情况还可能更复杂些,因为这样的重定向最多可能有两次。

  那么什么是重定向模式?根据上面所说,一条记录的格式是[IP地址][国家记录][地区记录],如果国家记录是重定向的话,那么地区记录是有可能没有的,于是就有了两种情况,我管他叫做模式1和模式2。我们对这些格式的情况举图说明:

图2.

文章图片

摘要

  网络上的IP数据库以纯真版的最为流行,LumaQQ也采用了纯真版IP数据库做为IP查询功能的基础。不过关于其格式的文档却非常之少,后来终于在网上找到了一份文档,得以了解其内幕,不过那份文档寥寥数语,也是颇为耐心才读明白。在这里我重写一份,以此做为LumaQQ开发者文档的一部分,我想还是必要的。本文详细介绍了纯真IP数据库的格式,并且给出了一些Demo以供参考。

Luma, 清华大学

修改日期: 2005/01/14

Note: 在此感谢纯真IP数据库作者金狐和那唯一一份文档的作者。

修改历史:

2005-01-14 修改了原来一些表达不清和错误的地方

    自从有了IP数据库这种东西,QQ外挂的显示IP功能也随之而生,本人见识颇窄,是否还有其他应用不得而知,不过,IP数据库确实是个不错的东西。如今网络上最流行的IP数据库我想应该是纯真版的(说错了也不要扁我),迄今为止其IP记录条数已经接近30000,对于有些IP甚至能精确到楼层,不亦快哉。2004年4、5月间,正逢LumaQQ破土动工,为了加上这个人人都喜欢,但是好像人人都不知道为什么喜欢的显IP功能,我也采用了纯真版IP数据库,它的优点是记录多,查询速度快,它只用一个文件QQWry.dat就包含了所有记录,方便嵌入到其他程序中,也方便升级。

基本结构

  QQWry

定义

  在各种计算机体系结构中,对于字节等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方将无法进行正确的编/译码从而导致通信失败。  目前在各种体系的计算机中,通常采用big-endian和little-endian两种字节存储机制描述在多字节数中各个字节的存储顺序。

Endian的词源  据Jargon File记载,endian这个词来源于Jonathan Swift在1726年写的讽刺小说 "Gulliver's Travels"(《格利佛游记》)。该小说在描述Gulliver畅游小人国时碰到了如下的一个场景。在小人国里的小人因为非常小(身高6英寸)所以总是碰到一些意想不到的问题。有一次因为对水煮蛋该从大的一端(Big-End)剥开还是小的一端(Little-End)剥开

本文主要介绍Spring与Mybatis三种常用整合方法,需要的整合架包是mybatis-spring.jar,可通过链接

http://code.google.com/p/mybatis/下载到。

  1、采用数据映射器(MapperFactoryBean)的方式,不用写mybatis映射文件,采用注解方式提供相应的sql语句和输入参数。

  (1)Spring配置文件:

<!-- 引入jdbc配置文件 --> <context:property-placeholder location="jdbc.properties"/> <!--创建jdbc数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> <property name="initialSize" value="${initialSize}"/> <property name="maxActive" value="${maxActive}"/> <property name="maxIdle" value="${maxIdle}"/> <property name="minIdle" value="${minIdle}"/> </bean> <!-- 创建SqlSessionFactory,同时指定数据源--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean&q

      使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,已 经为我们提供了这样一个功能。

SELECT * FROM table   LIMIT [offset,] rows | rows OFFSET offset

      LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初 始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。

mysql> SELECT * FROM table LIMIT 5,10;  // 检索记录行 6-15

//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:

mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.

//如果只给定一个参数,它表示返回最大的记录行数目:

mysql> SELECT * FROM table LIMIT 5;     //检索前 5 个记录行

//换句话说,LIMIT n 等价于 LIMIT 0,n。

实例:

mysql> use sppeivan;

Database changed

mysql> select * from employee;

+------------+------------+--------+-------------+

| username   | password   | gender | cellphone   |

+------------+------------+--------+-----