cassandra

在博客文章《从Java连接到Cassandra》中,我提到了用Java实现的Cassandra Java开发人员的一个优势是能够创建自定义Cassandra数据类型。 在这篇文章中,我将详细介绍如何执行此操作。

Cassandra具有许多内置数据类型,但是在某些情况下可能需要添加自定义类型。 通过扩展org.apache.cassandra.db.marshal.AbstractType类,可以在Java中实现Cassandra定制数据类型。 扩展此方法的类必须最终实现具有以下签名的三个方法:

public ByteBuffer fromString(final String) throws MarshalException
public TypeSerializer getSerializer()
public int compare(Object, Object)

下一个代码清单显示了本文的AbstractType示例实现。

UnitedStatesState.java –扩展AbstractType

package dustin.examples.cassandra.cqltypes;import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.serializers.MarshalException;
import org.apache.cassandra.serializers.TypeSerializer;import java.nio.ByteBuffer;/*** Representation of a state in the United States that* can be persisted to Cassandra database.*/
public class UnitedStatesState extends AbstractType
{public static final UnitedStatesState instance = new UnitedStatesState();@Overridepublic ByteBuffer fromString(final String stateName) throws MarshalException{return getStateAbbreviationAsByteBuffer(stateName);}@Overridepublic TypeSerializer getSerializer(){return UnitedStatesStateSerializer.instance;}@Overridepublic int compare(Object o1, Object o2){if (o1 == null && o2 == null){return 0;}else if (o1 == null){return 1;}else if (o2 == null){return -1;}else{return o1.toString().compareTo(o2.toString());}}/*** Provide standard two-letter abbreviation for United States* state whose state name is provided.** @param stateName Name of state whose abbreviation is desired.* @return State's abbreviation as a ByteBuffer; will return "UK"*    if provided state name is unexpected value.*/private ByteBuffer getStateAbbreviationAsByteBuffer(final String stateName){final String upperCaseStateName = stateName != null ? stateName.toUpperCase().replace(" ", "_") : "UNKNOWN";String abbreviation;try{abbreviation =  upperCaseStateName.length() == 2? State.fromAbbreviation(upperCaseStateName).getStateAbbreviation(): State.valueOf(upperCaseStateName).getStateAbbreviation();}catch (Exception exception){abbreviation = State.UNKNOWN.getStateAbbreviation();}return ByteBuffer.wrap(abbreviation.getBytes());}
}

上面的类列表引用了State枚举,如下所示。

State.java

package dustin.examples.cassandra.cqltypes;/*** Representation of state in the United States.*/
public enum State
{ALABAMA("Alabama", "AL"),ALASKA("Alaska", "AK"),ARIZONA("Arizona", "AZ"),ARKANSAS("Arkansas", "AR"),CALIFORNIA("California", "CA"),COLORADO("Colorado", "CO"),CONNECTICUT("Connecticut", "CT"),DELAWARE("Delaware", "DE"),DISTRICT_OF_COLUMBIA("District of Columbia", "DC"),FLORIDA("Florida", "FL"),GEORGIA("Georgia", "GA"),HAWAII("Hawaii", "HI"),IDAHO("Idaho", "ID"),ILLINOIS("Illinois", "IL"),INDIANA("Indiana", "IN"),IOWA("Iowa", "IA"),KANSAS("Kansas", "KS"),LOUISIANA("Louisiana", "LA"),MAINE("Maine", "ME"),MARYLAND("Maryland", "MD"),MASSACHUSETTS("Massachusetts", "MA"),MICHIGAN("Michigan", "MI"),MINNESOTA("Minnesota", "MN"),MISSISSIPPI("Mississippi", "MS"),MISSOURI("Missouri", "MO"),MONTANA("Montana", "MT"),NEBRASKA("Nebraska", "NE"),NEVADA("Nevada", "NV"),NEW_HAMPSHIRE("New Hampshire", "NH"),NEW_JERSEY("New Jersey", "NJ"),NEW_MEXICO("New Mexico", "NM"),NORTH_CAROLINA("North Carolina", "NC"),NORTH_DAKOTA("North Dakota", "ND"),NEW_YORK("New York", "NY"),OHIO("Ohio", "OH"),OKLAHOMA("Oklahoma", "OK"),OREGON("Oregon", "OR"),PENNSYLVANIA("Pennsylvania", "PA"),RHODE_ISLAND("Rhode Island", "RI"),SOUTH_CAROLINA("South Carolina", "SC"),SOUTH_DAKOTA("South Dakota", "SD"),TENNESSEE("Tennessee", "TN"),TEXAS("Texas", "TX"),UTAH("Utah", "UT"),VERMONT("Vermont", "VT"),VIRGINIA("Virginia", "VA"),WASHINGTON("Washington", "WA"),WEST_VIRGINIA("West Virginia", "WV"),WISCONSIN("Wisconsin", "WI"),WYOMING("Wyoming", "WY"),UNKNOWN("Unknown", "UK");private String stateName;private String stateAbbreviation;State(final String newStateName, final String newStateAbbreviation){this.stateName = newStateName;this.stateAbbreviation = newStateAbbreviation;}public String getStateName(){return this.stateName;}public String getStateAbbreviation(){return this.stateAbbreviation;}public static State fromAbbreviation(final String candidateAbbreviation){State match = UNKNOWN;if (candidateAbbreviation != null && candidateAbbreviation.length() == 2){final String upperAbbreviation = candidateAbbreviation.toUpperCase();for (final State state : State.values()){if (state.stateAbbreviation.equals(upperAbbreviation)){match = state;}}}return match;}
}

