Pac*_*ver 10 spring hibernate jpa hql spring-boot
我是Spring Boot和JPA的新手......
假设我有两个实体映射到两个表,这两个表在数据库中连接.
学生 - 1 ------ < - 课程
另外,假设已经创建并填充了数据库.
这表明一个学生有很多课程......
我的学生实体:
@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
}
Run Code Online (Sandbox Code Playgroud)
我的课程实体:
@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
}
Run Code Online (Sandbox Code Playgroud)
在Spring Boot的教程指南中,它说明了如何扩展CrudRepository接口,但它没有指定如何设置基于Spring的DAO,其中包含在其中使用HQL和EntityManager的自定义查找程序方法.
以下DAO和DaoImpl是否正确?
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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后在客户端代码中,例如,在主类中:
public class Application {
@Autowired
CustomerDao dao;
public static void main (String args []) {
List<Course> courses = dao.findCoursesByStudentName("John");
}
}
Run Code Online (Sandbox Code Playgroud)
这是在Spring DAO中使用HQL的标准方法吗?我已经看到@Transactional注释的例子被添加到DAO类的impl(例如CustomerDAOImpl)之前?
如果这是构建我的Spring Boot应用程序的写入方式,或者我应该仅扩展/添加到CrudRepository,请告诉我?
如果有人可以更正我的示例并指向我使用已加入的实体来讨论HQL的URL,我将非常感激.
Spring Boot指南没有描述连接或DAO - 我只需要学习如何正确创建finder方法,该方法模拟返回列表或数据结构的select语句.
感谢您抽时间阅读...
dan*_*ten 12
如果我理解你的问题是正确的,你有两个问题:
关于第一个问题,我想指出这是一个关于将spring-data-jpa
Hibernate用作JPA提供程序的问题,而不是spring-boot
.
使用Spring Data我通常会完全跳过创建DAO但直接使用自定义存储库扩展标准的类似CrudRepository
.因此,在您的情况下,您甚至不必编写更多代码:
@Repository
public interface StudentRepository extends CrudRepository<Student, Long> {
List<Student> findByStudentName(String studentName);
}
Run Code Online (Sandbox Code Playgroud)
这将是足够的,如果您使用,Spring Data将负责使用正确的实现填充它
@Autowired
StudentRepository studentRepo;
Run Code Online (Sandbox Code Playgroud)
在您的服务类中.这也是我通常用我的方法注释的地方,@Transactional
以确保一切都按预期工作.
关于你关于HQL的问题,请查看spring数据jpa文档,它指出对于大多数情况来说,在接口中坚持使用正确的命名方法或者进行命名查询(第3.3.3节)或使用@Query
注释(第3.3.4节)手动定义查询,例如应该工作(没试过):
@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);
}
Run Code Online (Sandbox Code Playgroud)
如果您使用注释CourseDaoImpl
(@Transactional
假设您已JpaTransactionManager
正确定义),您只需检索具有匹配名称的学生并调用该getCourses()
方法来延迟加载附加到该学生的课程。由于findCoursesByStudentName
将在事务中运行,因此它将很好地加载课程。
@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>();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
17323 次 |
最近记录: |