博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Cassandra-java操作——基本操作
阅读量:4096 次
发布时间:2019-05-25

本文共 8962 字,大约阅读时间需要 29 分钟。

  接着上篇博客,我们来谈谈java操作cassandra; 上篇博客的环境:jdk1.7 + python2.7.10 + cassandra2.2.8; 由于2.2.8没有对应的驱动文档,那么我们就用3.0的驱动文档,而驱动则用2.1.10.3版本;

  驱动文档:

一、驱动下载

老规矩,创建maven工程,让maven来维护我们的jar,maven最重要的pom文件内容如下:

4.0.0
com.huawei
cassandra
0.0.1-SNAPSHOT
jar
cassandra
http://maven.apache.org
UTF-8
com.datastax.cassandra
cassandra-driver-core
2.1.10.3

二、session获取

我们先来看看官方给的Quick start案例

Cluster cluster = null;        try {            cluster = Cluster.builder()                                                    // (1)                    .addContactPoint("127.0.0.1")                                 // cassandra服务器ip                    .withCredentials("admin", "admin")                                     // 若没有启用账号认证,此处可以去掉                    .build();            Session session = cluster.connect();                                           // (2)            ResultSet rs = session.execute("select release_version from system.local");    // (3)            Row row = rs.one();            System.out.println(row.getString("release_version"));                          // (4)        } finally {            if (cluster != null) cluster.close();                                          // (5)        }

我们来看看代码中的(1) ~ (5)分别表示或者代表什么

(1):Cluster对象是驱动程序的主入口点,它保存着真实Cassandra集群的状态(尤其是元数据);Cluster是线程安全的,一个Cassandra集群创建一个Cluster的单例,整个应用用这一个单例即可

(2):Session用来执行查询的,而且它也是线程安全的,同样也应该重复利用

(3):利用execute来发送一个查询到Cassandra,execute返回一个Resultset(结果集),这个结果集就是必要的列的行集合(二维表,行是满足条件的记录,列是我们关注的某些字段)

(4):从row中提取数据

(5):当任务完成后,关闭cluster,关闭cluster的同时将会关闭它创建的全部session;这一步很重要,它会释放潜在的资源(TCP连接、线程池等),在真实的应用中,我们应该在应用关闭(或应用卸载)的时候关闭cluster

如若大家有jdbc开发的经验,就会发现,上述代码似曾相识,上述代码中的session就相当于jdbc中的connection,是整个数据库操作的基础,那么我们将session的获取单独抽出来

 
View Code

拿到session了,那么请随意操作Cassandra吧!

三、cassandra基本操作

1、  创建表

在mycas下创建表student

use mycas;create table student(    id int,    address text,    name text,    age int,    height int,    primary key(id,address,name));insert into student(id,address,name,age,height) values(1,'guangdong','lixiao',32,172);

2、  session直接执行cql

  和jdbc类似,关键是cql的拼接,下例是插入一条记录,删、改、查和这类似,不一一列举了

    // 字符串注意单引号'        String cql = "insert into mycas.student(id,address,name,age,height) values("                 + student.getId() + ",'" + student.getAddress() + "','" + student.getName()                + "'," + student.getAge() + "," + student.getHeight() + ");";        System.out.println(cql);        session.execute(cql);

3、  Querybuilder

  利用Querybuilder可以减轻cql的拼接,sql语句的拼接由驱动完成

  查询一个student:

@Override    public Student getStudentByKeys(int id, String address, String name)    {        Student student = null;        ResultSet rs = session.execute(                QueryBuilder.select("id", "address", "name", "age", "height")                .from("mycas", "student")                .where(QueryBuilder.eq("id", id))                .and(QueryBuilder.eq("address", address))                .and(QueryBuilder.eq("name", name)));        Iterator
rsIterator = rs.iterator(); if (rsIterator.hasNext()) { Row row = rsIterator.next(); student = new Student(); student.setAddress(row.getString("address")); student.setAge(row.getInt("age")); student.setHeight(row.getInt("height")); student.setId(row.getInt("id")); student.setName(row.getString("name")); } return student; }

  保存一个student:

  @Override    public void saveStudent(Student student)    {        session.execute(                QueryBuilder.insertInto("mycas", "student")                .values(new String[]{"id", "address", "name", "age", "height"},                        new Object[]{student.getId(), student.getAddress(),                             student.getName(), student.getAge(), student.getHeight()}));    }

  修改一个student:

@Override    public void updateStudent(Student student)    {        session.execute(                QueryBuilder.update("mycas", "student")                .with(QueryBuilder.set("age", student.getAge()))                .and(QueryBuilder.set("height", student.getHeight()))                .where(QueryBuilder.eq("id", student.getId()))                .and(QueryBuilder.eq("address", student.getAddress()))                .and(QueryBuilder.eq("name", student.getName())));    }

  删除一个student:

@Override    public void removeStudent(int id, String address, String name)    {        session.execute(QueryBuilder.delete()                .from("mycas", "student")                .where(QueryBuilder.eq("id", id))                .and(QueryBuilder.eq("address", address))                .and(QueryBuilder.eq("name", name)));    }

  注意:驱动版本不同,Querybuilder的用法有些许不同,有些版本的某些方法变成非静态的了!

4、  类似jdbc那样使用预编译占位符

  

  预编译的原理是怎样的了,上面的链接是驱动官方的解释,我来谈谈我的理解

  当我们预编译statement的时候,Cassandra会解析query语句,缓存解析的结果并返回一个唯一的标志(PreparedStatement对象保持着这个标志的内部引用,就相当于通过标志可以获取到query语句预编译后的内容):

   当你绑定并且执行预编译statement的时候,驱动只会发送这个标志,那么Cassandra就会跳过解析query语句的过程:

  所以,我们应该保证query语句只应该被预编译一次,缓存PreparedStatement 到我们的应用中(PreparedStatement 是线程安全的);如果我们对同一个query语句预编译了多次,那么驱动会打印警告日志;如果一个query语句只执行一次,那么预编译不会提供性能上的提高,反而会降低性能,因为它是两个来回(结合上面两张图),那么此时可以考虑用  来代替

  和jdbc的预编译非常类似,我们来看看实际代码

  静态cql

  private static final String GET_STUDENT = "select id,address,name,age,height from mycas.student where id=? and address=? and name=?;";    private static final String SAVE_STUDENT = "insert into mycas.student(id,address,name,age,height) values(?,?,?,?,?);";    private static final String UPDATE_STUDENT = "update mycas.student set age=?, height=? where id=? and address=? and name=?;";    private static final String REMOVE_STUDENT = "delete from mycas.student where id=? and address=? and name=?;";

  查询一个student

     Student student = null;        PreparedStatement prepareStatement = session.prepare(GET_STUDENT);        BoundStatement bindStatement = new BoundStatement(prepareStatement).bind(id, address, name);        ResultSet rs = session.execute(bindStatement);        Iterator
rsIterator = rs.iterator(); if (rsIterator.hasNext()) { Row row = rsIterator.next(); student = new Student(); student.setAddress(row.getString("address")); student.setAge(row.getInt("age")); student.setHeight(row.getInt("height")); student.setId(row.getInt("id")); student.setName(row.getString("name")); } return student;

  保存一个student

PreparedStatement prepareStatement = session.prepare(SAVE_STUDENT);        BoundStatement bindStatement = new BoundStatement(prepareStatement)            .bind(student.getId(), student.getAddress(), student.getName(), student.getAge(), student.getHeight());        session.execute(bindStatement);

  修改一个student

     PreparedStatement prepareStatement = session.prepare(UPDATE_STUDENT);        BoundStatement bindStatement = new BoundStatement(prepareStatement)            .bind(student.getAge(), student.getHeight(), student.getId(), student.getAddress(), student.getName());        session.execute(bindStatement);

  删除一个student

     PreparedStatement prepareStatement = session.prepare(REMOVE_STUDENT);        BoundStatement bindStatement = new BoundStatement(prepareStatement)            .bind(id, address, name);        session.execute(bindStatement);

5、  批量batch

public static void batch()    {        Session session = SessionRepository.getSession();        BoundStatement insertBind1 = new BoundStatement(                session.prepare("insert into mycas.student(id,address,name,age,height) values(?,?,?,?,?);"))                       .bind(3, "guangxi", "huangfeihong", 67, 175);                BoundStatement insertBind2 = new BoundStatement(                session.prepare("insert into mycas.student(id,address,name,age,height) values(?,?,?,?,?);"))                       .bind(4, "hunan", "youzhibing", 26, 160);                BoundStatement updateBind = new BoundStatement(                session.prepare("update mycas.student set age=?, height=? where id=? and address=? and name=?;"))                       .bind(72, 173, 3, "guangxi", "huangfeihong");                BoundStatement deleteBind = new BoundStatement(                session.prepare("delete from mycas.student where id=? and address=? and name=?;"))                       .bind(4, "hunan", "youzhibing");                BatchStatement batchStatement = new BatchStatement();        batchStatement.add(insertBind1);        batchStatement.add(insertBind2);        batchStatement.add(updateBind);        batchStatement.add(deleteBind);        session.execute(batchStatement);    }

四、参考

转载地址:http://cklii.baihongyu.com/

你可能感兴趣的文章
4 岁小女孩给 Linux 内核贡献提交
查看>>
推荐几个私藏很久的技术公众号给大家
查看>>
20 个 2020 年软件开发趋势预测
查看>>
王垠受邀面试阿里 P9,被 P10 面跪后网上怒发文,惨打 325 的 P10 赵海平回应了!...
查看>>
Python 趣味打怪:147 段简单代码助你从入门到大师
查看>>
卧槽!小姐姐用动画图解 Git 命令,这也太秀了吧?!
查看>>
厉害了!Python 编辑器界的神器 Jupyter ,推出官方可视化 Debug 工具!
查看>>
卧槽!Java 虚拟机竟然还有这些性能调优技巧...
查看>>
听说玩这些游戏能提升编程能力?
查看>>
7 年工作经验,面试官竟然还让我写算法题???
查看>>
被 Zoom 逼疯的歪果仁,造出了视频会议机器人,同事已笑疯丨开源
查看>>
上古语言从入门到精通:COBOL 教程登上 GitHub 热榜
查看>>
再见,Eclipse...
查看>>
超全汇总!B 站上有哪些值得学习的 AI 课程...
查看>>
如果你还不了解 RTC,那我强烈建议你看看这个!
查看>>
神器面世:让你快速在 iOS 设备上安装 Windows、Linux 等操作系统!
查看>>
沙雕程序员在无聊的时候,都搞出了哪些好玩的小玩意...
查看>>
太赞了!GitHub 标星 2.4k+,《可解释机器学习》中文版正式开放!
查看>>
程序员用 AI 修复百年前的老北京视频后,火了!
查看>>
漫话:为什么你下载小电影的时候进度总是卡在 99% 就不动了?
查看>>