A table entity is a class that will be mapped to a table in Cassandra. It is annotated with @Table:html
@Table(keyspace = "ks", name = "users", readConsistency = "QUORUM", writeConsistency = "QUORUM", caseSensitiveKeyspace = false, caseSensitiveTable = false) public class User { @PartitionKey @Column(name = "user_id") private UUID userId; private String name; // ... constructors / getters / setters }
@Table
takes the following options:java
keyspace
: the keyspace for the table.name
: the name of the table in the database.caseSensitiveKeyspace
: whether the keyspace name is case-sensitive.caseSensitiveTable
: whether the table name is case-sensitive.readConsistency
: the consistency level that will be used on each get operation in the mapper. (if unspecified, it defaults to the cluster-wide setting)writeConsistency
: the consistency level that will be used on each save, or delete operation in the mapper. (if unspecified, it defaults to the cluster-wide setting)
@Table(name = "users") public class User { // annotation on a field @PartitionKey private UUID id; public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } } @Table(name = "users") public class User { private UUID id; // annotation on a getter method @PartitionKey public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } }
註解能夠加在域(字段)上,也能夠加在方法上,項目最好始終用同一種方案.git
註解域較少冗餘github
註解方法,在多態數據模型則更靈活app
若是同時註解了域和方法,則使用方法的註解.框架
Cassandra的Column和Bean的字段ide
column會與field的相同名字(大小寫不敏感)進行映射函數
若想給colum取一個不一樣的field名字,則能夠註解ui
// column name does not match field name @Column(name = "user_name") private String userName;
若想要大小寫敏感,能夠this
// column name is case-sensitive @Column(caseSensitive = true) private String userName;
@PartitionKey標籤的使用
CREATE TABLE sales(countryCode text, areaCode text, sales int, PRIMARY KEY((countryCode, areaCode)));
@PartitionKey(0) private String countryCode; @PartitionKey(1) private String areaCode;
建表語句的多primary key的順序在bean中的表現如代碼所示,從0開始標號
@Computed能夠在Cassandra端的計算結果的屬性上使用.能夠是Cassandra的函數或者自定義的方法.
@Computed("ttl(name)")
Integer ttl;
CQL返回的類型要與name匹配
默認狀況下,映射器會試圖把全部字段和bean屬性映射到表的列上,
註解@Transaction能夠組織這一行爲
User Defined Types can also be mapped by using @UDT:
CREATE TYPE address (street text, zip_code int);
@UDT(keyspace = "ks", name = "address") class Address { private String street; @Field(name = "zip_code") private int zipCode; // ... constructors / getters / setters }
因此什麼是Types呢?
一個table能夠有UDT 列,mapper湖自動映射到相應類,兩者結合以下:
CREATE TABLE company (company_id uuid PRIMARY KEY, name text, address address);
public class Company { @PartitionKey @Column(name = "company_id") private UUID companyId; private String name; private Address address; }
UDTs能夠嵌套到集合,或者其餘UDTs中
Java collections will be automatically mapped into corresponding Cassandra types. As in Cassandra, collections can contain all native types and all user types previously defined is the database.
// Will be mapped as a 'list<text>' private List<String> stringList; // Will be mapped as a 'frozen<list<text>>' @Frozen private List<String> frozenStringList; // Will be mapped as 'map<frozen<address>, frozen<list<text>>>' @FrozenKey @FrozenValue private Map<Address, List<String>> frozenKeyValueMap; // Will be mapped as 'map<text, frozen<list<address>>>' @FrozenValue private Map<String, List<Address>> frozenValueMap;
@Frozen標籤意義還不明確 indicate whether they are frozen
實體類或UDT類,映射器會掃描父類父接口的註解,所以一個類有多層次(多態),會映射到不一樣CQL或者UDTs
一個類必須只對應一個table或或者UTD,而且要用@Table or @UDT註解. 這相似於一般通流行的SQL映射框架(如Hibernate)的"table per concrete class"策略.
Here is an example of a polymorphic mapping:
CREATE TYPE point2d (x int, y int); CREATE TYPE point3d (x int, y int, z int); CREATE TABLE rectangles (id uuid PRIMARY KEY, bottom_left frozen<point2d>, top_right frozen<point2d>); CREATE TABLE spheres (id uuid PRIMARY KEY, center frozen<point3d>, radius double);
@UDT(name = "point2d") public class Point2D { public int x; public int y; } @UDT(name = "point3d") public class Point3D extends Point2D { public int z; } public interface Shape2D { @Transient double getArea(); } public interface Shape3D { @Transient double getVolume(); } public abstract class Shape { private UUID id; @PartitionKey public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } } @Table(name = "rectangles") public class Rectangle extends Shape implements Shape2D { private Point2D bottomLeft; private Point2D topRight; @Column(name = "bottom_left") @Frozen public Point2D getBottomLeft() { return bottomLeft; } public void setBottomLeft(Point2D bottomLeft) { this.bottomLeft = bottomLeft; } @Column(name = "top_right") @Frozen public Point2D getTopRight() { return topRight; } public void setTopRight(Point2D topRight) { this.topRight = topRight; } @Transient public double getWidth() { return Math.abs(topRight.x - bottomLeft.x); } @Transient public double getHeight() { return Math.abs(topRight.y - bottomLeft.y); } @Override public double getArea() { return getWidth() * getHeight(); } } @Table(name = "spheres") public class Sphere extends Shape implements Shape3D { private Point3D center; private double radius; @Frozen public Point3D getCenter() { return center; } public void setCenter(Point3D center) { this.center = center; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } @Override public double getVolume() { return 4d / 3d * Math.PI * Math.pow(getRadius(), 3); } }
One powerful advantage of annotating getter methods is that annotations are inherited from overridden methods in superclasses and superinterfaces; in other words, if a getter method is overridden in a subclass, annotations in both method declarations will get merged together. If duplicated annotations are found during this merge process, the overriding method's annotations will take precedence over the overridden's.