引言:在一些业务场景,我们会遇到这个问题,比如一个商品或者一个源码有多个标签,根据不同的标签可以查询到对应的源码或者商品?一个学生需要使用复选框选择多个兴趣爱好?那么我们该如何实现这个多标签添加、以及标签回显、修改问题呢?
本次我们以SSM框架、MySQL数据库、IDEA开发工具为背景,来实现这个功能,由于在这个基础上开发设计,我们主要写核心的功能模块,不一定要按照的我的这个框架和开发工具,只要是SSM或者SPringBoot即可。
SSM实战-演示多标签复选框的回显、修改功能
首页
添加
实现功能:复选框的添加、回显、修改
修改复选框
实现思路:一个三个实体,label(标签)、code(源码)、labelcode(中间表),需要做一个中间表来存储标签的主键,源码的编号,为什么这里存储源码的主键呢 ,因为在添加标签的时候这个源码的主键无法添加的,因为是数据库自动生成的,所以需要由工具类生成一个源码编号。
在添加源码的时候先把所有的标签查询出来,然后添加源码的时候把这些标签添加到中间表里面去,这样形成了关联,属于一个多对多的关系。
修改的时候,比较难实现,这个时候就要使用jquery了,可见jquery的重要性,使用ajax先把所有的标签查询出来,然后清空选中,再根据源码编号查询中间表这个源码相同的源码编号的标签,也就是这个源码选中的标签,来进行比对,如果选中了,就进行回显。修改的时候注意把中间表的原来关联的删掉,然后再新增。
标签表设计
中间表设计
源码表设计
这个源码表是我做的一个例子,仅供参考,按照你要做的功能来进行设计。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>源码客栈后台系统</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="${pageContext.request.contextPath}/resource/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="${pageContext.request.contextPath}/resource/layuiadmin/style/admin.css" media="all">
</head>
<body>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md9">
<div class="layui-card">
<div class="layui-card-header">${empty param.id?"发布源码":"编辑源码"}</div>
<div class="layui-card-body">
<span class="msg" style="color:red;">${requestScope.msg}</span>
<form class="layui-form" action="${pageContext.request.contextPath}${empty param.id ?"/code/add.action":"/code/update.action"}" method="post">
<div class="layui-row layui-col-space10 layui-form-item">
<input type="hidden" name="id" id="id" value="${record.id}">
<input type="hidden" name="codeNo" id="codeNo" value="${record.code_no}">
<input type="hidden" name="a_id" value="${admin.id}">
<div class="layui-col-lg3">
<label class="layui-form-label">源码分类:</label>
<div class="layui-input-block">
<select name="category_id" lay-verify="required" lay-filter="aihao">
<c:if test="${requestScope.categoryList!=null}">
<c:forEach items="${requestScope.categoryList}" var="category">
<option value="${category.id}" <c:if test="${category.id==record.category_id}">selected</c:if> >${category.name}</option>
</c:forEach>
</c:if>
</select>
</div>
</div>
</div>
<div class="layui-row layui-col-space10 layui-form-item">
<div class="layui-form-item">
<label class="layui-form-label">复选框</label>
<div class="layui-input-block" id="checkid">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" type="submit" id="add" >${empty param.id ?"发布":"修改"}</button>
<button type="button" onclick="location.href='/code/pageList.action'" class="layui-btn layui-btn-normal">返回</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="${pageContext.request.contextPath}/resource/layuiadmin/layui/layui.js"></script>
<script src="${pageContext.request.contextPath}/resource/js/jquery-3.3.1.js"></script>
<script>
var id = $("#id").val();
if(id != null && id != ""){
selectIsCheckList();
}
init();
var checkList = null;
function selectIsCheckList(){
var codeNo = $("#codeNo").val();
$.ajax({
cache : true,
type : "post",
url : "/code/selectLabelByCodeNo",
data : {"codeNo":codeNo},
async : false,
success : function(data) {
if (data) {
checkList = data;
} else {
alert("查询失败!");
}
}
})
}
//这里是核心区,霹提供
function init(){
$("#checkid").html("");
var html = "";
$.ajax({
cache : true,
type : "post",
url : "/code/selectAllLabel",
//data : {"fid":fid},
async : false,
success : function(data) {
if (data) {
if(data.length>0){
var html = "";
for(var i=0 ;i <data.length;i++){
var re = 0;
if(checkList!=null){
for(var j=0;j<checkList.length;j++){
if(checkList[j].label_id == data[i].id ){
re = 1;
}
}
if(re == 1){
html += "<input type='checkbox' name='label_id' checked value='"+data[i].id+"'title='"+data[i].lname+"'/>";
}else{
html += "<input type='checkbox' name='label_id' value='"+data[i].id+"'title='"+data[i].lname+"'/>";
}
}else{
html += "<input type='checkbox' name='label_id' value='"+data[i].id+"'title='"+data[i].lname+"'/>";
}
}
$("#checkid").append(html);
}
} else {
alert("查询失败!");
}
}
})
}
</script>
</body>
</html>
//Label接口
public interface LabelService {
public List<Label> getLabelList();
}
//LabelCodeService接口
public interface LabelCodeService {
public List<LabelCode> getLabelId(String code_no);
public boolean addLabelCode(LabelCode r);
public boolean deleteByCodeNo(String code_no);
}
//CodeService接口
public interface CodeService {
public boolean addCode(Code r);
public boolean updateCode(Code r);
}
这个是核心的查询方法,根据源码编号查询中间表的里的标签信息(包括了ID),其他的增删改查的就不写了,自己根据自己的SSM框架来设计
<select id="selectByLabelId" parameterType="com.website.entity.Code" resultMap="BaseResultMap">
/* select * from t_code where id in (select code_id from t_label_code where label_id = '1' )*/
select
*
from t_code
where code_no in (select code_no from t_label_code where label_id = #{label_Id,jdbcType=INTEGER} )
</select>
<delete id="deleteByCodeNo" parameterType="java.lang.String">
delete from t_label_code
where code_no = #{code_no,jdbcType=VARCHAR}
</delete>
实现层,可以自己编写,不一定要看我的
//标签实现层
@Service
@Transactional
public class LabelServiceImpl implements LabelService {
@Autowired
private LabelMapper mapper;
@Override
public List<Label> getLabelList() {
return mapper.selectByExample(null);//查询所有
}
}
public List<LabelCode> getLabelCodeList() {
return mapper.selectByExample(null);//查询所有
}
//中间表实体实现层。我这里使用的是自动生成的拼写规则根据源码编号查询,看不懂这种写法的请使用自己原来写的查询方法即可
@Override
public List<LabelCode> getLabelId(String code_no) {
LabelCodeExample example = new LabelCodeExample();
LabelCodeExample.Criteria criteria = example.createCriteria();
if(StringUtils.isNoneBlank(code_no)){
criteria.andCode_noEqualTo(code_no);
}
List<LabelCode> list = mapper.selectByExample(example);//第2步
return list;
}
//这里是源码的实现层
@Override
public boolean addCode(Code record) {
return mapper.insertSelective(record) > 0 ? true : false;
}
@Override
public boolean updateCode(Code record) {
return mapper.updateByPrimaryKeySelective(record) > 0 ? true : false;
}
源码编号生成
public static String getCodeNo() {//生成源码编号
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
String newDate=sdf.format(new Date());
String result="";
Random random=new Random();
for(int i=0;i<2;i++){
result+=random.nextInt(5);
}
return newDate+result;
控制层我们主要写CodeController里面的
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
@RequestMapping(value = "/code/add.action",method = RequestMethod.POST,produces = "text/html;charset=UTF-8")
@ResponseBody
public String add(Code record,HttpServletRequest request){
Date date = new Date();
// 得到一个Timestamp格式的时间,存入mysql中的时间格式“yyyy/MM/dd HH:mm:ss”
Timestamp timeStamp = new Timestamp(date.getTime());
record.setCreate_time(timeStamp);
record.setSee_count(0);
String[] labels=request.getParameterValues("label_id");//获取选中的复选框
String code_no=WebUtils.getCodeNo();//生成复选框编号
record.setCode_no(code_no);
for(String label_id:labels ){//for循环插入中间表,把选到的标签依次插入中间表,同时查询源码编号进行关联
//插入标签
System.out.println(label_id);
LabelCode labelCode=new LabelCode();
labelCode.setCode_no(code_no);
labelCode.setLabel_id(Integer.parseInt(label_id));
labelCodeService.addLabelCode(labelCode);
}
if(service.addCode(record)){
return "<script>location.href='/code/pageList.action';</script>";
//return "<script>alert('添加成功');location.href='/client/findMyInfo.action';</script>";
}else{
return "<script>alert('添加失败');history.go(-1);</script>";
}
}
主要回显实现的是其他的信息。
//去编辑界面
@RequestMapping(value = "/code/query.action")
public String toUpdatecode(Integer id,Model model,Map map){
System.out.println(id+"******");
Code record=service.findById(id);
if(null!=record){
model.addAttribute("record",record);
}
return "code/edit";
}
这里是核心地区,在编辑页面先把所有的标签查询出来,然后在中间表查询源码里面已经选择了的复选框的标签
//通过编号查询关联的label
@RequestMapping(value = "/code/selectAllLabel")
@ResponseBody
public List<Label> selectAllLabel(String codeNo){
List<Label> labelList=ls.getLabelList();
return labelList;
}
//通过编号查询关联的label
@RequestMapping(value = "/code/selectLabelByCodeNo")
@ResponseBody
public List<LabelCode> selectLabelByCodeNo(String codeNo){
List<LabelCode> labelCodeList= labelCodeService.getLabelId(codeNo);
return labelCodeList;
}
@RequestMapping(value = "/code/update.action",method = RequestMethod.POST,produces = "text/html;charset=UTF-8")
@ResponseBody
public String update(Code record,HttpServletRequest request){
Code c=service.findById(record.getId());
String filename=c.getPhoto();
WebUtils.deleteImg(filename);
String[] labels=request.getParameterValues("label_id");
//修改标签前先删掉原来的中间表关联
labelCodeService.deleteByCodeNo(c.getCode_no());
for(String label_id:labels ){
//插入标签
System.out.println(label_id);
LabelCode labelCode=new LabelCode();
labelCode.setCode_no(c.getCode_no();
labelCode.setLabel_id(Integer.parseInt(label_id));
labelCodeService.addLabelCode(labelCode);
}
if(service.updateCode(record)){
return "<script>alert('修改成功');location.href='/code/pageList.action';</script>";
}else{
return "<script>alert('修改失败');history.go(-1);</script>";
}
}
备注:如果需要源码文件,请关注微信公众号:逛逛Java主窗口回复口令fj01领取相关源码文件