我们还可以提供由上面显示的getSerializer()方法返回的TypeSerializer接口的实现。 通常,通过扩展org.apache.cassandra.serializers package中Cassandra提供的TypeSerializer的众多现有实现之一,通常最容易编写实现TypeSerializer类。 在我的示例中,我的自定义序列化程序扩展了AbstractTextSerializer并且我需要添加的唯一方法是签名public void validate(final ByteBuffer bytes) throws MarshalException 。 我的两个自定义类都需要通过静态访问提供对自身实例的引用。 这是通过AbstractTypeSerializer扩展实现TypeSerializer的类:

UnitedStatesStateSerializer.java –实现TypeSerializer

package dustin.examples.cassandra.cqltypes;import org.apache.cassandra.serializers.AbstractTextSerializer;
import org.apache.cassandra.serializers.MarshalException;import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;/*** Serializer for UnitedStatesState.*/
public class UnitedStatesStateSerializer extends AbstractTextSerializer
{public static final UnitedStatesStateSerializer instance = new UnitedStatesStateSerializer();private UnitedStatesStateSerializer(){super(StandardCharsets.UTF_8);}/*** Validates provided ByteBuffer contents to ensure they can* be modeled in the UnitedStatesState Cassandra/CQL data type.* This allows for a full state name to be specified or for its* two-digit abbreviation to be specified and either is considered* valid.** @param bytes ByteBuffer whose contents are to be validated.* @throws MarshalException Thrown if provided data is invalid.*/@Overridepublic void validate(final ByteBuffer bytes) throws MarshalException{try{final String stringFormat = new String(bytes.array()).toUpperCase();final State state =  stringFormat.length() == 2? State.fromAbbreviation(stringFormat): State.valueOf(stringFormat);}catch (Exception exception){throw new MarshalException("Invalid model cannot be marshaled as UnitedStatesState.");}}
}

