Bitte im Interesse der Old Gods and the New Gods dies nicht tun
tun so etwas wie dies würde total mess up Ihrer Datenbank. Sie wird früher oder später in Probleme laufen. Wenn Sie auf Ihr Profil schauten, haben Sie einen CS-Abschluss gemacht, so dass Sie Ihren Datenbank-Kurs hatten. Denken Sie daran, die Second normal form und die Third normal form und wie Sie dies brechen, wenn Sie Attribute haben, die von anderen Attributen abhängen.
Was Sie tun sollten, ist entweder ein transientes Feld (markiert mit @Transient
) oder Sie können den Getter verwenden und die Informationen von dort bereitstellen. Jedes Mal, wenn Sie auf die name_length
zugreifen müssen, rufen Sie diesen Getter auf, aber Sie werden die Informationen nicht in der Datenbank speichern.
Auch wenn Sie die Länge außerhalb Ihrer Anwendung berechnen möchten, können Sie dafür weiterhin eine Datenbankfunktion verwenden - like length.
Bearbeiten auf der Grundlage der Anforderung durch die OP erwähnt:
In JPA gibt es zwei Möglichkeiten, wie Sie die Spalten erklären können - entweder auf den Feldern oder zu den Methoden (Getter/Setter). Es würde wie folgt aus:
@Column(name = "complex_calculation") // Due to some bad requirement
public Integer getNameLength() {
return fisrtName.length() + lastName.length();
}
immer Sie Ebean in Ihrer Frage und Ebean erwähnt wird, nicht als Referenz JPA-Implementierung angesehen. Es gibt eine gute Chance, dass dies noch nicht unterstützt wird, aber Sie können es in Ihrem speziellen Fall versuchen.
Es gibt einen anderen Weg, der nachweislich funktioniert. Sie definieren Ihr Modell wie folgt aus:
@Entity
public class Person extends Model {
@Id
private Long id;
private String firstName;
private String lastName;
private Integer nameLength;
public Long getId() {
return id;
}
// getter for first name and last name with @Column annotation
@Column(name = "complex_calculation")
public Integer getNameLength() {
return firstName.length() + lastName.length();
}
public Person (String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
updateComplexCalculation();
}
public void setFirstName(String firstName) {
this.firstName = firstName;
updateComplexCalculation();
}
public void setLastName(String lastName) {
this.lastName = lastName;
updateComplexCalculation();
}
private void updateComplexCalculation() {
this.nameLength = firstName.length() + lastName.length();
}
}
Der wichtige Teil der updateComplexCalculation
Methode. Wenn der Konstruktor aufgerufen wird und bei jedem Setter-Aufruf, rufen Sie diese Methode auf, um die komplexe Eigenschaft zu aktualisieren. Natürlich sollten Sie es nur bei Setter-Aufrufen aufrufen, die für die Berechnung benötigt werden.
Der folgende Code:
Person p = new Person("foo", "bar");
p.save();
Logger.debug("Complex calculation: " + p.getNameLength());
p.setFirstName("somethingElse");
p.save();
Logger.debug("Complex calculation: " + p.getNameLength());
Ausbeuten dann:
[debug] application - Complex calculation: 6
[debug] application - Complex calculation: 16
Ich erinnere mich an meine normalen Formen gut, und ich stimme dir zu. Aber manchmal kommen Anforderungen auf. Der Client möchte das Feld in der Datenbank, aber es soll nicht nur ein berechneter Wert von der Datenbank sein. Dies ist aus Leistungsgründen. Dies ist nicht der tatsächliche Anwendungsfall, also wird die Länge nicht funktionieren. Die Regeln zur Berechnung dieser Felder sind wesentlich komplizierter und existieren in unserem Java-Code. Wir benötigen diese Felder als Felder für die Erstellung von Berichten mit SQL, und es wäre besser, die Geschäftslogik nicht in einer Reihe von SQL-Ansichten zu duplizieren. – ncphillips
Ich verstehe deinen Standpunkt. Obwohl ich die Idee immer noch nicht mag, habe ich meine Antwort mit einer Möglichkeit aktualisiert, diese Arbeit zu machen. Meine Annahme ist, dass Sie eine Eigenschaft definieren müssen, wenn Sie Ebean verwenden. Es sollte ohne eine Eigenschaft in Hibernate funktionieren. – Anton
Akzeptiert Ihren Kommentar. Die Tatsache, dass er für die Namenslänge getwittert hat, berechnete die Werte manuell. – ncphillips