1. 简介
Ebean 是一个用 Java 编写的对象关系映射(ORM)工具。
虽然它支持标准的 JPA 注解 来定义实体类,但 Ebean 提供了更加简洁的 API 来进行数据持久化操作。值得一提的是,Ebean 是 无会话(sessionless) 架构,这意味着它不会对实体进行全生命周期管理。此外,Ebean 支持原生 SQL 查询,并兼容主流数据库,例如 Oracle、PostgreSQL、MySQL、H2 等。
接下来,我们将从创建和持久化数据开始,然后使用 Ebean 和 H2 数据库进行实体查询。
2. 环境配置
首先,我们需要添加必要的依赖项来搭建项目环境。
2.1. Maven 依赖
在 pom.xml
文件中添加以下依赖:
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>13.25.2</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</dependency>
2.2. 实体增强(Enhancements)
Ebean 需要对实体类进行增强处理,以便服务器能够对其进行管理。为此,我们需要添加 ebean-maven-plugin 插件:
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>13.25.2</version>
<executions>
<execution>
<id>main</id>
<phase>process-classes</phase>
<configuration>
<transformArgs>debug=1</transformArgs>
</configuration>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
此外,我们还需要通过 ebean.mf
文件告知插件哪些包中包含实体类和事务类:
entity-packages: com.baeldung.ebean.model
transactional-packages: com.baeldung.ebean.app
2.3. 日志配置
为了方便调试,我们可以在 logback.xml
中开启相关日志:
<logger name="io.ebean.DDL" level="TRACE"/>
<logger name="io.ebean.SQL" level="TRACE"/>
<logger name="io.ebean.TXN" level="TRACE"/>
这样就可以看到 Ebean 执行的 DDL、SQL 和事务日志。
3. 数据库服务器配置
接下来,我们需要创建一个 Database
实例,用于保存实体或执行查询。有两种方式可以创建数据库实例:使用默认配置文件或通过编程方式。
3.1. 使用默认配置文件
Ebean 会自动查找名为 application.properties
、ebean.properties
或 application.yml
的配置文件。
示例配置如下:
ebean.db.ddl.generate=true
ebean.db.ddl.run=true
datasource.db.username=sa
datasource.db.password=
datasource.db.databaseUrl=jdbc:h2:mem:customer
datasource.db.databaseDriver=org.h2.Driver
通过这些配置,我们可以指定数据库连接信息,并让 Ebean 自动生成并执行 DDL 语句。
3.2. 使用 DatabaseConfig 编程配置
我们也可以使用 DatabaseFactory
和 DatabaseConfig
来手动创建数据库实例:
DatabaseConfig cfg = new DatabaseConfig();
Properties properties = new Properties();
properties.put("ebean.db.ddl.generate", "true");
properties.put("ebean.db.ddl.run", "true");
properties.put("datasource.db.username", "sa");
properties.put("datasource.db.password", "");
properties.put("datasource.db.databaseUrl", "jdbc:h2:mem:app2");
properties.put("datasource.db.databaseDriver", "org.h2.Driver");
cfg.loadFromProperties(properties);
Database server = DatabaseFactory.create(cfg);
3.3. 默认数据库实例
✅ 一个 Database
实例对应一个数据库。 根据需要,我们可以创建多个实例。
如果只创建了一个实例,它将自动注册为默认数据库实例,可以通过 DB
类的静态方法访问:
Database server = DB.getDefault();
如果存在多个数据库实例,可以通过以下方式设置默认实例:
cfg.setDefaultServer(true);
4. 创建实体类
Ebean 支持标准的 JPA 注解,同时也提供了自己的扩展注解。
我们先创建一个基类 BaseModel
,用于定义通用字段:
@MappedSuperclass
public abstract class BaseModel {
@Id
protected long id;
@Version
protected long version;
@WhenCreated
protected Instant createdOn;
@WhenModified
protected Instant modifiedOn;
// getters and setters
}
这里使用了 JPA 的 @MappedSuperclass
,以及 Ebean 的 @WhenCreated
和 @WhenModified
注解用于审计。
然后创建两个实体类 Customer
和 Address
:
@Entity
public class Customer extends BaseModel {
public Customer(String name, Address address) {
super();
this.name = name;
this.address = address;
}
private String name;
@OneToOne(cascade = CascadeType.ALL)
Address address;
// getters and setters
}
@Entity
public class Address extends BaseModel {
public Address(String addressLine1, String addressLine2, String city) {
super();
this.addressLine1 = addressLine1;
this.addressLine2 = addressLine2;
this.city = city;
}
private String addressLine1;
private String addressLine2;
private String city;
// getters and setters
}
在 Customer
类中,我们定义了与 Address
的一对一关系,并设置了级联操作。
5. 基本 CRUD 操作
我们已经完成了数据库配置和实体创建,现在来进行基本的 CRUD 操作。
使用默认数据库实例进行数据持久化和查询:
Address a1 = new Address("5, Wide Street", null, "New York");
Customer c1 = new Customer("John Wide", a1);
Database server = DB.getDefault();
server.save(c1);
c1.setName("Jane Wide");
c1.setAddress(null);
server.save(c1);
Customer foundC1 = DB.find(Customer.class, c1.getId());
DB.delete(foundC1);
步骤如下:
- 创建
Customer
对象并保存; - 更新对象并再次保存;
- 查询对象并删除。
6. 查询操作
Ebean 的查询 API 支持构建带有过滤条件的对象图。
下面是一个示例查询,查找城市为 "San Jose" 的客户,并只返回部分字段:
Customer customer = DB.find(Customer.class)
.select("name")
.fetch("address", "city")
.where()
.eq("city", "San Jose")
.findOne();
说明:
find()
:指定要查询的实体类型;select()
:指定要加载的字段;fetch()
:指定关联对象及要加载的字段;where().eq(...)
:添加查询条件;findOne()
:返回单个结果。
7. 事务支持
默认情况下,Ebean 会为每个语句或查询开启一个新的事务。
如果需要在同一个事务中执行多个操作,可以使用 @Transactional
注解:
@Transactional
public static void insertAndDeleteInsideTransaction() {
Customer c1 = getCustomer();
Database server = DB.getDefault();
server.save(c1);
Customer foundC1 = server.find(Customer.class, c1.getId());
server.delete(foundC1);
}
此时,方法中的所有数据库操作将在同一个事务中执行。
8. 项目构建
最后,使用以下命令构建 Maven 项目并执行增强处理:
mvn compile io.ebean:ebean-maven-plugin:enhance
9. 总结
本文介绍了 Ebean ORM 的基本用法,包括实体定义、数据库配置、CRUD 操作、查询构建以及事务管理。Ebean 以其简洁的 API 和强大的查询能力,成为 Java 持久化领域的一个不错选择。✅