Cassandra的mapped類定義

Creating a table entity

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)

 

 

 

Mapping table columns 

@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;

 

Primary key fields

@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 fields

@Computed能夠在Cassandra端的計算結果的屬性上使用.能夠是Cassandra的函數或者自定義的方法.

@Computed("ttl(name)")
Integer ttl;

CQL返回的類型要與name匹配

Transient properties

默認狀況下,映射器會試圖把全部字段和bean屬性映射到表的列上,

註解@Transaction能夠組織這一行爲

 

 

Mapping User Types

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中

 

Mapping collections

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

Polymorphism support

實體類或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.

相關文章
相關標籤/搜索