Property是Category的子模塊,是多對一的關係,所以,這裏的代碼,要解決的問題也就是這個。
1.pojo
@Entity
@Table(name = "property")
@JsonIgnoreProperties({
"handler","hibernateLazyInitializer"
})
public class Property {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@ManyToOne
@JoinColumn(name = "cid")
private Category category;
//省略set,get,tostring
}
在類中加上映射的對象category,並且用@ManyToOne註解修飾,然後用@JoinColumn(name = "cid")給出外鍵
後面的vue中接受數據的的data,也要如此設計
2.dao
public interface PropertyDAO extends JpaRepository<Property,Integer>{
Page<Property> findByCategory(Category category, Pageable pageable);
}
給出一個通過category查找對應的property的方法的聲明
3.service
@Service
public class PropertyService {
@Autowired
PropertyDAO propertyDAO;
@Autowired
CategoryService categoryService;
public void add(Property bean){
propertyDAO.save(bean);
}
public void delete(int id){
propertyDAO.delete(id);
}
public Property get(int id){
return propertyDAO.findOne(id);
}
public void update(Property bean){
propertyDAO.save(bean);
}
public Page4Navigator<Property> list(int cid, int start, int size, int navigatePages) {
//Property對應分類的id
Category category = categoryService.get(cid);
Sort sort = new Sort(Sort.Direction.DESC,"id");
Pageable pageable = new PageRequest(start, size, sort);
Page<Property> pageFromJPA = propertyDAO.findByCategory(category, pageable);
return new Page4Navigator<>(pageFromJPA, navigatePages);
}
}
唯一值得一提的service中的方法就是list,因爲需要根據category查找property,所以需要注入CategoryService,這也是多對一關係映射業務處理中的一個步驟
3.controller
那個跳轉的controller我就不說了,跟之前的規則差不多
說一下PropertyController
@RestController
public class PropertyController {
@Autowired
PropertyService propertyService;
@GetMapping("/categories/{cid}/properties")
public Page4Navigator<Property> list(@PathVariable("cid") int cid,
@RequestParam(value = "start", defaultValue = "0")
int start,@RequestParam(value = "size", defaultValue = "5")
int size){
start = start<0?0:start;
Page4Navigator<Property> page = propertyService.list(cid, start, size, 5);
return page;
}
@GetMapping("/properties/{id}")
public Property get(@PathVariable("id") int id) {
Property bean = propertyService.get(id);
return bean;
}
@PostMapping("/properties")
public Object add(@RequestBody Property bean) {
propertyService.add(bean);
return bean;
}
@DeleteMapping("/properties/{id}")
public String delete(@PathVariable("id") int id) {
propertyService.delete(id);
return null;
}
@PutMapping("/properties")
public Object update(@RequestBody Property bean) {
propertyService.update(bean);
return bean;
}
}
這裏需要額外注意的還是list方法,這裏的url設計是重點,後面的vue,中的list的ajax請求的url也要如此設計
其他操作其實沒有變化,只有list方法的操作是不同的
4.listProperty.html
<script>
$(function () {
var cid = getUrlParms("cid");
var data4Vue = {
uri: 'properties',
beans: [],
pagination: {},
bean: {id:0,name:'',category:{id:0}},
category: ''
};
//ViewModel
var vue = new Vue({
el: '#workingArea',
data: data4Vue,
mounted:function () {
//mounted 表示這個Vue被加載成功了
this.getCategory(cid);
this.list(0);
},
methods: {
getCategory: function (cid) {
var url = "categories/" + cid;
axios.get(url).then(function (response) {
vue.category = response.data;
})
},
list: function (start) {
var url = "categories/"+ cid + "/" + this.uri + "?start=" + start;
axios.get(url).then(function (response) {
vue.beans = response.data.content;
vue.pagination = response.data;
});
},
add: function () {
if (!checkEmpty(this.bean.name, "屬性名稱"))
return;
var url = this.uri;
this.bean.category.id = cid;
axios.post(url, this.bean).then(function (response) {
vue.list(0);
vue.bean = {id: 0, name: '', category: {id: 0}};
});
},
jump: function (page) {
jump(page,vue);
},
jumpByNumber: function (start) {
jumpByNumber(start,vue);
},
//delete是保留字
deleteBean: function (id) {
//這裏其實會出現一個確認刪除的提示框
if (!checkDeleteLink())
return;
//url規範,說實話這裏的接口其實是和controller映射一致的吧
var url = this.uri + "/" + id;
axios.delete(url).then(function (response) {
//刪除成功會返回一個空字符串
if (0!=response.data.length)
alert(response.data);
else {
//刪除成功,返回第一頁
vue.list(0);
}
})
}
}
});
});
</script>
其實代替上設計大同小異,我們主要聚焦實現多對一查詢的部分,尤其是url,以及list方法的實現,這個是實現這個業務邏輯的重點
data部分,bean中多了一個category對象,這裏我突然又想到了一個點,這裏出現的對象的屬性,其實是和pojo中映射到的屬性是一致的,如果沒有映射到,就不會出現,具體的理解我也沒有形成自己完整的看法,等待後一步的學習吧
這裏的url適合mapping綁定的
爲了更方便看出整個流程這裏,我再把listCategory中的鏈接代碼放出來
<a :href="'admin_property_list?cid=' + bean.id "><span class="glyphicon glyphicon-th-list"></span></a>
get方法,先根據請求的url的cid得到property所屬的category對象,然後查詢list出所有的property屬性,這裏有一個想到了,就是ajax的axios的數據綁定機制,下去以後還要查閱資料思考
add方法呢,就是根據已經綁定的bean的category屬性,以及提交的bean數據,創建一個新的bean然後post上去,然後初始化掉
<a href="#nowhere" @click="deleteBean(bean.id)"><span class=" glyphicon glyphicon-trash"></span></a>
deleteBean呢,就直接在當前頁面調用函數就可以了,突然想到一個點,因爲這裏實現的是雙向的綁定,所以也不用刷新,只要後臺刪除掉一個property,頁面就會自動減少一個bean,感覺自己好像感受到一點點雙向綁定的意思了
最後給一下跳轉eidt頁面的鏈接,我們就進入下一部分代碼
<a :href="'admin_property_edit?id=' + bean.id "></a>
可以看出,傳遞了id的屬性
5.editProperty.html
還是先看vue的部分
<script>
$(function () {
var data4Vue = {
uri: 'properties',
listURL: 'admin_property_list',
bean: '',
category: ''
};
//ViewModel
var vue = new Vue({
el: '#workingArea',
data: data4Vue,
mounted:function () {
this.get();
},
methods: {
get: function () {
//把id從地址欄中取出來
var id = getUrlParms("id");
//結果類似/properties/3這種形式
var url = this.uri + "/" + id;
axios.get(url).then(function (response) {
vue.bean = response.data;
vue.category = vue.bean.category;
});
},
update: function () {
if(!checkEmpty(this.bean.name,"屬性名稱"))
return;
var url = this.uri;
axios.put(url,vue.bean).then(function (response) {
//上傳後直接跳轉到list的URL,通過對location對象的操作
location.href = vue.listURL+"?cid="+vue.category.id;
});
}
}
})
})
</script>
這裏我想到了一個點,就是如果想通過頁面把一個參數傳到下一個參數,在下一個頁面如果想用到這個就要通過我們自己封裝的函數getUrlParams()傳入想要從url中提取的PathVariabel來獲取
這裏在獲取到id以後,還是通過查後端的代碼,通過ajax請求get到這個property的屬性,完成bean的綁定,其實在update框中其實綁定了bean的name屬性,默認顯示的也是這個,然後實現了一個update方法
在還有一個點,就是vue中的data需要封裝哪些的問題,這個其實是由我們需要的數據對象的集合決定的,就好比這裏,只需要提取出一個category,然後給出一個bean(只對一個bean進行操作就夠了)用來提交就可以了,至於bean中有哪些屬性,不知道爲何沒有給出?是因爲上一步已經給出了麼,但在進行get方法時,也用到了vue.bean.category啊?這裏下一步還需要思考。
屬性關係就暫時寫到這裏,不懂得地方還有很多,自己也纔在這條路上剛剛開始
謝謝觀看