在本节中,我们将介绍如何执行 ClusterJ 应用程序的基本操作,包括以下内容
创建新实例、设置其属性并将它们保存到数据库
执行主键查找(读取)
更新现有行并将更改保存到数据库
从数据库中删除行
构造和执行查询,从数据库中获取满足特定条件的一组行
创建新行。 要将新行插入表格中,首先创建 Employee
的新实例。这可以通过调用 Session
方法 newInstance()
来完成,如下所示
Employee newEmployee = session.newInstance(Employee.class);
设置与所需 employee
表列对应的 Employee
实例属性。例如,以下设置了 id
、firstName
、lastName
和 started
属性。
emp.setId(988);
newEmployee.setFirstName("John");
newEmployee.setLastName("Jones");
newEmployee.setStarted(new Date());
对更改满意后,可以持久化 Employee
实例,从而导致将包含所需值的newRow 插入 employee
表,如下所示
session.persist(newEmployee);
如果自动提交已开启,并且数据库中已存在与该 Employee
实例的 id
相同的行,则 persist()
方法将失败。如果自动提交已关闭,并且数据库中已存在与该 Employee
实例的 id
相同的行,则 persist()
方法将成功,但随后的 commit()
将失败。
如果希望保存数据,即使该行已存在,也请使用 savePersistent()
方法而不是 persist()
方法。 savePersistent()
方法根据需要更新现有实例或创建新实例,不会抛出异常。
未指定的将使用其 Java 默认值存储(对于整数类型为 0
,对于数字类型为 0.0
,对于引用类型为 null
)。
主键查找。 可以使用 Session
的 find()
方法查找 NDB
表中的现有行,如下所示
Employee theEmployee = session.find(Employee.class, 988);
这等效于主键查找查询 SELECT * FROM employee WHERE id = 988
。
ClusterJ 还支持复合主键。 find()
方法可以接受一个对象数组作为键,其中对象数组的组件用于表示主键列,顺序与声明顺序相同。此外,查询经过优化,可以检测主键列是否被指定为查询条件的一部分,如果是,则将执行主键查找或扫描作为实现查询的策略。
ClusterJ 还支持多列有序 B 树和唯一哈希索引。与主键一样,如果查询指定了有序或唯一索引字段的值,ClusterJ 会优化查询,使用索引扫描表格。
NDB Cluster 会自动将表格数据分布到多个数据节点。对于某些操作(查找、插入、删除和更新),向集群告知数据在哪个数据节点上物理存在,并在该数据节点上执行事务效率更高。ClusterJ 会自动检测分区键;如果操作可以针对特定数据节点进行优化,ClusterJ 会自动在该节点上启动事务。
更新并保存一行。 要更新我们刚刚获取的作为 theEmployee
的行中给定列的值,请使用名称与该列名称相对应的方法 set*()
。例如,要更新该 Employee
的 started
日期,请使用 Employee
的 setStarted()
方法,如下所示
theEmployee.setStarted(new Date(getMillisFor(2010, 01, 04)));
为了方便起见,我们在本示例中使用了方法 getMillisFor()
,该方法定义如下,在文件 AbstractClusterJModelTest.java
中(位于 NDB Cluster 源代码树的 storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj
目录中)
/** Convert year, month, day into milliseconds after the Epoch, UTC.
* Set hours, minutes, seconds, and milliseconds to zero.
* @param year the year
* @param month the month (0 for January)
* @param day the day of the month
* @return
*/
protected static long getMillisFor(int year, int month, int day) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DATE, day);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
long result = calendar.getTimeInMillis();
return result;
}
有关更多信息,请参阅指定的文件。
可以通过调用其他 Employee
setter 方法来更新其他列,如下所示
theEmployee.setDepartment(3);
要将更改后的行保存回 NDB Cluster 数据库,请使用 Session
的 updatePersistent()
方法,如下所示
session.updatePersistent(theEmployee);
删除行。 可以使用 Session
的 deletePersistent()
方法轻松删除单个行。在本示例中,我们将找到 ID 为 13 的员工,然后从 employee
表中删除该行
Employee exEmployee = session.find(Employee.class, 13);
session.deletePersistent(exEmployee);'
System.out.println("Deleted employee named " + exEmployee.getFirst()
+ " " + exEmployee.getLast() + ".");
还存在一个用于删除多行的方法,它提供两个选项
删除表格中的所有行。
删除任意行集合。
这两种类型的多行删除都可以使用 deletePersistentAll()
方法执行。 该方法的第一个变体 会作用于一个 Class
。例如,以下语句会删除 employee
表中的所有行并返回删除的行数,如下所示
int numberDeleted = session.deletePersistentAll(Employee);
System.out.println("There used to be " + numberDeleted + " employees, but now there are none.");
上面显示的 deletePersistentAll()
调用等效于在 mysql 客户端中发出 SQL 语句 DELETE FROM employee
。
deletePersistentAll()
也可用于删除行集合,如本示例所示
// Assemble the collection of rows to be deleted...
List<Employee> redundancies = new ArrayList<Employee>();
for (int i = 1000; i < 2000; i += 100) {
Employee redundant = session.newInstance(Employee.class);
redundant.setId(i);
redundancies.add(redundant);
}
numberDeleted = session.deletePersistentAll(redundancies);
System.out.println("Deleted " + numberDeleted + " rows.");
在删除行之前,不必在数据库中查找它们。
编写查询。 ClusterJ QueryBuilder
接口用于实例化查询。该过程从获取 QueryBuilder
实例开始,该实例由当前 Session
提供;然后,我们可以获得一个 QueryDefinition
,如下所示
QueryBuilder builder = session.getQueryBuilder();
QueryDomainType<Employee> domain = builder.createQueryDefinition(Employee.class);
然后使用它来设置查询要比较的列。此处,我们将展示如何准备一个查询,该查询将 employee
表的 department
列的值与常量值 8
进行比较。
domain.where( domain.get("department").equal(domain.param("department") );
Query<Employee> query = session.createQuery(domain);
query.setParameter("department", 8);
要从查询中获取结果,请调用 Query
的 getResultList()
方法,如下所示;
List<Employee> results = query.getResultList();
返回值是一个 List
,可以迭代它以按常规方式检索和处理行。
事务。 可以选择使用 Transaction
接口通过以下方法绑定事务
begin()
:开始事务。commit()
:提交事务。rollback()
:回滚事务。
也可以使用 Transaction
来检查事务是否处于活动状态(通过 isActive()
方法),并获取和设置仅回滚标志(分别使用 getRollbackOnly()
和 setRollbackOnly()
)。
如果您不使用 Transaction
接口,则 Session
中影响数据库的方法(如 persist()
、deletePersistent()
、updatePersistent()
等)会自动包含在数据库事务中。