我正在使用 Spring Data REST 和 Angular 构建一个网站,该网站连接到我的 mySQL-DB。
通过这样的 http 请求,我将获取我的数据:
$scope.getAllHolidays = function(){
var URL = String('http://localhost:8080/holidays?projection=noHolidayweek');
$http({
url: URL,
method: 'GET',
contentType: 'application/json'
})
.then(useData);
};
现在它将为我带来所有假期及其信息(包括由外键连接的数据)。 我的结果如下:
"_embedded" : {
"holidays" : [ {
"strTitle" : "Summer 2016",
"byteHolidayReason" : 0,
"bolEnabled" : false,
"holidayweek" : [ {
"shortYear" : 2016,
"byteWeek" : 29,
"occupancy" : [ { <-- joined table
"intNumber" : 0,
}, {
"intNumber" : 3,
}, {
"intNumber" : 2,
{ AND SO ON (LARGE ARRAY) }]
}]
但我的问题是,我只想获取特定信息,而无需连接中的数据,因为它包含大量数据,此时毫无用处。
更新: 我添加了我的模型和 Controller ,并在我的存储库中创建了一个投影,就像 @Valerio Vaudi 向我建议的那样,但它仍然不起作用。
我的模型(main.holiday.model):
@Entity
public class Holiday {
public Holiday(){
}
@Id
@Column(name="holiday_id")
private Long LongHoliday_id = main.modules.calcID.calculateID();
@Column(name="Title")
private String strTitle;
@Column(name="HolidayReason")
private byte byteHolidayReason;
//0=Sommer
//1=Winter
@Column(name="Enabled")
private boolean bolEnabled;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "holiday_id")
private Set<Holidayweek> holidayweeks = new HashSet<Holidayweek>();
//setter & getter
我的存储库(main.holiday.controller):
public interface HolidayRepository extends PagingAndSortingRepository<Holiday, Long>,
QueryDslPredicateExecutor<Holiday> {
}
@Projection(name = "noHolidayweek", types = {Holiday.class})
interface NoHolidayweek{
Long getLongHoliday_id();
String getStrTitle();
Byte getByteHolidayReason();
Boolean getBolEnabled();
}
请帮助我!
最佳答案
如果你想减少信息量,可以考虑投影技术,我建议阅读有关此主题的文档 Projection 。
考虑如下模型:
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
private String street;
private String city;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Address> addressList;
…
}
假设它有太多信息,而你想要更少的信息,你可以这样做:
声明一个如下所示的接口(interface)
@Projection(name = "personProjectionCriteria", types = Person.class)
public interface PersonProjectionCriteria {
String getFirstName();
String getLastName();
}
@RepositoryRestResource(excerptProjection = PersonProjectionCriteria.class)
public interface PersonRepository extends CrudRepository<Person, Long> {
}
然后在您的网址中使用它,如下所示
http://localhost:8080/person ?projection=personProjectionCriteria。
更新 一个重要的想法是,标记为@Projection的接口(interface)必须位于域类型的同一个包(或子包)中。
我按照我想说的方式发布了一些文档屏幕。 [ 2 ]
如果这种方法还不够,您应该考虑使用经典的 Spring MVC 或 JAx-RS 方法构建您自己的 REST API,并执行细粒度的调整。
希望对你有帮助
更新 在您发布代码后,我尝试修复错误并在我的 githHub 链接 code 中你可以找到解决方案。在 fork 的存储库中,您可以看到许多更改,因为在 2016 年 5 月 8 日 fork 时的代码中,我发现代码布局和代码本身存在许多错误。以有序的方式发布的代码中,您的错误实际上并不存在,因为您定义了一个具有依赖关系的实体,但在为该实体定义了存储库接口(interface)之后。在这种情况下,Spring data Rest 将用链接替换嵌入的依赖项。事实上,如果您没有定义如下所示的存储库接口(interface),Spring 数据休息将插入嵌入的实体关系,并且您会遇到问题中描述的问题。
@RepositoryRestResource
public interface HolidayweekRepository extends PagingAndSortingRepository<Holidayweek, Long> {
}
克服它的唯一方法是定义一个投影并按照我上面在我的答案中描述的那样应用它。在您的代码中,我在 Controller 包中找到投影,而不是在模型包中,因此您可以继续受益于投影。
在 fork 存储库的链接中,我以一种无法获取关系数据的方式更正了代码,但如果您不想要它并且您想要使用投影的好处,则可以获取链接,您已经删除了关系实体的存储库接口(interface),并在模型包而不是 Controller 包下定义投影接口(interface),并且如果您希望投影默认应用在/holidays url 中,则 intert excerptProjection = NoHolidayweek.class 或者不要将其插入到 @RepositoryRestResource 如果你不想要这种行为。
我希望现在一切都清楚了。
关于mysql - 具有特定结果的 Spring Data Rest 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38612887/