13.2.1 为 Cassandra 定义实体类
与持久化 Mongo 时一样,选择响应式还是非响应式 Cassandra 持久化,在定义领域实体类上完全没区别。我们将使用的 Ingredient、Taco 和 TacoOrder 类,与我们在第 4 章创建的完全相同。
Cassandra 注解的 Ingredient 类如清单 13.17 所示。
清单 13.17 注解 Cassandra 持久化 Ingredient 类。
package tacos;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)
@Table("ingredients")
public class Ingredient {
@PrimaryKey
private String id;
private String name;
private Type type;
public static enum Type {
WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
}
}
至于 Taco 类,它是用类似的 Cassandra 持久化注解定义的,如清单 13.18 所示:
清单 13.18 为 Cassandra 持久化注解的 Taco。
package tacos;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.springframework.data.cassandra.core.cql.Ordering;
import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
import org.springframework.data.cassandra.core.mapping.Column;
import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
import org.springframework.data.cassandra.core.mapping.Table;
import org.springframework.data.rest.core.annotation.RestResource;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import lombok.Data;
@Data
@RestResource(rel = "tacos", path = "tacos")
@Table("tacos")
public class Taco {
@PrimaryKeyColumn(type=PrimaryKeyType.PARTITIONED)
private UUID id = Uuids.timeBased();
@NotNull
@Size(min = 5, message = "Name must be at least 5 characters long")
private String name;
@PrimaryKeyColumn(type=PrimaryKeyType.CLUSTERED,
ordering=Ordering.DESCENDING)
private Date createdAt = new Date();
@Size(min=1, message="You must choose at least 1 ingredient")
@Column("ingredients")
private List<IngredientUDT> ingredients = new ArrayList<>();
public void addIngredient(Ingredient ingredient) {
this.ingredients.add(new IngredientUDT(ingredient.getName(), ingredient.getType()));
}
}
由于通过用户定义的类型引用对象,因此您还需要 IngreditUDT 类,如清单 13.19 所示。
清单 13.19 是 Cassandra 持久化的用户定义类型。
package tacos;
import org.springframework.data.cassandra.core.mapping.UserDefinedType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
@UserDefinedType("ingredient")
public class IngredientUDT {
private String name;
private Ingredient.Type type;
}
三个领域实体类中的最后一个,TacoOrder 持久化如清单 13.20 所示。
清单 13.20 为 Cassandra 持久化注解 TacoOrder。
package tacos;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.data.cassandra.core.mapping.Column;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import lombok.Data;
@Data
@Table("tacoorders")
public class TacoOrder implements Serializable {
private static final long serialVersionUID = 1L;
@PrimaryKey
private UUID id = Uuids.timeBased();
private Date placedAt = new Date();
@Column("user")
private UserUDT user;
private String deliveryName;
private String deliveryStreet;
private String deliveryCity;
private String deliveryState;
private String deliveryZip;
private String ccNumber;
private String ccExpiration;
private String ccCVV;
@Column("tacos")
private List<TacoUDT> tacos = new ArrayList<>();
public void addTaco(Taco taco) {
this.addTaco(new TacoUDT(taco.getName(), taco.getIngredients()));
}
public void addTaco(TacoUDT tacoUDT) {
this.tacos.add(tacoUDT);
}
}
就像 Taco 通过用户定义的类型引用配料一样,TacoOrder 引用通过 TacoUDT 类实现 Taco,如清单 13.21 所示。
清单 13.21 Cassandra 持久化的 Taco 用户定义类型。
package tacos;
import java.util.List;
import org.springframework.data.cassandra.core.mapping.UserDefinedType;
import lombok.Data;
@Data
@UserDefinedType("taco")
public class TacoUDT {
private final String name;
private final List<IngredientUDT> ingredients;
}
再重复一遍,它们与非响应式的对应类是相同的。我只重复在这里把它们放了一遍,这样您就不必到其他单来记住它们的样子。
现在让我们定义保存这些对象的 Repository。