• Cassandra:java客户端操作


    java客户端介绍

    Cassandra有众多的JAVA客户端,目前比较流程的都是不同公司开源的客户端,如:Netfix的astyanax,datastax的java-driver,hector,以及Spring Data for Apache Cassandra。

    image-20220316150337082

    本文使用datastax的java-driver作为连接cassandra的客户端。

    datastax的java-driver

    介绍

    是由DataStax公司,开源的用来操作Cassandra的工具包,官网:

    https://docs.datastax.com/en/landing_page/doc/landing_page/current.html

    在github的搜索页面点击 datastax/java-driver

    源码地址:

    https://github.com/datastax/java-driver

    在页面上可以看到使用java-driver的简单介绍,包含Maven依赖内容,环境兼容要求。

    可以看到需要jdk8或更版本,支持Cassandra2.1获取更高版本

    入门使用

    引入相关依赖:

            <!--cassandra 包-->
            <dependency>
                <groupId>com.datastax.cassandra</groupId>
                <artifactId>cassandra-driver-core</artifactId>
                <version>3.9.0</version>
            </dependency>
            <dependency>
                <groupId>com.datastax.cassandra</groupId>
                <artifactId>cassandra-driver-mapping</artifactId>
                <version>3.9.0</version>
            </dependency>
            <!--junit 测试-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
    

    键空间操作

    1.查询键空间

        Session session;
    
        @Before
        public void init() {
            String host = "192.168.1.43";
            int port = 9042;
    
            //连接服务端,获取会话
            Cluster cluster = Cluster.builder()
                    .addContactPoint(() -> new InetSocketAddress(host, port))
                    .build();
            session = cluster.connect();
        }
    
        /**
         * 查询键空间
         * @author wen.jie
         * @date 2022/3/16 15:07
         */
        @Test
        public void selectKeySpace() {
            List<KeyspaceMetadata> keyspaces =
                    session.getCluster().getMetadata().getKeyspaces();
            for (KeyspaceMetadata keyspace : keyspaces) {
                System.out.println(keyspace);
            }
        }
    

    image-20220316151346613

    2.创建键空间

    /**
     * 创建键空间
     * @author wen.jie
     * @date 2022/3/16 15:08
     */
        @Test
        public void createKeySpace() {
            //执行cql语句
            //session.execute("CREATE KEYSPACE school_test WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 3};");
    
            //面向对象方式
            HashMap<String, Object> map = new HashMap<>();
            map.put("class", "SimpleStrategy");
            map.put("replication_factor", 1);
            KeyspaceOptions opts = SchemaBuilder.createKeyspace("school_test")
                    .ifNotExists()
                    .with()
                    .replication(map);
            session.execute(opts);
        }
    

    效果:

    image-20220316151533984

    3.删除键空间

        @Test
        public void dropKeySpace() {
            DropKeyspace dropKeyspace = SchemaBuilder.dropKeyspace("school_test").ifExists();
            session.execute(dropKeyspace);
        }
    

    4.修改键空间

        @Test
        public void alterKeySpace() {
            HashMap<String, Object> map = new HashMap<>();
            map.put("class", "SimpleStrategy");
            map.put("replication_factor", 2);
            KeyspaceOptions options = SchemaBuilder.alterKeyspace("school")
                    .with().replication(map);
            session.execute(options);
        }
    

    表操作

    1.创建表

        @Test
        public void createTable() {
            Create create = SchemaBuilder.createTable("school", "students")
                    .addPartitionKey("id", DataType.bigint())
                    .addColumn("address", DataType.varchar())
                    .addColumn("name", DataType.varchar())
                    .addColumn("phone", DataType.CollectionType.list(DataType.varchar()))
                    .addColumn("interest", DataType.CollectionType.set(DataType.varchar()))
                    .addColumn("education", DataType.CollectionType.map(DataType.varchar(), DataType.varchar()))
                    .ifNotExists();
            session.execute(create);
        }
    

    image-20220316153237948

    2.修改表

        @Test
        public void alterTable() {
            SchemaStatement statement = SchemaBuilder.alterTable("school", "students")
                    .addColumn("email").type(DataType.text());
            session.execute(statement);
    
            SchemaStatement statement1 = SchemaBuilder.alterTable("school", "students")
                    .dropColumn("address");
            session.execute(statement1);
        }
    

    image-20220316153802915

    3.删除表

        @Test
        public void dropTable() {
            Drop drop = SchemaBuilder.dropTable("school", "students");
            session.execute(drop);
        }
    

    数据操作

    使用Mapper和Bean对象形式保存数据:

    @Data
    @Table(keyspace = "school", name = "student")
    public class Student implements Serializable {
        @PartitionKey //标识当前字段是分区键
        private Integer id;
        private String address;
        private Integer age;
        private Map<String, String> education;
        private Byte gender;
        private Set<String> interest;
        private String name;
        private List<String> phone;
    }
    

    测试插入数据

        /**
         * 使用Mapper和Bean对象形式保存数据
         * @author wen.jie
         * @date 2022/3/16 15:51
         */
        @Test
        public void insert() {
            Student student = new Student();
            student.setId(1012);
            student.setAddress("南京");
            student.setAge(17);
            student.setEducation(Collections.singletonMap("大学", "abc大学"));
            student.setGender((byte)1);
            student.setInterest(new HashSet<>(Arrays.asList("看书", "音乐")));
            student.setName("tom");
            student.setPhone(Arrays.asList("12222222222","13333333333"));
            Mapper<Student> mapper = new MappingManager(session).mapper(Student.class);
            mapper.save(student);
        }
    

    image-20220316155932528

    测试查询全部

        @Test
        public void findAll() {
            ResultSet resultSet = session.execute(QueryBuilder.select().from("school", "student"));
            Mapper<Student> mapper = new MappingManager(session).mapper(Student.class);
            List<Student> students = mapper.map(resultSet).all();
            for (Student student : students) {
                System.out.println(student);
            }
        }
    

    image-20220316160146856

    根据id查询

        @Test
        public void findById() {
            Select.Where where = QueryBuilder.select().from("school", "student").where(QueryBuilder.eq("id", 1012));
            ResultSet resultSet = session.execute(where);
            Mapper<Student> mapper = new MappingManager(session).mapper(Student.class);
            Student student = mapper.map(resultSet).one();
            System.out.println(student);
        }
    

    image-20220316160450412

    根据id删除

        @Test
        public void deleteById() {
            Mapper<Student> mapper = new MappingManager(session).mapper(Student.class);
            mapper.delete(1012);
        }
    

    image-20220316160622567

    索引操作

    创建索引

        @Test
        public void createIdx() {
            SchemaStatement statement = SchemaBuilder.createIndex("name_idx")
                    .onTable("school", "student")
                    .andColumn("name");
            session.execute(statement);
        }
    

    image-20220316161017941

    删除索引

        @Test
        public void dropIndex() {
            Drop drop = SchemaBuilder.dropIndex("school", "name_idx");
            session.execute(drop);
        }
    

    预编译操作

    cassandra提供了类似jdbc preparedstatement使用预编译占位符。官方文档链接如下:

    https://docs.datastax.com/en/developer/java-driver/3.0/manual/statements/prepared/

    基本原理:

    预编译statement的时候,Cassandra会解析query语句,缓存解析的结果并返回一个唯一的标志。当绑定并且执行预编译statement的时候,驱动只会发送这个标志,那么Cassandra就会跳过解析query语句的过程。

    应保证query语句只应该被预编译一次,缓存PreparedStatement 到我们的应用中(PreparedStatement 是线程安全的);如果我们对同一个query语句预编译了多次,那么驱动输出印警告日志;

    如果一个query语句只执行一次,那么预编译不会提供性能上的提高,反而会降低性能,因为是两次请求,那么此时可以考虑用 simple statement 来代替

    代码:

        @Test
        public void batchPrepare(){
            //先把语句预编译
            BatchStatement batch = new BatchStatement();
            PreparedStatement ps = session .prepare("INSERT INTO school.student (id,address,age,gender,name,interest, phone,education) VALUES (?,?,?,?,?,?,?,?)");
            //循环10次,构造不同的student对象
            for (int i = 0; i < 10; i++) {
                HashMap<String, String> education = new HashMap<>();
                education.put("小学", "中心第"+i+"小学");
                education.put("中学", "第"+i+"中学");
                HashSet<String> interest = new HashSet<>();
                interest.add("看书");
                interest.add("电影");
                List<String> phones = new ArrayList<>();
                phones.add("0"+i+"0-66666666");
                phones.add("1"+i+"666666666");
                Student student = new Student(
                        1013 + i,
                        "北京市朝阳区10" + i + "号",
                        21 + i,
                        education,
                        (byte)1,
                        interest,
                        "学生"+i,
                        phones);
                BoundStatement bs = ps.bind(student.getId(),
                        student.getAddress(),
                        student.getAge(),
                        student.getGender(),
                        student.getName(),
                        student.getInterest(),
                        student.getPhone(),
                        student.getEducation());
                batch.add(bs);
            }
            session.execute(batch);
            batch.clear();
        }
    

    效果:

    image-20220316162411363

  • 相关阅读:
    如何利用 JConsole观察分析Java程序的运行,进行排错调优
    【解决】网站运行一段时间后就无法访问,重启Tomcat才能恢复
    不允许一个用户使用一个以上用户名与一个服务器或共享
    SVN升级到1.8后 Upgrade working copy
    Windows Server 2012 R2 创建AD域
    JTA 深度历险
    svn merge error must be ancestrally related to,trunk merge branch报错
    OutputStream-InputStream-FileOutputStream-FileInputStream-BufferedOutputStream-BufferedInputStream-四种复制方式-单层文件夹复制
    SVN提交时响应很慢,我是这样解决的。
    docker学习6-docker-compose容器集群编排
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/16013322.html
Copyright © 2020-2023  润新知