1. Introduction
1.绪论
Ebean is an object-relational mapping tool written in Java.
Ebean是一个用Java编写的对象关系映射工具。。
It supports the standard JPA annotations for declaring entities. However, it provides a much simpler API for persisting. In fact, one of the points worth mentioning about the Ebean architecture is that it is sessionless, meaning it does not fully manage entities.
它支持用于声明实体的标准JPA注解。然而,它为持久化提供了一个更简单的API。事实上,关于Ebean架构值得一提的一点是,它是无会话的,这意味着它不完全管理实体。
Besides that, it also comes with a query API and supports writing queries in native SQL. Ebean supports all major database providers such as Oracle, Postgres, MySql, H2 etc.
除此之外,它还配备了一个查询API,并支持用本地SQL编写查询。Ebean支持所有主要的数据库供应商,如Oracle、Postgres、MySql、H2等。
In this tutorial, we’ll take a look at how we can create, persist and query entities using Ebean and H2.
在本教程中,我们将看看如何使用Ebean和H2来创建、持久化和查询实体。
2. Setup
2.设置
To get started, let’s get our dependencies as well as some basic configuration.
为了开始工作,让我们获得我们的依赖性以及一些基本配置。
2.1. Maven Dependencies
2.1.Maven的依赖性
Before we begin, let’s import the required dependencies:
在我们开始之前,让我们导入所需的依赖项。
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>11.22.4</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
The latest versions of Ebean, H2, and Logback can be found on Maven Central.
Ebean、H2和Logback的最新版本可以在Maven中心找到。
2.2. Enhancements
2.2 改进措施
Ebean needs to modify entity beans so that they can be managed by the server. Thus, we’ll add a Maven plugin to do that job:
Ebean需要修改实体Bean,使其能够被服务器所管理。因此,我们将添加一个Maven插件来完成这项工作。
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>11.11.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>
We also need to provide the Maven plugin with the names of the packages which contain the entities and classes which use transactions. To do that we create the file ebean.mf:
我们还需要向Maven插件提供包含实体和使用事务的类的包名。为此,我们创建了ebean.mf:文件。
entity-packages: com.baeldung.ebean.model
transactional-packages: com.baeldung.ebean.app
2.3. Logging
2.3.伐木
Let’s also create logback.xml and set logging levels on some packages to TRACE so that we can see the statements that are being executed:
让我们也创建logback.xml,并在一些包上设置日志级别为TRACE,以便我们可以看到正在执行的语句。
<logger name="io.ebean.DDL" level="TRACE"/>
<logger name="io.ebean.SQL" level="TRACE"/>
<logger name="io.ebean.TXN" level="TRACE"/>
3. Configuring a Server
3.配置一台服务器
We need to create an EbeanServer instance to save entities or run queries on a database. There are two ways in which we can create a server instance – using a default properties file or doing it programmatically.
我们需要创建一个EbeanServer实例来保存实体或在数据库上运行查询。我们有两种方法可以创建一个服务器实例–使用默认的属性文件或以编程方式进行。
3.1. Using a Default Properties File
3.1.使用默认属性文件
The default properties file can be of type properties or yaml. Ebean will search for configuration in files with names application.properties, ebean.properties or application.yml.
默认的属性文件可以是properties或yaml类型。Ebean会在名称为application.properties、ebean.properties或application.yml的文件中搜索配置。
Apart from supplying the database connection details, we can also instruct Ebean to create and run DDL statements.
除了提供数据库连接的详细信息,我们还可以指示Ebean创建和运行DDL语句。
Now, let’s look at a sample configuration:
现在,让我们看看一个样本配置。
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
3.2. Using ServerConfig
3.2.使用ServerConfig
Next, let’s look at how we can create the same server programmatically using EbeanServerFactory and ServerConfig:
接下来,让我们看看如何使用EbeanServerFactory和ServerConfig以编程方式创建相同的服务器。
ServerConfig cfg = new ServerConfig();
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);
EbeanServer server = EbeanServerFactory.create(cfg);
3.3. Default Server Instance
3.3.默认的服务器实例
A single EbeanServer instance maps to a single database. Depending on our requirements we could create more than one EbeanServer instance as well.
一个EbeanServer实例映射到一个数据库。根据我们的要求,我们也可以创建一个以上的EbeanServer实例。
If only a single server instance is created, by default, it is registered as the default server instance. It can be accessed anywhere in the application using a static method on the Ebean class:
如果只创建了一个服务器实例,在默认情况下,它被注册为默认服务器实例。可以使用Ebean类的静态方法,在应用程序的任何地方访问它。
EbeanServer server = Ebean.getDefaultServer();
In case there are multiple databases, it’s possible to register one of the server instances as default one:
在有多个数据库的情况下,可以将其中一个服务器实例注册为默认实例。
cfg.setDefaultServer(true);
4. Creating Entities
4.创建实体
Ebean provides full support for JPA annotations as well as additional features using its own annotations.
Ebean提供了对JPA注释的全面支持,以及使用其自身注释的额外功能。
Let’s create few entities using both JPA and Ebean annotations. First, we’ll create a BaseModel which contains properties that are common across entities:
让我们使用JPA和Ebean注解来创建一些实体。首先,我们将创建一个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
}
Here, we have used the MappedSuperClass JPA annotation to define the BaseModel. And two Ebean annotations io.ebean.annotation.WhenCreated and io.ebean.annotation.WhenModified for auditing purposes.
在这里,我们使用了MappedSuperClass JPA注解来定义BaseModel.和两个Ebean注解io.ebean.annotation.WhenCreated和io.ebean.annotation.WhenModified用于审计目的。
Next, we will create two entities Customer and Address which extend BaseModel:
接下来,我们将创建两个实体Customer和Address,它们扩展BaseModel。
@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
}
In Customer, we have defined a one to one mapping with Address and added set cascade type to ALL so that child entities are also updated along with the parent entities.
在Customer中,我们定义了与Address的一对一映射,并将级联类型设置为ALL,以便子实体也与父实体一起被更新。
5. Basic CRUD Operations
5.基本CRUD操作
Earlier we’ve seen how to configure the EbeanServer and created two entities. Now, let’s carry out some basic CRUD operations on them.
前面我们已经看到了如何配置EbeanServer和创建两个实体。现在,让我们对它们进行一些基本的CRUD操作。
We’ll be using the default server instance to persist and access the data. The Ebean class also provides static methods to persist and access data which proxy the request to default server instance:
我们将使用默认的服务器实例来持久化和访问数据。Ebean类也提供了静态方法来坚持和访问数据,这些方法将请求代理给默认服务器实例。
Address a1 = new Address("5, Wide Street", null, "New York");
Customer c1 = new Customer("John Wide", a1);
EbeanServer server = Ebean.getDefaultServer();
server.save(c1);
c1.setName("Jane Wide");
c1.setAddress(null);
server.save(c1);
Customer foundC1 = Ebean.find(Customer.class, c1.getId());
Ebean.delete(foundC1);
First, we create a Customer object and used the default server instance to save it using save().
首先,我们创建了一个Customer对象,并使用默认的服务器实例用save()来保存它。
Next, we’re updating the customer details and saving it again using save().
接下来,我们要更新客户的详细信息,并使用save()再次保存它。
Finally, we’re using the static method find() on Ebean to fetch the customer and delete it using delete().
最后,我们使用Ebean上的静态方法find()来获取客户,并使用delete()删除它。
6. Queries
6.查询
Query APIs can also be used to create an object graph with filters and predicates. We can either use Ebean or EbeanServer to create and execute queries.
查询API也可以用来创建一个带有过滤器和谓词的对象图。我们可以使用Ebean或EbeanServer来创建和执行查询。
Let’s look at a query which finds a Customer by city and returns a Customer and Address object with only some fields populated:
让我们看看一个查询,它通过城市找到一个客户,并返回一个客户和地址对象,只有一些字段被填充。
Customer customer = Ebean.find(Customer.class)
.select("name")
.fetch("address", "city")
.where()
.eq("city", "San Jose")
.findOne();
Here, with find() we indicate that we want to find entities of type Customer. Next, we use select() to specify the properties to populate in the Customer object.
在这里,通过find(),我们表明我们希望找到Customer类型的实体。接下来,我们使用select()来指定要在Customer对象中填充的属性。
Later, we use fetch() to indicate that we want to fetch the Address object belonging to the Customer and that we want to fetch the city field.
稍后,我们使用fetch()来表示我们想要获取属于Customer的Address对象,并且我们想要获取cityfield。
Finally, we add a predicate and restrict the size of the result to 1.
最后,我们添加一个谓词,并将结果的大小限制为1。
7. Transactions
7.事务
Ebean executes each statement or query in a new transaction by default.
Ebean默认在一个新的事务中执行每个语句或查询。
Although this may not be an issue in some cases. There are times when we may want to execute a set of statements within a single transaction.
尽管在某些情况下这可能不是一个问题。有的时候,我们可能想在一个事务中执行一组语句。
In such cases, if we annotate the method with io.ebean.annotations.Transactional, all the statements within the method will be executed inside the same transaction:
在这种情况下,如果我们用io.ebean.annotations.Transactional>注解方法,该方法中的所有语句将在同一个事务中执行。
@Transactional
public static void insertAndDeleteInsideTransaction() {
Customer c1 = getCustomer();
EbeanServer server = Ebean.getDefaultServer();
server.save(c1);
Customer foundC1 = server.find(Customer.class, c1.getId());
server.delete(foundC1);
}
8. Building the Project
8.项目建设
Lastly, we can build the Maven project using the command:
最后,我们可以用命令构建Maven项目。
compile io.ebean:ebean-maven-plugin:enhance
9. Conclusion
9.结语
To sum up, we’ve looked at the basic features of Ebean which can be used to persist and query entities in a relational database.
总而言之,我们已经看了Ebean的基本功能,它可以用来持久化和查询关系型数据库中的实体。
Finally, this code is available on Github.
最后,这个代码可以在Github上找到。