保存

保存将根据 bean 的状态插入或更新 bean。

Order order = new Order();
order.setOrderDate(new Date());
...
// insert the order
order.save();

如果已获取 bean,则将更新 bean...

Order order = DB.find(Order.class, 42);
order.setStatus(SHIPPED);
...
// update the order
order.save();

保存和删除将基于关联的 @OneToMany、@OneToOne 等注解中指定的 CascadeType 进行级联。

默认情况下,保存和删除不会级联,因此您需要为 save() 或 delete() 指定级联类型(例如以下详细信息中的级联类型)以进行级联。

...
@Entity
@Table(name="orders")
public class Order {

  ...
  @ManyToOne // no cascading
  Customer customer;

  @OneToMany(cascade=CascadeType.ALL) // save and delete cascaded
  List<OrderDetail> details;
	...

请注意 details 属性上的 @OneToMany(cascade=CascadeType.ALL)。这意味着 save() 和 delete() 都将从订单级联到其订单详细信息。

...
// save the order ...  will cascade also saving the order details
DB.save(order);

删除

删除与保存非常相似。只需调用 DB.delete();

...
Order order = DB.find(Order.class, 12);

// delete the order
// ... this will cascade also deleting the order details
// ... with either CascadeType.ALL or CascadeType.REMOVE
DB.delete(order);

级联

映射注解 @ManyToOne、@OneToMany、@OneToOne 和 @ManyToMany 提供了一个级联属性,用于控制是否级联保存和删除。

默认情况下,不级联保存或删除(根据 JPA 规范)。

以下示例显示了具有其映射注解的 Order 实体 bean。如果您保存一个 Order,则详细信息也将被保存,但关联的客户不会被保存,因为没有级联属性,并且默认情况下不级联。

...
@Entity
@Table(name="orders")
public class Order {
  ...

  @ManyToOne // no cascading
  Customer customer;

  @OneToMany(cascade=CascadeType.ALL)  // save and delete cascaded
  List<OrderDetail> details;

批量更新

Update 提供了一种发出插入、更新或删除语句的方法。

这对于使用单个语句(通常称为“批量”更新)更新或删除多行(或单行)非常有用。

如果您想在不先执行查询的情况下执行更新或删除,这也很有用。这是在无状态 Web 应用程序中执行更新的典型方法。

该语句可以作为原始 DML 提供,其中包含表名和列名,也可以采用“逻辑”形式,其中实体名用于代替表名,属性名用于代替列名。

// orm bulk delete use bean name and bean properties
DB.createUpdate(OrderDetail.class, "delete from orderDetail").execute();

// sql bulk update uses table and column names
DB.sqlUpdate("delete from country").execute();
`

批量 SQL 更新

SqlQuery 类似,您可以使用命名或定位参数指定 SQL INSERT、UPDATE 或 DELETE 语句。

String dml = "update b_bug set title=:title where id = :id";
int rows = DB.sqlUpdate(dml)
  .setParameter("title", "Updated Again")
  .setParameter("id", 1)
  .execute();

CallableSql

CallableSql 提供了一种调用数据库存储过程的方法。

String sql = "{call sp_order_mod(?,?)}";
CallableSql cs = DB.createCallableSql(sql);
cs.setParameter(1, "turbo");
cs.registerOut(2, Types.INTEGER);
DB.execute(cs);

// read the out parameter
Integer returnValue = (Integer) cs.getObject(2);

您可以扩展 CallableSql,还可以从事务中获取 java.sql.Connection,并使用原始 JDBC API 调用存储过程。

原始 JDBC

您无法始终预测应用程序需求何时无法通过 Ebean 中的功能得到满足。如果您需要,了解您可以轻松使用原始 JDBC 会很好。

java.sql.Connection 对象可以从事务中返回,有了它,您可以执行任何您喜欢的原始 JDBC 调用。

这对于保存点、高级 Clob/Blob 使用或高级存储过程调用(如果 CallableSql 无法为您完成业务)可能很有用。

try (Transaction transaction = DB.beginTransaction()) {

  Connection connection = transaction.getConnection();
  // use raw JDBC
  ...

  transaction.commit();
}

JDBC 批处理

Ebean 提供对 JDBC 批处理的支持。批处理将相关的 SQL 语句分组到一个批处理中,并通过一次调用提交到数据库。

批处理设置可以通过 application.properties 或通过 DatabaseConfig 进行配置,并且可以针对每个事务进行覆盖。

您可以通过 setBatch() 为要保存的实体设置批处理模式,并通过 setCascadeBatch() 为其子集合设置批处理模式。

...(正在建设中)...需要提供更好的指导,说明如何确定批处理模式、子批处理模式和批处理大小

Transaction transaction = database.beginTransaction();
try {
  // turn of cascade persist
  transaction.setCascadePersist(false);

  // control the jdbc batch mode and size
  // transaction.setBatchMode(true); // equivalent to transaction.setBatch(PersistBatch.ALL);
  // transaction.setBatchMode(false); // equivalent to transaction.setBatch(PersistBatch.NONE);
  transaction.setBatch(PersistBatch.ALL); // PersistBatch: NONE, INSERT, ALL
  transaction.setCascadeBatch(PersistBatch.INSERT); // PersistBatch: NONE, INSERT, ALL
  transaction.setBatchSize(30);


  // for a large batch insert if you want to skip
  // getting the generated keys
  transaction.setGetGeneratedKeys(false);

  // for batch processing via raw SQL you can inform
  // Ebean what tables were modified so that it can
  // clear the appropriate L2 caches
  String tableName = "customer";
  boolean inserts = true;
  boolean upates = true;
  boolean deletes = false;
  transaction.addModification(tableName, inserts, updates, deletes);

  ...
} finally {
  transaction.end();
}
使用 @Transactional 的示例
@Transactional(batchSize = 50)
public void goodStuff() {

    order.save()
    customer.save()
}