一对多动态添加关联对象的做法

Posted znsongshu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一对多动态添加关联对象的做法相关的知识,希望对你有一定的参考价值。

package app.models;

import java.util.HashSet;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;

import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;

public class Expense {
    private Integer id;
    @NotNull
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date date;
    private Float sum;
    
    private ExacctThree exacctThree;    
    private Department department;    
    private User user;    
    private Set<Explain> explains = new HashSet<Explain>();
    private List<Integer> explainIds = new ArrayList<Integer>();
    private List<String> explainNames = new ArrayList<String>();
    private List<String> explainDescriptions = new ArrayList<String>();
    

    public Expense() {
        super();
    }
    
    public Expense(
        Date date,
        Float sum
    ) {
        super();
        this.date = date;
        this.sum = sum;
    }
    
    
    
    public List<String> getExplainNames() {
        return explainNames;
    }

    public void setExplainNames(List<String> explainNames) {
        this.explainNames = explainNames;
    }

    public List<String> getExplainDescriptions() {
        return explainDescriptions;
    }

    public void setExplainDescriptions(List<String> explainDescriptions) {
        this.explainDescriptions = explainDescriptions;
    }

    public Date getDate() {
        return date;
    }
    
    public void setDate(Date date) {
        this.date = date;
    }
    public Float getSum() {
        return sum;
    }
    
    public void setSum(Float sum) {
        this.sum = sum;
    }
    
    public ExacctThree getExacctThree() {
        return exacctThree;
    }
    
    public void setExacctThree(ExacctThree exacctThree) {
        this.exacctThree = exacctThree;
    }
    public Department getDepartment() {
        return department;
    }
    
    public void setDepartment(Department department) {
        this.department = department;
    }
    public User getUser() {
        return user;
    }
    
    public void setUser(User user) {
        this.user = user;
    }
    public Set<Explain> getExplains() {
        return explains;
    }
    
    public void setExplains(Set<Explain> explains) {
        this.explains = explains;
    }
    
    public List<Integer> getExplainIds() {
        return explainIds;
    }
    
    public void setExplainIds(List<Integer> explainIds) {
        this.explainIds = explainIds;
    }
    
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    
}
<form:form action="expenses/${expense.id != null ? ‘update‘ : ‘create‘ }" method="POST" modelAttribute="expense"
    class="form-horizontal"  >
    <c:if test="${expense.id != null }">
        <form:hidden path="id" />
    </c:if>
    
    <div class="form-group">
        <label for="date" class="col-sm-2 control-label"><fmt:message key="expense.date"></fmt:message></label>
        <div class="col-sm-10">
            <form:input  type="date" class="form-control" path="date"  />
            <form:errors path="date"></form:errors>
        </div>
    </div>
    <div class="form-group">
        <label for="sum" class="col-sm-2 control-label"><fmt:message key="expense.sum"></fmt:message></label>
        <div class="col-sm-10">
            <form:input  type="number" class="form-control" path="sum"  />
            <form:errors path="sum"></form:errors>
        </div>
    </div>

    <div class="form-group">
        <label for="exacctThree" class="col-sm-2 control-label"><fmt:message
            key="exacctThree.name"></fmt:message></label>
        <div class="col-sm-10 ">
        <c:if test="${!empty exacctThrees }">
        <form:select class="form-control" path="exacctThree.id" items="${exacctThrees}" itemLabel="name" itemValue="id"></form:select>
        </c:if>
        </div>
    </div>
    <div class="form-group">
        <label for="department" class="col-sm-2 control-label"><fmt:message
            key="department.name"></fmt:message></label>
        <div class="col-sm-10 ">
        <c:if test="${!empty departments }">
        <form:select class="form-control" path="department.id" items="${departments}" itemLabel="name" itemValue="id"></form:select>
        </c:if>
        </div>
    </div>
                       
    <div class="form-group">
        <label for="sum" class="col-sm-2 control-label"><fmt:message key="explain.name"></fmt:message></label>
        <div class="col-sm-10">
            <div class="form-group">
                <div class="col-sm-1">
                    <button type="button" class="btn btn-primary" id="btn-add-explain"><fmt:message key="btn.add"></fmt:message></button>
                </div>
            </div>
            <div id="explain-ctn">
            <c:forEach items="${expense.explainIds }" var="explainId" varStatus="status">
                <div class="form-group explain-content">
                    <input type="hidden" name="explainIds" value="${explainId }">
                    <div class=" col-sm-2">
                        <input type="text" class="form-control" name="explainNames" value="${expense.explainNames[status.index] }" />
                    </div>
                    <div class=" col-sm-9">
                        <input type="text" class="form-control" name="explainDescriptions" value="${expense.explainDescriptions[status.index] }"/>
                    </div>
                    <div class="col-sm-1">
                        <button type="button" class="btn btn-danger btn-delete-explain"
                            onclick="deleteExplain(this)"><fmt:message key="btn.delete"></fmt:message></button>
                    </div>
                </div>        
            </c:forEach>
            </div>            
        </div>
    </div>
    
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-1">
            <button type="submit" class="btn btn-success"><fmt:message key="btn.save"></fmt:message></button>
        </div>
        <div class="col-sm-offset-1 col-sm-1">
            <a href="expenses/index" type="button" class="btn btn-warning"><fmt:message key="btn.back"></fmt:message></a>
        </div>
    </div>
