我是来自PHP / Larvel,Ruby / Rails和Python / Django的Spring新手。来自这些框架,我以前只看到模型(Entity / Dao?),其他一切都由Framework / ORM / QueryBuilders处理,因此我要做的就是声明一个模型并添加任何模型我需要的操作/关系/方法。
在这些框架中,这就是我所拥有的:
class User extends BaseModel
{
public function devices() { .. } // Relation to Device model
// Any additional functions on user go here these can operate on
// just the User model or pull additional data from DB or other models.
public function assignUserToDevice();
public function getUsersScore();
public function connectUserToService();
}
然而,按照本春季教程,我现在有了这个:
Model(Entity / Dao?):除了GET / SET和关系之外,只包含没有方法的属性。
@Entity
@Table(name = "users")
class User {
@Id
@GeneratedValue
var id: Long = 0
var username: String = "" //...
}
存储库:
interface UserRepository : CrudRepository<User, Long> {
fun findByUsername(username: String): User
}
UserServiceContract:
interface UserServiceContract {
/**
* Attempts to find User associated with the given id.
* @throws ModelNotFoundException if not user has been found associated with the given id.
* @param id given users id.
* @return User associated with the given id.
*/
@Throws(ModelNotFoundException::class)
fun find(id: Long): User
/**
* Returns all existing users.
* @return list of all existing users.
*/
fun findAll(): List<User>
}
一项服务:
@Service
class UserService : UserServiceContract {
@Autowired
lateinit var userRepository: UserRepository
/**
* Attempts to find User associated with the given id.
* @throws ModelNotFoundException if not user has been found associated with the given id.
* @param id given users id.
* @return User associated with the given id.
*/
override fun find(id: Long) = userRepository.findOne(id) ?: throw ModelNotFoundException("User not found!")
override fun findAll(): List<User> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
问题:
为什么我需要UserRepository
和UserService + UserServiceContract
?从我在存储库的Spring指南中读到的内容,您已经获得了默认的CRUD
方法save, read, update, delete..
,您还可以使用查询方法来执行findUserBy...
或编写带注释的原始查询。所以我有点困惑为什么只声明UserServiceContract
和UserService
来实现存储库已经提供的功能?
以前我会保留在模型中使用我的模型的方法,但是我从少数资源中注意到这不是他们在Spring中的位置,所以我在哪里保留它们?这就是UserService
和UserServiceContract
的原因吗?
我是否应该仅使用UserRepository
进行数据库访问,并使用UserServiceContract
声明方法来处理/与用户一起工作,如:public function connectUserToService()
?
答案 0 :(得分:1)
用户是实体。它基本上表示数据库中表的一行。它绝对可以有方法。将实体与该实体无关的方法仅放在实体类中通常不是一个好主意。特别是不需要访问外部依赖项的方法(如存储库或服务)。
Repository是允许执行与给定实体相关的查询或保存该实体的新实例的组件。
该服务包含业务逻辑。它可以像简单地委托给存储库一样简单,但除非您的应用程序只包含从数据库查看信息,否则它通常包含更复杂的逻辑,涉及多个实体和存储库。
将存储库与服务分开很有用,因为它允许
您是否使用界面来定义服务合同取决于您。 Spring并没有强迫你这样做。你也可以混合使用服务和存储库,如果你想用脚射击自己,但Spring不鼓励它,如果你使用spring-data-jpa,你将无法做到这一点,它基本上会生成一个基于接口的存储库实现。
我对你习惯的框架了解不多,但是在考虑spring应用程序的设计时需要牢记这一点:Spring是一个依赖注入框架,因此包含将组件注入其他组件。实体不是Spring组件,因此如果它们包含业务逻辑(再次混合职责,IMO),则不能注入它们所需的依赖项。依赖注入本身主要用于制作代码 可测试的,并且能够添加方法调用的方面(例如,启动和提交事务)。这就是驱动Spring设计的原因:单一责任原则,依赖注入的可测试性,以及。