(一)QueryDsl簡介
這邊簡介我就不從各大網站的文章中copy過來了,這邊給個官網的中文翻譯傳送門:http://books.aying.org/querydsl_zh_CN/Introduction.html
(二)引入QueryDsl
2.1 依賴
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
2.2 plugin
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
JPAAnnotationProcessor 查找帶有 javax.persistence.Entity 注解的領域類型並為其生成查詢類型。簡單來說,比如有個Student的entity,運行clean install 會在項目的target/generated-sources/java 目錄下將生成QStudent,這個QStudent就是查詢類型類。
(三)實體 Student類
@Table(name = "student")
@Entity
public class Student {
@Id
@GeneratedValue(
strategy = GenerationType.IDENTITY
)
private long id;
private String name;
private int age;
private long schoolId;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public long getSchoolId() {
return schoolId;
}
public void setSchoolId(Long schoolId) {
this.schoolId = schoolId;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", schoolId=" + schoolId +
'}';
}
}
運行mvn clean install后生成的QStudent
@Generated("com.querydsl.codegen.EntitySerializer")
public class QStudent extends EntityPathBase<Student> {
private static final long serialVersionUID = -5814978L;
public static final QStudent student = new QStudent("student");
public final NumberPath<Integer> age = createNumber("age", Integer.class);
public final NumberPath<Long> id = createNumber("id", Long.class);
public final StringPath name = createString("name");
public final NumberPath<Long> schoolId = createNumber("schoolId", Long.class);
public QStudent(String variable) {
super(Student.class, forVariable(variable));
}
public QStudent(Path<? extends Student> path) {
super(path.getType(), path.getMetadata());
}
public QStudent(PathMetadata metadata) {
super(Student.class, metadata);
}
}
(四)查詢
4.0 QueryDslTest測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class QueryDslTest {
@Autowired
@PersistenceContext
private EntityManager entityManager;
private JPAQueryFactory queryFactory;
@Before
public void init() {
queryFactory = new JPAQueryFactory(entityManager);
}
}
4.1 簡單查詢
@Test
public void selectStudent(){
QStudent qStudent = QStudent.student;
List<Student> students = queryFactory.selectFrom(qStudent).fetch();
System.out.println(students);
}
4.2 單表條件查詢
@Test
public void selectStudentWithWhere() {
QStudent qStudent = QStudent.student;
//單表單條件查詢
List<Student> students = queryFactory.selectFrom(qStudent).where(qStudent.age.goe(2)).fetch();
//單表多條件and查詢
List<Student> studentList = queryFactory.selectFrom(qStudent).where(qStudent.age.goe(2).and(qStudent.name.eq("vincent"))).fetch();
//單表多條件or查詢
List<Student> list = queryFactory.selectFrom(qStudent).where(qStudent.age.goe(20).or(qStudent.name.eq("vincent"))).fetch();
//單表排序分頁查詢
List<Student> list1 = queryFactory.selectFrom(qStudent).offset(1).limit(3).orderBy(qStudent.id.desc()).fetch();
System.out.println(students);
System.out.println(studentList);
System.out.println(list);
System.out.println(list1);
}
4.3 多表查詢
@Test
public void selectStudent1() {
QStudent qStudent = QStudent.student;
QSchool qSchool = QSchool.school;
List<Student> students = queryFactory.select(qStudent).from(qSchool, qStudent).where(qSchool.id.eq(qStudent.schoolId)).fetch();
System.out.println(students);
}
以上查詢的結果只是student的表的值,比如我現在關心學校名稱,那么這樣子就不能得到,用下面的做法可以得到你想要的值
@Test
public void selectStudent2() {
QStudent qStudent = QStudent.student;
QSchool qSchool = QSchool.school;
List<Tuple> students = queryFactory.select(qStudent.age, qStudent.name, qSchool.name).from(qSchool, qStudent).where(qSchool.id.eq(qStudent.schoolId)).fetch();
List<Map<String, Object>> maps = students.stream().map(tuple -> {
Map<String, Object> map = new HashMap<>();
map.put("studentName", tuple.get(qStudent.name));
map.put("age", tuple.get(qStudent.age));
map.put("schoolName", tuple.get(qSchool.name));
return map;
}).collect(Collectors.toList());
System.out.println(maps);
}
4.4 leftjoin查詢
@Test
public void selectStudent3() {
QStudent qStudent = QStudent.student;
QSchool qSchool = QSchool.school;
List<Student> students = queryFactory.select(qStudent)
.from(qStudent)
.leftJoin(qSchool)
.on(qStudent.schoolId.eq(qSchool.id))
.fetch();
System.out.println(students);
}
這段代碼本身是沒有問題的,不過按照之前的配置運行起來將會報以下錯誤,如何解決我在后面另寫一個文章。
2018-09-06 10:25:25.678 ERROR 4742 --- [ main] o.h.hql.internal.ast.ErrorCounter : Path expected for join! 2018-09-06 10:25:25.686 ERROR 4742 --- [ main] o.h.hql.internal.ast.ErrorCounter : Path expected for join! antlr.SemanticException: Path expected for join! at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:368) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3912) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3698) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3576) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:716) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:572) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:309) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:257) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:262) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1894) [hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) [hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144] at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347) [spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE] at com.sun.proxy.$Proxy91.createQuery(Unknown Source) [na:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144] at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) [spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE] at com.sun.proxy.$Proxy91.createQuery(Unknown Source) [na:na] at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:101) [querydsl-jpa-4.1.4.jar:na] at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:94) [querydsl-jpa-4.1.4.jar:na] at com.querydsl.jpa.impl.AbstractJPAQuery.fetch(AbstractJPAQuery.java:201) [querydsl-jpa-4.1.4.jar:na] at com.vincent.QueryDslTest.selectStudent4(QueryDslTest.java:129) [test-classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144] at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) [junit-4.12.jar:4.12] at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12] at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) [junit-4.12.jar:4.12] at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.12.jar:4.12] at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.12.jar:4.12] at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) [spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) [spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) [spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) [junit-4.12.jar:4.12] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) [spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) [spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12] at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) [spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12] at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) [junit-rt.jar:na] at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) [junit-rt.jar:na] at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) [junit-rt.jar:na] at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) [junit-rt.jar:na] java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [select student from com.vincent.model.Student student left join School school with student.schoolId = school.id where student.name = ?1] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1679) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:294) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347) at com.sun.proxy.$Proxy91.createQuery(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) at com.sun.proxy.$Proxy91.createQuery(Unknown Source) at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:101) at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:94) at com.querydsl.jpa.impl.AbstractJPAQuery.fetch(AbstractJPAQuery.java:201) at com.vincent.QueryDslTest.selectStudent4(QueryDslTest.java:129) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [select student from com.vincent.model.Student student left join School school with student.schoolId = school.id where student.name = ?1] at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:268) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1894) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) ... 45 more
(五)更新
在Querydsl JPA中,更新語句是簡單的 update-set/where-execute 形式。
execute()執行后返回的是被更新的實體的數量。
@Test
public void testUpdate() {
QStudent qStudent = QStudent.student;
Long result = queryFactory.update(qStudent)
.set(qStudent.name, "haha")
.where(qStudent.id.eq(111L)).execute();
assertThat(result,equalTo(1L));
}
這段代碼運行后會報錯,錯誤如下
javax.persistence.TransactionRequiredException: Executing an update/delete query at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:54) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:372) at com.sun.proxy.$Proxy102.executeUpdate(Unknown Source) at com.querydsl.jpa.impl.JPAUpdateClause.execute(JPAUpdateClause.java:77) at com.vincent.QueryDslTest.testUpdate(QueryDslTest.java:156) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
原因是jpa的update和delete需要加上@Transactional注解,這個細節很重要
可執行版本如下
@Test
@Transactional
public void testUpdate() {
QStudent qStudent = QStudent.student;
Long result = queryFactory.update(qStudent)
.set(qStudent.name, "haha")
.where(qStudent.id.eq(111L)).execute();
assertThat(result,equalTo(1L));
}
(六)刪除
刪除語句是簡單的 delete-where-execute 形式。
@Test
@Transactional
public void testDelete() {
QStudent qStudent = QStudent.student;
//刪除指定的一個
Long result = queryFactory.delete(qStudent)
.where(qStudent.id.eq(111L))
.execute();
assertThat(result, equalTo(1L));
//刪除所有
Long totalResult = queryFactory.delete(qStudent)
.execute();
System.out.println(totalResult);
}
