首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Spring Boot框架对基于Spring JPA的DAO进行分层的正确方法

使用Spring Boot框架对基于Spring JPA的DAO进行分层的正确方法
EN

Stack Overflow用户
提问于 2015-04-01 08:48:49
回答 2查看 21.3K关注 0票数 9

我是Spring Boot &JPA的新手。

假设我有两个实体映射到两个表,这两个表在一个数据库中联接。

学生-1-<-课程

另外,让我们假设数据库已经创建并填充。

这描绘了一个学生有许多课程...

我的学生实体:

代码语言:javascript
复制
@Entity
public class Student {

    @OneToMany(mappedBy="student")
    private List<Courses> courses;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Student_Id")
    private long studentId;

    @Column(name = "Student_Name")
    private String studentName;

    protected Student() { }

    // Getters & Setters
}

我的课程实体:

代码语言:javascript
复制
@Entity
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Course_Id")
    private long courseId;

    @Id
    @Column(name = "Student_Id")
    private long studentId;

    @ManyToOne
    @PrimaryKeyJoinColumn(name="Student_Id", referencedColumnName="Student_Id")
    private Student student;

    @Column(name = "Course_Name")
    private String courseName;

    // Getters & Setters

}

在Spring Boot的教程指南中,它演示了如何扩展CrudRepository接口,但没有指定如何设置基于Spring的DAO,该DAO包含使用HQL和EntityManager的自定义查找器方法。

下面的DAO和DaoImpl是否正确?

代码语言:javascript
复制
public interface CourseDao {
    List<Course> findCoursesByStudentName(String studentName);
}

@Repository
public class CourseDaoImpl implements CourseDao {

    @PersistenceContext
    EntityManager em;

    public List<Course> findCoursesByStudentName(String studentName) {
        String sql = "select c.courseName" +
                     "from Course c, Student s " +
                     "where c.course_id = s.student_id " +
                     "and s.studentName = :studentName ";

        Query query = em.createQuery(sql);
        query.setParameter("studentName", studentName);
        return query.getResultList();
    }
}   

然后在客户机代码中,例如,在主类中:

代码语言:javascript
复制
 public class Application {

    @Autowired
    CustomerDao dao;

    public static void main (String args []) {
        List<Course> courses = dao.findCoursesByStudentName("John");
    }   
 }

这是在Spring DAOs中使用HQL的标准方式吗?我已经看到了@Transactional注解被放在DAO类的impl前面的例子(例如CustomerDAOImpl)?

请让我知道这是否是构建我的Spring Boot应用程序的编写方式,或者我应该只扩展/添加到CrudRepository?

如果有人能纠正我的例子,并给我指出一个URL,其中谈到使用连接的实体的HQL,我将非常感激。

Spring Boot指南并没有描述joins或DAOs -我只需要学习如何正确地创建查找器方法来模拟select语句,从而返回列表或数据结构。

感谢您抽出时间阅读这篇文章。

EN

回答 2

Stack Overflow用户

发布于 2015-04-01 16:03:12

如果我没理解错你的问题,你有两个问题:

  1. 如何创建DAO和DAOImpl?
  2. 在何处放置事务批注?

关于第一个问题,我想指出的是,这是一个关于使用Hibernate作为JPA提供者的spring-data-jpa的问题,而不是spring-boot

使用Spring Data时,我通常会完全跳过创建DAO,而直接使用自定义存储库来扩展标准的存储库,比如CrudRepository。因此,在您的示例中,您甚至不需要编写比以下代码更多的代码:

代码语言:javascript
复制
@Repository
public interface StudentRepository extends CrudRepository<Student, Long> {

    List<Student> findByStudentName(String studentName);

}

这就足够了,如果您使用

代码语言:javascript
复制
@Autowired
StudentRepository studentRepo; 

在你的服务班里。这也是我通常用@Transactional注释我的方法的地方,以确保一切都像预期的那样工作。

关于你关于HQL的问题,请查看spring data jpa documentation,它指出在大多数情况下,在接口中坚持正确的命名方法或进行命名查询(3.3.3节)或使用@Query注释(3.3.4节)手动定义查询就足够了,例如应该工作(未尝试):

代码语言:javascript
复制
@Repository
public interface @CourseRepository extends CrudRepository<Course, Long> {

    @Query("select c.courseName from Course c, Student s where c.course_id = s.student_id and s.studentName = :studentName")
    public List<Course> findCoursesByStudentName(String studentName);

}
票数 13
EN

Stack Overflow用户

发布于 2015-04-01 09:13:00

如果您使用@Transactional注释您的CourseDaoImpl (假设您已经正确定义了JpaTransactionManager ),那么您就可以检索具有匹配名称的学生,并调用getCourses()方法来延迟加载附加到该学生的课程。由于findCoursesByStudentName将在事务内运行,因此它将很好地加载课程。

代码语言:javascript
复制
@Repository
@Transactional(readOnly=true)
public class CourseDaoImpl implements CourseDao {

    @PersistenceContext
    EntityManager em;

    public List<Course> findCoursesByStudentName(String studentName) {
        String sql = "select s " +
                     "from Student s " +
                     "where s.studentName = :studentName ";

        Query query = em.createQuery(sql);
        query.setParameter("studentName", studentName);
        User user = query.getSingleResult();
        if(user != null) {
            return user.getCourses();
        }

        return new ArrayList<Course>();
    }
}   
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29381058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档