0

我正在 Play Framework 2.0.1 中探索 JPA 和 Ebean,以研究在本地关系数据库中生成的内容。在我的测试中,我使用的是 MySQL 的一个分支 MariaDB。

到目前为止,我已经能够使用模型中的 JPA 注释在数据库中成功生成表。我想确保我学会了如何设置一个与另一个实体具有 OneToOne 关系的实体,以及与另一个实体的 OneToMany 关系。

OneToOne:EmployeeAddress

OneToMany:EmployeePet(S)

我设置了一个小型应用程序,它允许我快速填充表格、显示一些信息以及从表格中删除行。下面是那些想要查看我的设置的人的代码:

路线

GET     /                   controllers.Application.index()
GET     /add                controllers.Application.addEmployee()
GET     /delete/:id         controllers.Application.deleteEmployee(id: Long)
GET     /employee/:id       controllers.Application.showEmployee(id: Long)

控制器

应用程序.java

public class Application extends Controller {

    public static Result index() {
        return ok(index.render("entry point"));
    }

    public static Result addEmployee() {
        // Create an employee.
        Employee employee = new Employee();     
        employee.firstName = "John";
        employee.lastName = "Doe";
        employee.salary = new BigDecimal(123456);

        // Create an address for the employee.
        Address address = new Address();
        address.city = "West Chester";
        address.country = "United States of America";
        address.postalCode = "19380";
        address.province = null;
        address.street = "45 Jingleheimer Drive";

        // Create pets for the employee.
        Pet pet = new Pet();
        pet.petString = "dog";
        Pet pet2 = new Pet();
        pet2.petString = "cat";

        employee.address = address;
        employee.pets.add(pet);
        employee.pets.add(pet2);
        employee.save();

        return ok(index.render("added an employee"));
    }

    public static Result showEmployee(Long id) {
        Employee e = Employee.get(id);
        //String s = e.address.street;
        return ok(employee.render(e));
    }

    public static Result deleteEmployee(Long id) {
        Employee.delete(id);
        return ok(index.render("deleted employee " + id));
    }
}

楷模

雇员.java

@Entity
public class Employee extends Model {
    @Id
    public Long employee_id;

    public String firstName;

    public String lastName;

    public BigDecimal salary;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="owner_id")
    public Address address;

    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name="owner_id", referencedColumnName="employee_id")
    public List<Pet> pets;

    public static Employee get(Long id) {
        return find.byId(id);
    }

    public static void delete(Long id) {
        find.byId(id).delete();
    }

    public static Finder<Long, Employee> find = new Finder<Long,Employee>(Long.class, Employee.class);
}

地址.java

@Entity
public class Address extends Model {
    @Id
    public Long address_id;

    public String street;

    public String city;

    public String province;

    public String country;

    public String postalCode;
}

宠物.java

@Entity
public class Pet extends Model {
    @Id
    public Long pet_id;
    public String petString;    
}

意见

员工.scala.html

@(employee: models.Employee)

@import helper._

@main("employee view") {

    <p>@employee.firstName</p>
    <p>@employee.lastName</p>
    <p>@employee.salary</p>
    <p>@employee.address.country</p>

    <p>@employee.pets(1).petString</p>

    @for(pet <- employee.pets) {
        <p>@pet.petString</p>
    }
}

如果我使用 localhost:9000/employee/1 之类的 URL 呈现上面的视图,我会在浏览器中显示以下内容:

John

Doe

123456

cat

dog

cat

请注意,地址所在的国家/地区未显示。我还尝试在控制器中访问它并将其打印到打印 NULL 的命令窗口。

但是,我发现如果我在Address类中添加 getter,我可以在 scala 模板中检索它:

添加

public String getCity() {
    return city;
}

...

到 Address.java 结果

John

Doe

123456

United States of America

cat

dog

cat

所以我可以设置一个地址并将其分配给一个员工(它显示在我的数据库中)。此外,正确删除员工会级联并删除数据库中的地址。同样,这适用于 Pet 类,即OneToMany. 那么为什么我需要添加 getter 来访问我的Address属性,而不是 forPet呢?我的一对一关系是否未在 Java 注释中正确设置?

4

1 回答 1

1

EBean 不支持通过直接属性访问进行延迟加载。在 Java-Controller-Code 中,该语句employee.address.country被增强为类似employee.getAddress().getCountry(). 唉,这不是在 Scala 代码中完成的,尤其是在模板中。

employee.pets(1).petString另一方面,被转换为employee.pets.get(1).petString,这足以让 EBean 延迟加载,因为涉及到 EBean LazyList。

请不要坚持使用 getter/setter!表演!人们认为你应该在控制器中知道你需要什么数据并在查询时获取它:

public static Employee get(Long id) {
  return find.fetch("address").where().idEq(id).findUnique();
}
于 2012-05-26T14:18:14.430 回答