</form:form>
$(document).ready(function() {
    $("#btn-add-explain").click(function() {
        var html = "<div class=‘form-group explain-content‘><div class=‘ col-sm-2‘><input type=‘text‘ class=‘form-control‘ name=‘explainNames‘ value=‘‘/></div><div class=‘ col-sm-9‘><input type=‘text‘ class=‘form-control‘ name=‘explainDescriptions‘  value=‘‘/></div><div class=‘col-sm-1‘><button type=‘button‘ class=‘btn btn-danger btn-delete-explain‘onclick=‘deleteExplain(this)‘>删除</button></div></div>";
        $("#explain-ctn").append(html);
    });
});

function deleteExplain(that) {
    $(that).parentsUntil("#explain-ctn").remove();
}
package app.controllers;

import java.util.HashSet;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.Map;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import app.models.ImageAttachment;
import app.services.ImageAttachmentService;

import app.models.Expense;
import app.models.ExacctThree;
import app.models.Department;
import app.models.User;
import app.models.Explain;
import app.services.ExpenseService;
import app.services.ExacctThreeService;
import app.services.DepartmentService;
import app.services.UserService;
import app.services.ExplainService;


@Controller
@RequestMapping("/expenses")
public class ExpenseController extends BaseController {

    @Autowired
    ExpenseService expenseService;
    @Autowired
    ExacctThreeService exacctThreeService;
    @Autowired
    DepartmentService departmentService;
    @Autowired
    UserService userService;
    @Autowired
    ExplainService explainService;
    
    
    @ModelAttribute
    public void getexpense(@RequestParam(value="id", required=false) Integer id, Map<String, Object> map) {
        if (id != null) {
            map.put("expense", expenseService.findById(id));
        }
    }
    
    @RequestMapping("/index")
    public String index(Map<String, Object> map) {
        map.put("expenses", expenseService.findAll());
        return "expenses/index";
    }
    
    @RequestMapping("/new")
    public String fresh(Map<String, Object> map) {
        prepareData(map, null);
        Expense expense = new Expense();
        map.put("expense", expense);
        return "expenses/new";
    }
        
    @RequestMapping("/{id}/edit")
    public String edit(@PathVariable("id") Integer id, Map<String, Object> map) {
        Expense expense = expenseService.findById(id);
        prepareData(map, expense);
        map.put("expense", expense);
        return "expenses/edit";
    }
    
    @RequestMapping(value="/{id}")
    public String show(@PathVariable("id") Integer id, Map<String, Object> map) {
        map.put("expense", expenseService.findById(id));
        return "expenses/show";
    }

    @RequestMapping(value="/{id}/destroy", method=RequestMethod.DELETE)
    public String destroy(@PathVariable("id") Integer id) {
        expenseService.deleteById(id);
        return "redirect:/expenses/index";
    }
    
