Java泛型。对我来说有什么好处?
现在我开始研究基于MVC的小型web应用程序。 现在我尝试使用DAO模式实现模型布局的主要类 因此,首先我创建了两个实体类(例如):Author和Book:Java泛型。对我来说有什么好处?,java,model-view-controller,generics,interface,dao,Java,Model View Controller,Generics,Interface,Dao,现在我开始研究基于MVC的小型web应用程序。 现在我尝试使用DAO模式实现模型布局的主要类 因此,首先我创建了两个实体类(例如):Author和Book: package myProject.model.entity; import java.io.Serializable; public class Author implements Serializable { private static final long serialVersionUID = 7177
package myProject.model.entity;
import java.io.Serializable;
public class Author implements Serializable {
private static final long serialVersionUID = 7177014660621405534L;
private long id;
private String firstName;
private String lastName;
public Author() {
}
// getter and setter methods here
}
图书类:
package myProject.model.entity;
import java.io.Serializable;
public class Book implements Serializable {
private static final long serialVersionUID = 7177014660621405534L;
private long id;
private String title;
private String description;
public Book() {
}
// getter and setter methods here
}
在下一步中,我看到,Book和Author类都有getId()
和setId()
。
因此,我为我的实体类创建了接口持久性:
package myProject.model.entity;
public interface Persistent {
public long getId();
public void setId(long id);
}
首先,我的问题是:
它是模型
包的正确实现吗
在下一步中,我开始为包dao
实现类
package myProject.model.dao;
import java.util.List;
import myProject.model.entity.Persistent;
public interface Dao {
Persistent get(long id);
void save(Persistent persistent);
void delete(long id);
}
下一步:创建接口AuthorDao
和BookDao
,扩展基本dao接口dao
但是这两个接口:AuthorDao和BookDao——现在都是空的。
你怎么看?在正常情况下,接口是空的?这是我的第二个问题
在最后一步中,我创建了包model.dao.hibernate
,并将其添加到类AuthorDaoHibernate和BookDaoHibernate中-这两个类都实现了AuthorDao和BookDao接口
我现在的主要问题是:
我的界面Dao
使用对象类型Persistent
,我不使用泛型。一切都很好
你怎么想?如果我重新使用Dao
接口和泛型,我有什么好处:
package myProject.model.dao;
import java.util.List;
import myProject.model.entity.Persistent;
public interface Dao<Persistent> {
T get(long id);
List<T> getAll();
void save(T persistent);
void delete(long id);
}
包myProject.model.dao;
导入java.util.List;
导入myProject.model.entity.Persistent;
公共接口Dao{
T get(长id);
List getAll();
无效保存(T持久);
作废删除(长id);
}
我的Dao类仅适用于持久性实体-没有任何其他对象类型
你真的有什么理由在我的情况下使用泛型吗?这里没有理由。如果它是唯一的,根据定义,它不是通用的!
List getAll()将完成此任务
ArrayList是泛型的,因为它有时会返回Persistent,有时返回President。如果要使用泛型,应该按照以下方式定义Dao:
public interface Dao<T extends Persistent> {
.....................
void save(T persistent);
...................
}
公共接口Dao{
.....................
无效保存(T持久);
...................
}
现在,当您扩展它时,您必须创建仅接受书本的存储:
public class Book extends Dao<Book> {
.....................
void save(Book persistent);
...................
}
公共类书扩展Dao{
.....................
作废保存(书本持久化);
...................
}
这里的好处是您不能将作者
传递给BookDao
。这不会通过编译
顺便说一句,如果您使用的是Hibernate、JPA或其他ORM解决方案,您实际上不必为每个实体创建DAO。一个通用dao可以解决您的所有需求 泛型可以极大地提高代码可读性,并减少错误转换可能导致的错误
我们使用的东西与您描述的类似(请注意,需要一些接口和实现)
下面是一个基本的例子(为了简洁起见,我将把getter和setter放在后面):
实际void保存(图书持久化)如果实现与基本实现没有差异,代码>甚至都不是必需的。@Thomas,我100%同意你的看法。我甚至写道,他根本不需要每个实体都使用DAO。一个通用实现就足够了。BaseEntity-必须是抽象的还是否?@user471011不,它不需要是抽象的,它只是没有被注释为一个实体,您不能持久化一个普通的BaseEntity
实例。将BaseEntity
甚至BaseDAO
抽象化是有意义的,但为了简洁起见,我省略了这一点。我们可以更详细地讨论一下吗?通过邮件还是通过skype?这对你来说很难吗?@user471011不幸的是,我现在没有那么多时间,因为我在工作。@user471011如果你有更多的问题,你可以在这里问他们。其他人可能会提供帮助,或者可能会发现这些信息也很有用。
@MappedSuperClass
class BaseEntity {
@Id
private int id;
}
@Entity
class UserEnity extends BaseEntity {
//user stuff like name
}
class BaseDAO<T extends BaseEntity> {
public T findById(int id) {
...
}
//other generic CRUD methods
}
@Stateless
class UserDAO extends BaseDAO<UserEntity> {
//additional user specific methods
}
UserDAO userDao; //some injection or lookup
//no explicit cast needed here, thanks to generics
UserEntity user = userDao.findById(userId);
//compiler error due to the generic parameter being UserEntity and AnotherEntity doesn't extend that
AnotherEntity a = userDao.findById(someId);