编写了用于创建自定义CQL数据类型的类后,需要将它们编译成.class文件并存档在JAR文件中。 此过程(使用javac -cp "C:\Program Files\DataStax Community\apache-cassandra\lib\*" -sourcepath src -d classes src\dustin\examples\cassandra\cqltypes\*.java ,并将生成的文件存档.class以下屏幕快照中显示了将.class文件放入名为jar cvf CustomCqlTypes.jar *名为CustomCqlTypes.jar的JAR中。

带有自定义CQL类型类的类定义的JAR需要放置在Cassandra安装的lib目录中,如下一个屏幕快照所示。

通过在Cassandra安装目录的lib目录中包含自定义CQL数据类型类实现的JAR,应该重新启动Cassandra,以便它能够“看到”这些自定义数据类型定义。

下一个代码清单显示了一个Cassandra查询语言(CQL)语句,用于使用新的自定义类型dustin.examples.cassandra.cqltypes.UnitedStatesState创建表。

createAddress.cql

CREATE TABLE us_address
(id uuid,street1 text,street2 text,city text,state 'dustin.examples.cassandra.cqltypes.UnitedStatesState',zipcode text,PRIMARY KEY(id)
);

下一个屏幕快照通过描述cqlsh中创建的表来演示运行上述createAddress.cql代码的结果。

上面的屏幕快照演示了自定义类型dustin.examples.cassandra.cqltypes.UnitedStatesStateus_address表的state列的类型。

可以使用常规INSERT将新行添加到US_ADDRESS表。 例如,以下屏幕快照演示了使用INSERT INTO us_address (id, street1, street2, city, state, zipcode) VALUES (blobAsUuid(timeuuidAsBlob(now())), '350 Fifth Avenue', '', 'New York', 'New York', '10118');命令INSERT INTO us_address (id, street1, street2, city, state, zipcode) VALUES (blobAsUuid(timeuuidAsBlob(now())), '350 Fifth Avenue', '', 'New York', 'New York', '10118');

请注意,虽然INSERT语句为该州插入了“纽约”,但它存储为“ NY”。

如果我在cqlsh中使用缩写以( INSERT INTO us_address (id, street1, street2, city, state, zipcode) VALUES (blobAsUuid(timeuuidAsBlob(now())), '350 Fifth Avenue', '', 'New York', 'NY', '10118');INSERT INTO us_address (id, street1, street2, city, state, zipcode) VALUES (blobAsUuid(timeuuidAsBlob(now())), '350 Fifth Avenue', '', 'New York', 'NY', '10118');开头的缩写在cqlsh中运行INSERT语句INSERT INTO us_address (id, street1, street2, city, state, zipcode) VALUES (blobAsUuid(timeuuidAsBlob(now())), '350 Fifth Avenue', '', 'New York', 'NY', '10118'); ),它仍然可以正常工作,如下图所示。

在我的示例中,无效状态不会阻止INSERT的发生,而是将状态持久保存为“ UK”(对于未知状态)[请参见UnitedStatesState.getStateAbbreviationAsByteBuffer(String)的实现UnitedStatesState.getStateAbbreviationAsByteBuffer(String)

证明为什么要在Java中实现自定义CQL数据类型的第一个优点就是,可以采用与关系数据库中的检查约束所提供的行为类似的行为。 例如,在这篇文章中,我的示例确保为新行输入的任何州列都是美国的五十个州,哥伦比亚特区或未知的“英国”之一。 不能在该列的值中插入其他值。

自定义数据类型的另一个优点是能够将数据整理成首选格式。 在此示例中,我将每个州名称都更改为大写的两位数缩写。 在其他情况下,我可能想要始终以大写形式存储或始终以小写形式存储或将有限的字符串集映射为数值。 定制的CQL数据类型允许在Cassandra数据库中进行定制的验证和值的表示。

结论

这篇文章介绍了如何在Cassandra中实现自定义CQL数据类型。 随着我更多地使用这个概念并尝试不同的方法,我希望就我所做的一些更细微的观察撰写另一篇博客文章。 如本文所显示,编写和使用自定义CQL数据类型非常容易,特别是对于Java开发人员而言。

翻译自: https://www.javacodegeeks.com/2014/07/custom-cassandra-data-types.html

cassandra

cassandra_自定义Cassandra数据类型相关推荐

  1. 自定义Cassandra数据类型

    在博客文章< 从Java连接到Cassandra>中 ,我提到了用Java 实现的Cassandra Java开发人员的一个优势是能够创建自定义 Cassandra数据类型 . 在这篇文章 ...

  2. springboot控制接口返回的字段_SpringBoot实战:SpringBoot之Rest Full接口自定义返回数据类型(ResponseBodyAdvice)...

    我们在日常开发的过程中,经常会要求统一返回数据格式.如要求统一访问格式为 { "success": 请求是否成功, "message": 请求消息, " ...

  3. ROS中自定义复杂数据类型

    ROS中自定义复杂数据类型 先说一下需求,想要服务的请求数据为一个point(x,y,z)的数组.具体的形式表示如: [point1,point2,...] geometry_msgs::Point ...

  4. Redis数据实战之GEO在LBS中应用与自定义新数据类型

    Redis数据实战之GEO在LBS中应用与自定义新数据类型 引言 面向 LBS 应用的 GEO 数据类型 GEO 的底层结构 GeoHash 的编码方法 如何操作 GEO 类型 如何自定义数据类型 R ...

  5. c++ 哪些自定义的数据类型

    http://www.cnblogs.com/ShaneZhang/archive/2013/06/21/3147648.html 这些数据类型是 C99 中定义的,具体定义在:/usr/includ ...

  6. Mapreduce自定义数据类型

    Hadoop自带的数据类型: Intwritable,LongWritable,Text,xxWritable. 某些情况下:使用自定义的数据类型方便一些(类似java中的pojo). 实现: 实现w ...

  7. 用类模板实现容器存储自定义数据类型(类似于STL里面的vector)

    上一节里面已经提到了,用类模板存储自定义的数据类型,如Teacher类型时,需要重载Teacher类的拷贝构造函数,"="操作符,"<<"操作符,特 ...

  8. 自学C++——自定义数据类型

    一,typedef声明 在编写程序时,除了可以使用内置的基本数据类型名和自定义的数据类型名外,还可以为一个已有的数据类型另外命名. 类型命名的语法形式: typedef 已有类型名  新类型名表: 其 ...

  9. SQL Server 创建自定义数据类型

    创建自定义数据类型 作用 在指定的数据库,创建自定义的数据类型. 格式 CREATE TYPE [dbo].[名称] FROM [类型] NOT NULL 例子 CREATE TYPE [dbo].[ ...

最新文章

  1. 谷歌又一部门震荡:半年2名副总出走,开发团队只剩一半
  2. JZOJ 1220. Pla
  3. Vue项目代码改进(二)—— element-UI的消息显示时间修改
  4. Java集合(1)--集合概述
  5. etl报表开发是什么意思_中间表是什么?和报表有什么关系?会带来怎样的问题?又如何解决?...
  6. ASP.NET性能监控和优化入门
  7. 聊聊Spring Data Auditable接口的变化
  8. 【设计模式专题】Singleton
  9. 计算机txt公式,完整word版本积分公式
  10. javascript百度地图使用(根据地名定位、根据经纬度定位)
  11. java insert方法_Java StringBuilder insert()方法
  12. 中国域名8大玩家传奇故事
  13. 论文阅读:A Survey on Deep Hashing Methods 综述:深度哈希方法
  14. 用Python分析北京二手房房价
  15. 【 第一章:初识 ts】
  16. python输入一个浮点数、输出其整数部分和小数部分_输入一个浮点数,并输出该数的整数部分和小数部分...
  17. word 加载MathType打开时显示“安全警告,宏已被禁用”解决办法
  18. Stm32 学习笔记(1)我所使用的板子
  19. ubuntu16.04外接显示器扩展屏幕设置
  20. java.net.UnknownHostException 异常处理(个人案例)

热门文章

  1. SyntaxError: Unexpected token T in JSON at position 0 的解决
  2. Websites about testing
  3. 第5天!争气!蒸汽!
  4. [动态规划] 换钱的最少货币数
  5. python解析json数据的三种方式
  6. Hibernate锁机制
  7. USACO翻译:USACO 2014 MARCH GOLD P2 Sabotage
  8. python4.0中文下载_pycharm4.0版本下载-pycharm4.0中文版v4.0.7 官方版 - 极光下载站
  9. gradle 统一版本号配置
  10. 小程序原生 详解实现腾讯地图标点和路线规划和距离计算