# 一.組合關係javascript
> 組合就是強聚合 ,聚合就是雙向的多對一,一對多
>> 強:最強級聯 一方放棄關係維護
>>> 單據都會用到組合關係
>>>> 保存的時候雙方都能找到對象```
//一方的配置
/**
cascade = CascadeType.ALL:包含全部級聯(增刪改)
orphanRemoval = true:孤兒刪除
mappedBy = "bill":放棄關係維護
*/java
@OneToMany(cascade = CascadeType.ALL, mappedBy = "bill", fetch = FetchType.LAZY, orphanRemoval = true) private List<Purchasebillitem> items = new ArrayList<Purchasebillitem>(); //多方的配置 @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "bill_id") @JsonIgnore private Purchasebill bill;// 組合關係,非空
```mysql
# 二.日期查詢問題## 2.1 SpringMVC獲取與設置日期
```sql
get -> @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") set -> @DateTimeFormat(pattern = "yyyy-MM-dd")
```json
## 2.2 easyui的日期控件
```app
<div id="cc" class="easyui-calendar"></div> <input name="beginDate" class="easyui-datebox" data-options="sharedCalendar:'#cc'" style="width:120px">
```
## 2.3 怎麼解決查詢有時分秒的問題
> 結束時間加一/大於等於開始時間,==小於結束時間==
```fetch
//準備一個方法,建立相應的條件規則 public Specification createSpec(){ //結束時間加一天 Date tempDate = null; if(endDate!=null){ tempDate = DateUtils.addDays(endDate, 1); } //gt:大於 ge:大於等於 //lt:小於 le:小於等於 Specification<Purchasebill> spec = Specifications.<Purchasebill>and() .ge(beginDate!=null,"vdate",beginDate) .lt(endDate!=null,"vdate",tempDate) .eq(status!=null,"status",status) .build(); return spec; }
```ui
# 三.明細的問題
> 控件:http://www.easyui-extlib.com/ ->Datagrid-Edit -單元格編輯
須要導入jsthis
## 3.1 研究控件的代碼含義
```
url
//設置一些基本數據 var dg = $("#dg1"), defaultRow = { ID: "", Code: "", Name: "", StandardModel: "", ApplyCount: "", Remark: "", Stocks: "" }, insertPosition = "bottom"; //作一些基本的配置(建立datagrid控件) var dgInit = function () {... //拿到剛添加的行數 var getInsertRowIndex = function () { ... //綁定相應的事件 var buttonBindEvent = function () { //進入頁面先執行相應的代碼 dgInit(); buttonBindEvent();
```
## 3.2 數據修改
```
//完成editgrid的功能 //定義定量 //dg:拿到編輯的grid defaultRow:默認有哪些數據 insertPosition:插入數據的位置(底部) var dg = $("#itemsGrid"), defaultRow = { product: "", productColor: "", productImg: "", num: 0, price: 0, amount: 0, descs: "" }, insertPosition = "bottom"; // 對grid的初始化設置 var dgInit = function () { var getColumns = function () { var result = []; //商品搞成下拉框,從後臺獲取到商品數據 var normal = [ { field: 'product', title: '商品', width: 80, editor: { type: "combobox", options: { required: true, panelHeight:'auto', valueField:'id', textField:'name', url:'/util/findProducts' } }, //加上format顯示產品的名稱 formatter:function (v,r,i) { if(v)return v.name; } }, { field: 'productColor', title: '顏色', width: 40, formatter: function (v, r, i) { if(r && r.product){ return `<div style="height: 20px;width: 20px;background: ${r.product.color}"></div>`; } } }, { field: 'productImg', title: '圖片', width: 100, formatter: function (v, r, i) { if(r && r.product){ return "<img src='"+r.product.smallpic+"' alt='沒有圖片' />"; } } }, { field: 'num', title: '數量', width: 100, editor: { type: "numberbox", //只容許輸入數字 options: { precision:2, //保留兩位小數 required: true } } }, { field: 'price', title: '價格', width: 100, editor: { type: "numberbox", options: { precision:2, required: true } } }, { field: 'amount', title: '小計', width: 100, formatter: function (v, r, i) { if(r.num && r.price){ //toFixed:保存幾位小數 return (r.num * r.price).toFixed(2); } return 0; } }, { field: 'descs', title: '備註', width: 100, editor: { type: "text" } } ]; result.push(normal); return result; }; var options = { idField: "ID", rownumbers: true, fitColumns: true, fit: true, border: true, title:"明細編輯", singleSelect: true, toolbar:"#itemsBtns", columns: getColumns(), //表示開啓單元格編輯功能 enableCellEdit: true }; dg.datagrid(options); }; //插入的行的位置(索引) var getInsertRowIndex = function () { return insertPosition == "top" ? 0 : dg.datagrid("getRows").length; } //按鈕的綁定事件 var buttonBindEvent = function () { //添加一行數據 $("#btnInsert").click(function () { var targetIndex = getInsertRowIndex(), targetRow = $.extend({}, defaultRow, { ID: $.util.guid() }); //在datagrid中插入一行數據 dg.datagrid("insertRow", { index: targetIndex, row: targetRow }); //哪一行的哪一列要進行編輯 dg.datagrid("editCell", { index: targetIndex, field: "product" }); }); //刪除一行數據 $("#btnRemove").click(function () { //獲取選中的行 var row = dg.datagrid("getSelected"); //獲取這一行的索引 var index = dg.datagrid("getRowIndex",row); //根據索引刪除這一行 dg.datagrid("deleteRow",index); }); }; //調用是相應的方法 dgInit(); buttonBindEvent();
```
## 3.3 添加與修改
> 添加時清空明細
`dg.datagrid("loadData",[]);`
> 修改時回顯明細
```
//回顯我們的明細數據
//複製一個明細數據
var newItems = [...row.items];
dg.datagrid("loadData",newItems);
```> 保存時提交明細數據
```
//items[index]. editForm.form('submit', { //form提交的路徑 url:url, //提交以前你要作什麼事件 onSubmit: function(param){ // 加一些本身的參數過去 //1.拿到編輯明細的全部數據 var rows = dg.datagrid("getRows"); //2.遍歷全部數據,拼接成我們須要的格式的參數 //items[0].product.id=1 for(let i=0;i<rows.length;i++){ var json = rows[i]; param[`items[${i}].product.id`] = json.product.id; param[`items[${i}].num`] = json.num; param[`items[${i}].price`] = json.price; param[`items[${i}].descs`] = json.descs; } // return false to prevent submit; 返回false阻止提交 return $(this).form('validate'); },
```
## 3.4 後臺保存與計算
> 雙向找到對方,而且進行計算
```
private JsonResult saveOrUpdate(Purchasebill purchasebill){ JsonResult jsonResult = new JsonResult(); try { //拿到採購訂單的全部明細 List<Purchasebillitem> items = purchasebill.getItems(); //System.out.println("一方獲取多方:"+items); //①.準備總金額與總數量 BigDecimal totalamount = new BigDecimal(0); BigDecimal totalnum = new BigDecimal(0); for (Purchasebillitem item : items) { //System.out.println("多方拿一方:"+item.getBill()); //設置明細對應的訂單 item.setBill(purchasebill); //計算每個明細的小計 item.setAmount(item.getNum().multiply(item.getPrice())); //②.總金額與總數量進行累加 totalamount = totalamount.add(item.getAmount()); totalnum = totalnum.add(item.getNum()); } //③.把值設置到訂單中去 purchasebill.setTotalamount(totalamount); purchasebill.setTotalnum(totalnum); purchasebillService.save(purchasebill); } catch (Exception e) { e.printStackTrace(); //表明出錯 jsonResult.setSuccess(false); jsonResult.setMsg(e.getMessage()); } return jsonResult; }
```
問題1;
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'inputUser_id' cannot be null
解決辦法
在PurchasebillServiceImpl中覆寫save方法
public void save(Purchasebill purchasebill) { if(purchasebill.getId()==null){ //添加的時候,錄入人就是當前登陸用戶 Employee loginUser = UserContext.getUser(); purchasebill.setInputUser(loginUser); } super.save(purchasebill); }
> n-to-n:關連對象清空
```
@ModelAttribute("editPurchasebill") public Purchasebill beforeEdit(Long id,String cmd){ //修改的時候才查詢(只要有id會就進行一次查詢,這是不對的) if(id!=null && "update".equals(cmd)) { Purchasebill purchasebill = purchasebillService.findOne(id); //把要傳過來的關聯對象都清空,就能夠解決n-to-n的問題 purchasebill.setSupplier(null); purchasebill.setBuyer(null); purchasebill.getItems().clear(); return purchasebill; } return null; }
```