    @RequestMapping(value="/create", method=RequestMethod.POST)
    public String create(@Valid Expense expense, Errors result, Map<String, Object> map
        , @RequestParam(value="exacctThree.id", required=false) Integer exacctThreeId
        , @RequestParam(value="department.id", required=false) Integer departmentId
        , @RequestParam(value="explainNames", required=false) String[] explainNames
        , @RequestParam(value="explainDescriptions", required=false) String[] explainDescriptions
        , HttpServletRequest request, HttpServletResponse response
    ) {
        if(result.getErrorCount() > 0){
            for(FieldError error:result.getFieldErrors()){
                System.out.println(error.getField() + ":" + error.getDefaultMessage());
            }
            prepareData(map, null);
            return "/expenses/new";
        }
        
        setAssociate(expense
        , exacctThreeId
        , departmentId
        );
        //这里有bug 如果explainNames 或 explainDescription有不填的项就会出现数组越界的问题,update也是这个问题,还没修
if (explainNames != null) { Set<Explain> explains = new HashSet<Explain>(); for (int i = 0; i < explainNames.length; i++) { Explain explain = new Explain(explainNames[i], explainDescriptions[i]); explains.add(explain); } expense.setExplains(explains); } expenseService.save(expense); return "redirect:/expenses/" + expense.getId().toString(); } @RequestMapping(value="/update", method=RequestMethod.POST) public String update(@Valid Expense expense, Errors result, Map<String, Object> map , @RequestParam(value="exacctThree.id", required=false) Integer exacctThreeId , @RequestParam(value="department.id", required=false) Integer departmentId , @RequestParam(value = "explainIds", required = false) Integer[] explainIds , @RequestParam(value="explainNames", required=false) String[] explainNames , @RequestParam(value="explainDescriptions", required=false) String[] explainDescriptions , HttpServletRequest request, HttpServletResponse response ) { if(result.getErrorCount() > 0){ for(FieldError error:result.getFieldErrors()){ System.out.println(error.getField() + ":" + error.getDefaultMessage()); } prepareData(map, expense); return "/expenses/edit"; } setAssociate(expense , exacctThreeId , departmentId ); if (explainIds != null) { for (int i = 0; i < explainIds.length; i++) { Explain explain = explainService.findById(explainIds[i]); explain.setName(explainNames[i]); explain.setDescription(explainDescriptions[i]); explainService.update(explain); } List<Explain> explains = explainService.findByIds(explainIds); Set<Explain> explainSet = new HashSet<Explain>(explains); for (int i = explainIds.length; i < explainNames.length; i++) { Explain explain = new Explain(explainNames[i], explainDescriptions[i]); explainSet.add(explain); } expense.setExplains(explainSet); } else { if (explainNames != null) { Set<Explain> explains = new HashSet<Explain>(); for (int i = 0; i < explainNames.length; i++) { Explain explain = new Explain(explainNames[i], explainDescriptions[i]); explains.add(explain); } expense.setExplains(explains); } } expenseService.update(expense); return "redirect:/expenses/" + expense.getId().toString(); } private void prepareExplains(Expense expense, Map<String, Object> map) { List<Integer> explainIds = new ArrayList<Integer>(); List<String> explainNames = new ArrayList<String>(); List<String> explainDescriptions = new ArrayList<String>(); Set<Explain> explains = expense.getExplains(); Iterator<Explain> iterator = explains.iterator(); while (iterator.hasNext()) { Explain explain = (Explain) iterator.next(); explainIds.add(explain.getId()); explainNames.add(explain.getName()); explainDescriptions.add(explain.getDescription()); } expense.setExplainIds(explainIds); expense.setExplainNames(explainNames); expense.setExplainDescriptions(explainDescriptions); } private void prepareData(Map<String, Object> map, Expense expense) { map.put("exacctThrees", exacctThreeService.findAll()); map.put("departments", departmentService.findAll()); if (expense != null) { prepareExplains(expense, map); } } public void setAssociate(Expense expense , Integer exacctThreeId , Integer departmentId ) { if (exacctThreeId != null) { ExacctThree exacctThree = exacctThreeService.findById(exacctThreeId); expense.setExacctThree(exacctThree); } if (departmentId != null) { Department department = departmentService.findById(departmentId); expense.setDepartment(department); } } }

 

以上是关于一对多动态添加关联对象的做法的主要内容,如果未能解决你的问题,请参考以下文章

spring Data jpa 一对多关联 动态查询怎么写

一对一,一对多,多对一,自关联

hibernate_关联映射_一对多

Mybatis

mybatis关联查询,一对一,一对多

Java--Mybatis关联映射之关联单个对象(即一对一);关联多个对象(即一对多)