levelDB 入门操作实例

本文采用Java语言版本的levelDB,在springboot项目下或者maven项目中进行测试。

0,快捷键复习

根据类名查找类 ctrl+shift+n或者在面板右上角点击搜索图标
查看接口的实现 ctrl+alt+左键

1,引入依赖

    <dependency>
            <groupId>org.iq80.leveldb</groupId>
            <artifactId>leveldb</artifactId>
            <version>0.12</version>
        </dependency>
        <dependency>
            <groupId>org.iq80.leveldb</groupId>
            <artifactId>leveldb-api</artifactId>
            <version>0.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2,定义一些常量

    //存储路径,默认是项目路径下
    private static final String PATH = "leveldb";
    private static final File FILE = new File(PATH);
    //编码集
    private static final Charset CHARSET = Charset.forName("UTF-8");

3,测试写入和读取操作

   /**
     * put操作测试
     */
    @Test
    public void putTest() {
        DBFactory factory = new Iq80DBFactory();
        // 默认如果没有则创建
        Options options = new Options();
        File file = new File(PATH);
        //sync写数据后强制写入磁盘
        WriteOptions writeOptions=new WriteOptions().sync(true);
        DB db = null;
        try {
            db = factory.open(file, options);
            byte[] keyByte1 = "key-01".getBytes(CHARSET);
            byte[] keyByte2 = "key-02".getBytes(CHARSET);
            // 会写入磁盘中
            db.put(keyByte1, "value-01".getBytes(CHARSET),writeOptions);
            db.put(keyByte2, "value-02".getBytes(CHARSET));

            System.out.println(asString(db.get(keyByte1)));
            System.out.println(asString(db.get(keyByte2)));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 写操作  WriteOptions可以对写操作进行一些定义,ReadOptions同样
     */
    @Test
    public void writeOptionsTest() {
        DBFactory factory = new Iq80DBFactory();
        Options options = new Options();
        DB db = null;
        try {
            db = factory.open(FILE, options);
            WriteOptions writeOptions = new WriteOptions().sync(true);	// 线程安全
            db.put("key-08".getBytes(CHARSET), "value-08".getBytes(CHARSET), writeOptions);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

项目目录中多了一些文件,分别是日志文件记录操作信息,manifest文件记录存储状态信息,current记录当前生效的manifest文件名。
在这里插入图片描述

4,从快照中读取

在上一步之后,能够从磁盘中间中的快照中读取数据。如果在生成快照之后进行写操作,快照读不会受到影响。

 /**
     * 测试从快照中读取数据
     */
    @Test
    public void readFromSnapshotTest() {
        DBFactory factory = new Iq80DBFactory();
        File file = new File(PATH);
        Options options = new Options();
        DB db = null;
        try {
            db = factory.open(file, options);
            // 读取当前快照,重启服务仍能读取,说明快照持久化至磁盘,
            Snapshot snapshot = db.getSnapshot();
            // 读取操作
            ReadOptions readOptions = new ReadOptions();
            //当读取一大块数据时,可以使用fillCache = false来禁止缓存被覆盖。
            readOptions.fillCache(false);
            // 默认snapshot为当前
            readOptions.snapshot(snapshot);
            DBIterator it = db.iterator(readOptions);
            //迭代访问
            while (it.hasNext()) {
                Map.Entry<byte[], byte[]> entry = it.next();
                String key = new String(entry.getKey(), CHARSET);
                String value = new String(entry.getValue(), CHARSET);
                System.out.println("key: " + key + " value: " + value);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
     /**
     * 生成快照后写操作不影响快照读取
     */
    @Test
    public void snapshotTest() {
        DBFactory factory = new Iq80DBFactory();
        Options options = new Options();
        DB db = null;
        try {
            db = factory.open(FILE, options);
            db.put("key-04".getBytes(CHARSET), "value-04".getBytes(CHARSET));
            // 只能之前到getSnapshot之前put的值,之后的无法获取,即读取期间数据的变更
            Snapshot snapshot = db.getSnapshot();
            db.put("key-05".getBytes(CHARSET), "value-05".getBytes(CHARSET));
            ReadOptions readOptions = new ReadOptions();
            readOptions.fillCache(false);
            readOptions.snapshot(snapshot);
          //可以从数据库中读取,但是快照遍历时没有
            byte[] res=db.get("key-05".getBytes(CHARSET));          
            System.out.println("From the database  "+new String(res,CHARSET));
            DBIterator it = db.iterator(readOptions);
            while (it.hasNext()) {
                Map.Entry<byte[],byte[]> entry =  it.next();
                String key = new String(entry.getKey(), CHARSET);
                String value = new String(entry.getValue(), CHARSET);
                System.out.println("key: " + key + " value: " + value);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

5,删除操作

删除操作最终转化put操作,只是将key-value中的value置空。
如下图所示,在底层会对value进行判断,分别调用不同方法,但是到最后都是memtable.add(),只是参数不同。
在这里插入图片描述
在这里插入图片描述

@Test
    public void deleteTest() {
        DBFactory factory = new Iq80DBFactory();
        Options options = new Options();
        DB db = null;
        try {
            db = factory.open(FILE, options);
            // 存在会删除,之后查询不出
            db.delete("key-02".getBytes(CHARSET));
            // 不存在不会报错
            db.delete("key02".getBytes(CHARSET));

            Snapshot snapshot = db.getSnapshot();
            ReadOptions readOptions = new ReadOptions();
            readOptions.fillCache(false);
            readOptions.snapshot(snapshot);

            DBIterator it = db.iterator(readOptions);
            while (it.hasNext()) {
                Map.Entry<byte[], byte[]> entry = (Map.Entry<byte[], byte[]>) it
                        .next();
                String key = new String(entry.getKey(), CHARSET);
                String value = new String(entry.getValue(), CHARSET);
                System.out.println("key: " + key + " value: " + value);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

6,批量操作

利用writeBatch可以将更新操作和删除操作作为一个整体批量执行。

 /**
     * 批量写和删除
     */
    @Test
    public void writeBatchDeleteTest() {
        DBFactory factory = Iq80DBFactory.factory;
        Options options = new Options();
        DB db = null;
        try {
            db = factory.open(FILE, options);
            WriteBatch writeBatch = db.createWriteBatch();
            writeBatch.put("key-10".getBytes(CHARSET), "value-10".getBytes(CHARSET));
            writeBatch.put("key-11".getBytes(CHARSET), "value-11".getBytes(CHARSET));
            // 会将key-01的value置为""
            writeBatch.delete("key-01".getBytes(CHARSET));
            db.write(writeBatch);
            writeBatch.close();
            DBIterator it = db.iterator();
            while (it.hasNext()) {
                Map.Entry<byte[], byte[]> entry = (Map.Entry<byte[], byte[]>) it
                        .next();
                String key = new String(entry.getKey(), CHARSET);
                String value = new String(entry.getValue(), CHARSET);
                System.out.println("key: " + key + " value: " + value);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

7,对象的写入和读取

对象的写入和读取,与普通数据的区别在于对象需要实现序列化接口,并在写入和读取后进行序列化和反序列化。

/**
     * 对象的写入测试
     */
    @Test
    public void writeObject() {
        Options options = new Options();
        DBFactory factory = Iq80DBFactory.factory;
        DB db = null;
        try {
            db = factory.open(FILE, options);
            User user = new User();
            user.setName("admin");
            user.setSex("男");
            WriteOptions writeOptions = new WriteOptions();
            writeOptions.snapshot(true);

            ByteArrayOutputStream baos = new ByteArrayOutputStream(); //byte[]输出流
            ObjectOutputStream oos = new ObjectOutputStream(baos); //包装流,对象输出到输出流对象中
            oos.writeObject(user);  //写对象到输出流

            db.put(user.getName().getBytes(CHARSET), baos.toByteArray()); //写入db时要转化为(byte[],byte[])形式
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
    *  对象读取测试
    */
    @Test
    public void readObject() {
        Options options = new Options();
        DBFactory factory = Iq80DBFactory.factory;
        DB db = null;
        try {
            db = factory.open(FILE, options);
            byte[] valueByte = db.get("admin".getBytes(CHARSET)); //从数据库中读出byte[]
            ByteArrayInputStream bais = new ByteArrayInputStream(valueByte);//输入流对象读取结果
            ObjectInputStream ois = new ObjectInputStream(bais);//写对象流包装
            User user = (User) ois.readObject();//获得对象
            System.out.println(user);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

参考资料
博客
levelDB手册

发布了47 篇原创文章 · 获赞 1 · 访问量 1576

猜你喜欢

转载自blog.csdn.net/chinamen1/article/details/105008916