天貓項目(6)屬性管理

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啊?這裏下一步還需要思考。

屬性關係就暫時寫到這裏,不懂得地方還有很多,自己也纔在這條路上剛剛開始

謝謝觀看

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章