精华内容
下载资源
问答
  • 指定某一字段作为唯一校验性主要逻辑: 获取需要校验的字段值和该对象的主键(为null需要处理),在该字段值在sql中作为判断条件进行查询并且只获取一条(limit 1),如果有一条记录则说明存在,如果没有则存在...

    指定某一字段作为唯一校验性主要逻辑:
    获取需要校验的字段值和该对象的主键(为null时需要处理),在该字段值在sql中作为判断条件进行查询并且只获取一条(limit 1),如果有一条记录则说明存在,如果没有则不存在;
    第二判断条件:则用于修改:排除本身

    1. Controller层
    //属性名称 类型 编号 作为唯一校验
            if (!(tsmPropertyTemplateService.checkPropertyTemplateUnique(tsmPropertyTemplate))) {
                return error("新增属性'" + tsmPropertyTemplate.getName() + "'失败,该属性已存在");
            }
    
    1. service层
    /**
         * 校验: 属性名称 类型 编号
         *
         * @param tsmPropertyTemplate
         * @Title:checkPropertyTemplateUnique
         * @Description:用于校验:属性名称 类型 编号
         * @author:云诺
         * @date:2021/2/25
         * @return:boolean
         */
        boolean checkPropertyTemplateUnique(TsmPropertyTemplate tsmPropertyTemplate);
    
    
    1. serviceImp
        @Override
        public boolean checkPropertyTemplateUnique(TsmPropertyTemplate template) {
    //        校验:名称 类型 编号
            String id = (template.getId() == null) ? "" : template.getId();
            String name = template.getName();
            String type = template.getType();
            String code = template.getCode();
            TsmPropertyTemplate info = tsmPropertyTemplateMapper.checkDeptNameUnique(name, type, code);
            String infoId = (info == null) ? "" : (info.getId());
            if ((info != null) && !((info.getId()).equals(id))) {
                //已存在
                return false;
            }
            return true;
        }
    
    1. Mapper.java
    
        /**
         * 校验
         *
         * @param name
         * @param type
         * @param code
         * @return
         */
        TsmPropertyTemplate checkDeptNameUnique(@Param("name") String name, @Param("type") String type, @Param("code") String code);
    
    1. Mapper.xml
        <select id="checkDeptNameUnique" resultType="TsmPropertyTemplate">
            select id, `name`, `type`, dic_code, code, `describe`,  remark, del_flag
            where del_flag='0'
            and name=#{name} and type=#{type} and code=${code} limit 1
        </select>
    
    展开全文
  • 在使用antd form组件的的validateFields或者validateFieldsAndScroll方法如果它没有进入方法而是直接跳过了方法,那不妨看看自定义验证方法validator代码块里是否有某一条分支没有执行 callback 函数。官方规定:...

    在使用antd form组件的的validateFields或者validateFieldsAndScroll方法时如果它没有进入方法而是直接跳过了方法,那不妨看看自定义验证方法validator代码块里是否有某一条分支没有执行 callback 函数。官方规定:自定义校验 callback 必须被调用。

    补充一下我测的,调callback(null)相当于没执行callback; callback(undefined)相当于callback()

    展开全文
  • 本例注解应用场景: 填写表单时某一项数据存在,对应的一类数据都应存在,一同提交。 二.源码 1.类注解 主注解用于标记要在校验的实体类 @Target( { TYPE }) @Retention(RUNTIME) @Constraint(validatedBy = ...

    最近新开了一个项目,虽然hibernate-validator很好用,但是有时不能满足稍微复杂一些的业务校验。为了不在业务代码中写校验逻辑,以及让代码更优雅,故而采用了自定义校验注解的方式。

    一. 场景说明

    本例注解应用场景: 填写表单时,某一项数据存在时,对应的一类数据都应存在,一同提交。

    二.源码

    1.类注解

    主注解用于标记要在校验的实体类

    @Target( { TYPE })
    @Retention(RUNTIME)
    @Constraint(validatedBy = RelateOtherValidator.class)
    @Documented
    public @interface RelateOther {
        String message() default "";
        /**
         * 校验数量
         */
        int num() default 2;
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
    }
    

    2.辅助注解

    辅助注解用于标注于要校验的字段,isMaster区分为主注解和从注解。
    主注解是关键字段,存在才进行校验从注解对应字段的有效性;主注解的value()属性可以设置默认值,当字段对应值对应value()时才开启校验。
    从注解为等待校验的值,默认为从注解。

    @Target( { FIELD })
    @Retention(RUNTIME)
    @Documented
    public @interface RelateOtherItem {
    
        /**
         * 是否为主字段,主字段存在才进行校验
         */
        boolean isMaster() default false;
        /**
         * 用于开启对指定值校验判断,master字段有效
         * 当前为master且value与标注字段值相等才进行校验,
         */
        String value() default "";
    
    }
    

    3.校验类

    校验类为实际执行校验逻辑的类,在类注解的@Constraint的validatedBy属性上设置。
    要设置为校验类,首先要实现ConstraintValidator类的isValid方法。

    @Slf4j  // @Slf4j是lombok的注解
    public class RelateOtherValidator implements ConstraintValidator<RelateOther, Object> {
    	// 要校验的个数
        private int validateNum;
    
        @Override
        public void initialize(RelateOther constraintAnnotation) {
            validateNum = constraintAnnotation.num();
        }
    
        @Override
        public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
            if (o == null) {
                return true;
            }
            Field[] declaredFields = o.getClass().getDeclaredFields();
            boolean mater = false;
            int emptyNum = 0;
            try {
                // 总共需要校验的字段数
                int totalValidateNum = validateNum;
                for (Field field : declaredFields) {
                    // 校验是否进行过标注
                    if (!field.isAnnotationPresent(RelateOtherItem.class)) {
                        continue;
                    }
                    if (validateNum > 0 && totalValidateNum-- < 0) {
                        return false;
                    }
                    field.setAccessible(true);
                    Object property = field.get(o);
                    RelateOtherItem relateOtherItem = field.getAnnotation(RelateOtherItem.class);
                    // 主字段不存在,则校验通过
                    if (relateOtherItem.isMaster()) {
                        if (property==null) {
                            return true;
                        }
                        // 与指定值不一致,校验通过
                        if (!StringUtils.isEmpty(relateOtherItem.value()) && !relateOtherItem.value().equals(property)) {
                            return true;
                        }
                        mater = true;
                        continue;
                    }
                    if (null == property) {
                        emptyNum++;
                    }
                }
                // 主字段不存在,则校验通过
                if (!mater) {
                    log.info("RelateOther注解主字段不存在");
                    return true;
                }
                return emptyNum==0;
            } catch (Exception e) {
                log.info("RelateOther注解,解析异常 {}", e.getMessage());
                return false;
            }
        }
    
    }
    

    4.校验失败

    注解校验不同时会抛出一个MethodArgumentNotValidException异常。这里可以采用全局异常处理的方法,进行捕获处理。捕获之后的异常可以获取BindingResult 对象,后面就跟hibernate-validator处理方式一致了。

    BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
    

    5.使用demo

    注解的使用类似下面,首先在请求实体类上标注类注解,再在对应的字段上标注辅助注解。

    @RelateOther(message = "xx必须存在!",num=2)
    public class MarkReq  {
    
    	@RelateOtherItem (isMaster= true,value="1")
    	private Integer  girl;
    
    	@RelateOtherItem 
    	private Integer sunscreen;
    
    	private String remarks;
    
    }
    

    三.总结

    自定义注解在开发中还是很好用的,本文主要起到抛砖引玉的作用。对于首次使用的朋友应该还是有些用处的。

    展开全文
  • JSF实现无刷新二级联动

    千次阅读 热门讨论 2017-10-04 18:21:11
    JSF有一个"bug":如果页面中包含了下拉框,则提交表单时,JSF会在应用请求值阶段就对下拉框选择的值进行验证(事实上应该在转换完毕后进行验证)。如果这个值不是可选的值之一,则会抛出校验失败的异常。所以BookBean...
    效果:
    在添加图书页,有一个图书分类的下拉框,选择某分类后会自动刷新出子分类。
    要点:
    JSF有一个"bug":如果页面中包含了下拉框,则提交表单时,JSF会在应用请求值阶段就对下拉框选择的值进行验证(事实上应该在转换完毕后进行验证)。如果这个值不是可选的值之一,则会抛出校验失败的异常。所以BookBean必须设置在SessionScoped上

    代码:
    addBook.xhtml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
    	  xmlns:h="http://java.sun.com/jsf/html"
    	  xmlns:f="http://java.sun.com/jsf/core"
    	  xmlns:c="http://java.sun.com/jsp/jstl/core"
    	  >
    <h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>add Book</title>
    </h:head>
    <h:body>
    <!-- 设置了表单,因此其中用到托管bean是是设置值 -->
    	<h:form id = "addBookForm">
    	<h:panelGrid columns="3">
    
    		<h:outputLabel value="图书名称:"></h:outputLabel>
    		<h:inputText id="bookName" value="#{bookBean.bookName}" required="true"></h:inputText>
    		<h:message for="bookName"></h:message>
    		
    		<h:outputLabel value="图书书号:"></h:outputLabel>
    		<h:inputText id="bookNumber" value="#{bookBean.bookNumber}" required="true">
    			<f:validateRegex pattern="ISBN[0-9]{13}"></f:validateRegex>
    		</h:inputText>
    		<h:message for="bookNumber"></h:message>
    		
    		<h:outputLabel value="作者:"></h:outputLabel>
    		<h:inputText id="author" value="#{bookBean.author}" required="true"
    			converter="authorConverter"></h:inputText>
    		<h:message for="author"></h:message>
    		
    		<h:outputLabel value="出版时间:"></h:outputLabel>
    		<h:inputText id="publishDate" value="#{bookBean.publishDate}" required="true">
    			<f:convertDateTime pattern="yyyy-mm-dd"></f:convertDateTime>
    		</h:inputText>
    		<h:message for="publishDate"></h:message>
    		
    		<h:outputLabel value="价格:">
    		</h:outputLabel>
    		<h:inputText id="price" value="#{bookBean.price}" required="true">
    			<f:convertNumber maxFractionDigits="1"
    			></f:convertNumber>
    		</h:inputText>
    		<h:message for="price"></h:message>
    		
    		<h:outputLabel value="分类:"></h:outputLabel>
    		<h:selectOneListbox id="category" value = "#{bookBean.category}" size = "1"
    			                    valueChangeListener="#{bookControl.changeCategory}"
    			                    οnchange="submit()" 
    			                    immediate="true"
    			                    >
    			<f:selectItem itemValue="0" itemLabel="请选择"></f:selectItem>
    			<f:selectItem itemValue="1" itemLabel="计算机"></f:selectItem>
    			<f:selectItem itemValue="2" itemLabel="文学"></f:selectItem>
    			<f:selectItem itemValue="3" itemLabel="管理"></f:selectItem>
    			<f:selectItem itemValue="4" itemLabel="其他"></f:selectItem>	
    		</h:selectOneListbox>
    		<h:message for="category"></h:message>
    		
    		<h:outputLabel value="子分类:"></h:outputLabel>
    		<h:selectOneListbox id="subCategory" value="#{bookBean.subCategory}"
    			size="1">
    			<c:forEach var="cat" items="#{bookBean.subCategories}" varStatus="catCount">
    				<f:selectItem itemValue="#{catCount.count}" 
    					itemLabel="#{cat}"></f:selectItem>
    			</c:forEach>
    		</h:selectOneListbox>
    		<h:message for="subCategory"></h:message>
    	
    		
    		<h:commandButton value="添加" action="#{bookControl.add}" 
    		></h:commandButton>
    		<h:commandButton value="取消" immediate="true"></h:commandButton>
    		</h:panelGrid>
    	</h:form>
    </h:body>
    </html>

    BookBean.java
    package cn.edu.jlu.pojo;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import javax.annotation.PostConstruct;
    import javax.enterprise.context.RequestScoped;
    import javax.enterprise.context.SessionScoped;
    import javax.faces.bean.NoneScoped;   //NoneScoped不行,
    									 //因为拿到.xhtml传回的值并设置BookBean后就被删除
    import javax.inject.Named;
    import javax.faces.bean.ViewScoped;
    
    @Named
    @SessionScoped
    public class BookBean implements Serializable{
    	
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	
    	private String bookName;
    	private String bookNumber;  //pk
    	private List<String> author;//多个作者
    	private Date publishDate;
    	private double price;
    	private int category = 0;
    	private int subCategory = 99;
    	private List<String> subCategories = new ArrayList<String>();
    	public String getBookName() {
    		return bookName;
    	}
    	public void setBookName(String bookName) {
    		System.out.println("?????????????");
    		this.bookName = bookName;
    	}
    	public String getBookNumber() {
    		return bookNumber;
    	}
    	public void setBookNumber(String bookNumber) {
    		this.bookNumber = bookNumber;
    	}
    	public List<String> getAuthor() {
    		return author;
    	}
    	public void setAuthor(List<String> author) {
    		this.author = author;
    	}
    	public Date getPublishDate() {
    		return publishDate;
    	}
    	public void setPublishDate(Date publishDate) {
    		this.publishDate = publishDate;
    	}
    	public double getPrice() {
    		return price;
    	}
    	public void setPrice(double price) {
    		this.price = price;
    	}
    	public int getCategory() {
    		return category;
    	}
    	public void setCategory(int category) {
    		this.category = category;
    	}
    	public int getSubCategory() {
    		return subCategory;
    	}
    	public void setSubCategory(int subCategory) {
    		this.subCategory = subCategory;
    	}
    	public List<String> getSubCategories() {
    		return subCategories;
    	}
    	public void setSubCategories(List<String> subCategories) {
    		this.subCategories = subCategories;
    	}
    	
    	
    }
    



    BookControl.java
    package cn.edu.jlu.controller;
    
    import java.io.Serializable;
    import java.util.List;
    
    import javax.annotation.PostConstruct;
    import javax.enterprise.context.RequestScoped;
    import javax.enterprise.context.SessionScoped;
    import javax.faces.context.FacesContext;
    import javax.faces.event.ActionEvent;
    import javax.faces.event.ValueChangeEvent;
    import javax.faces.model.SelectItem;
    import javax.inject.Inject;
    import javax.inject.Named;
    
    import cn.edu.jlu.client.CountBeanClient;
    import cn.edu.jlu.client.ListBeanClient;
    import cn.edu.jlu.pojo.BookBean;
    
    @Named
    @RequestScoped
    //SessionScoped的Bean需要支持钝化
    public class BookControl implements Serializable{
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = -3508615784767089380L;
    	@Inject @Named("bookBean")
    	private BookBean bookBean;
    	private int count ;
    	
    	@Inject @Named("bookBean")
    	BookBean book;
    	
    	public void changeCategory(ValueChangeEvent e) {
    		//获取更改后的值
    		Integer category = (Integer)e.getNewValue();
    		//System.out.println("选择分类------------"+bookBean.getCategory()+"-->"+category);
    		//获取bookBean中的子菜单
    		List<String> sub = bookBean.getSubCategories();
    		sub.clear();
    		if(1 == category) {
    			bookBean.setCategory(1);
    			sub.add("软件工程");
    			sub.add("计算机网络");
    			sub.add("编程语言");
    			sub.add("其他");
    		} else if(2 == category) {
    			bookBean.setCategory(2);
    			sub.add("小说");
    			sub.add("散文");
    			sub.add("诗词");
    			sub.add("其他");
    		} else if(3 == category) {
    			bookBean.setCategory(3);
    			sub.add("行政管理");
    			sub.add("金融管理");
    			sub.add("经商管理");
    			sub.add("其他");
    		} else if(4 == category) {
    			bookBean.setCategory(4);
    			
    		}
    		//System.out.println(sub);
    	}
    	
    	public String add() {
    		if(bookBean.getPrice() != 0.0)
    			return "success";
    		return "fail";
    	}
    	
    	public void confirmToAdd() {
    		System.out.println("confirmToAdd");
    		new ListBeanClient().add(bookBean);
    	}
    	
    	@PostConstruct
    	public void sCount() {
    		count = new CountBeanClient().getCount();
    	}
    	
    	public void setCount(int count) {
    		this.count = count;
    	}
    	public int getCount() {
    		return count;
    	}
    }
    

    作者属性的转换器,将输入的a,b,c转换成一个List
    package cn.edu.jlu.biz;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.faces.application.FacesMessage;
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.convert.Converter;
    import javax.faces.convert.ConverterException;
    import javax.faces.convert.FacesConverter;
    
    @FacesConverter("authorConverter")
    public class AuthorConverter implements Converter{
    
    	@Override
    	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
    		//将String转为List  arg2是获得的参数
    		//去掉空格
    		String ipt = arg2.replace(" ", "");
    		if(ipt.equals("")) {
    			FacesMessage message = new FacesMessage(
    					FacesMessage.SEVERITY_ERROR, "输入有误", "不可为空");
    			arg0.addMessage("author", message);
    			throw new ConverterException(message);
    		}
    		List<String> result = new ArrayList<String>();
    		//
    		String[] authors = ipt.split(",");
    		if(authors.length == 0) {
    			FacesMessage message = new FacesMessage(
    					FacesMessage.SEVERITY_ERROR, "输入有误", "多作者请用逗号间隔");
    			arg0.addMessage("author", message);
    			throw new ConverterException(message);
    		} 		
    		for (String s : authors) {
    			result.add(s);
    		}
    		return result;
    	}
    
    	@Override
    	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
    		//将List转为String
    		List<String> authors = (ArrayList<String>)arg2;
    		StringBuilder sb = new StringBuilder();
    		for (String i: authors) {
    			sb.append(i + ",");
    		}
    		//去掉最后一个,
    		String result = sb.toString();
    		int index = result.lastIndexOf(",");
    		result = result.substring(0, index);
    		return result;
    	}
    
    }
    



    展开全文
  • LockFile 锁定文件的某一部分,使其与其他应用程序共享 LockFileEx 与LockFile相似,只是它提供了更多的功能 lopen 以二进制模式打开指定的文件 lread 将文件中的数据读入内存缓冲区 lwrite 将数据从内存缓冲...
  • [会议管理]新增了根据会议室ID查询,某一时间段一个会议的使用情况的功能 [即时通讯]新增了IM聊天Web端创建群聊功能和修改群属性等功能 [移动办公]新增了移动端通知消息可打开对应应用的功能 [移动办公]新增了移动端...
  • 正则表达式

    2014-12-03 14:51:39
    \W 匹配一个不可以组成单词的字符,如[\W]匹配"$5.98"中的$,等于[^a-zA-Z0-9]。 用re = new RegExp("pattern",["flags"]) 的方式比较好 pattern : 正则表达式 flags: g (全文查找出现的所有 pattern) i ...
  • 当我为某一 form 字段的校验添加自定义规则,应该可以读取 data 属性,然后根据 data 里面的其他字段的值动态判断当前字段的值是否合法,下面的代码摘自官方文档 Form 里的一个 CheckForm 的...
  •  SessionBean: Stateless Session Bean 的生命周期是由容器决定的,当客户机发出请求要建立一个Bean的实例,EJB容器一定要创建一个新的Bean的实例供客户机调用,而是随便找一个现有的实例提供给客户机。...
  • java面试宝典

    2013-02-28 16:04:01
    28、char 型变量中能能存贮一个中文汉字?为什么? 10 29、abstract class 和interface 有什么区别? 10 30、Static Nested Class 和Inner Class 的不同? 11 31、java 中会存在内存泄漏吗,请简单描述。 11 32、...
  • 如果<code>import了一个不需要改造的,那其实是<code>import了<code>node_modules里的原始Vue的文件,如果是<code>import了需要改造的,那其实<code>import的是我的目录,文件也是我修改后...
  • 千方百计笔试题大全

    2011-11-30 21:58:33
    28、char 型变量中能能存贮一个中文汉字?为什么? 10 29、abstract class 和interface 有什么区别? 10 30、Static Nested Class 和Inner Class 的不同? 11 31、java 中会存在内存泄漏吗,请简单描述。 11 32、...
  • 一文带你搞懂API网关

    2020-12-28 06:45:32
    而且因为线程不再被某一个连接独占,一个连接所占用的系统资源也会低得多,只是一个文件描述符加上几个监听器等,而在阻塞模型中,每条连接都会独占一个线程,而线程是一个非常重的...
  • java 面试题 总结

    2009-09-16 08:45:34
    当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且希望让程序等待方法的返回,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。 17、abstract class和interface有什么区别? 声明方法...
  • (1)、数据一致性错误:主要是由于用户提交的表单信息正确而造成的; (2)、输出错误:主要是由于网络速度或程序设计问题等引起的。  二、性能测试 1、连接速度测试 (1)、Web系统响应时间; (2)、超时的...
  • GoodProject Maven Webapp.zip

    2019-05-12 14:06:27
    可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。...
  • 千里马酒店前台管理系统V7使用手册

    热门讨论 2011-06-16 14:09:38
    按酒店前台业务的部门分组,千里马V7.2的功能划分为可自定义的一个个动态工作视图,即房态视图、预订视图、接待视图、收银视图、管家视图、夜核视图、问讯视图、礼宾视图、报表视图等。这些工作视图以及相关的操作、...
  • 注册表将能读取、写出或刷新包含注册表系统映像的其中一个文件。  1017 系统试图将文件加载或还原到注册表中,但是,指定的文件不是注册表文件格式。  1018 试图在注册表键(已经标记为删除)中完成的操作...
  • jforum2像jforum哪样是一个单例的项目, jforum使用EhCache缓存即可以安全的工作, 但jforum2采用的多项目的分离设计,所以需要一个集中并可多项目共享的缓存. 这样的好处不言而喻,例:版主在管理端任命后前端即时...
  • 由于客户端的硬件配置可能存在差异,软件环能各相同,因此,在安装,必须对每一个客户端分别进行配置,同样,在软件升级也要对客户端分别处理。 B/S模式带来了巨大的好处: 开发成本及维护成本降低。由于B/S...
  • php网络开发完全手册

    热门讨论 2009-03-02 13:17:26
    15.3.5 获得结果集中的某一条记录 244 15.3.6 逐行获取结果集中的每一条 15.3.6 记录 245 15.3.7 结果集的分页 248 15.3.8 用户动态添加记录 249 15.3.9 用户动态更新记录 251 15.3.10 用户动态删除记录 253 15.4 ...
  • 6. 使用JS对表单提交的数据及格式进行校验(是否为空、是否为数字等等) 7. 要求系统具有良好的安全性,能有效防止非法登录用户访问需授权网页。 8. 系统具有良好的人机交互界面,界面应布局清晰、简洁大方。 9. ...
  • asp.net知识库

    2015-06-18 08:45:45
    页面一postback,它就显示页面的最顶端,怎样让它定位在某一位置? 如何保证页面刷新后的滚动条位置 清除网页历史记录,屏蔽后退按钮! 如何传值在2页面之间 :要求刷新父页面,并且能用Querystring传值 Asp...
  • 实例111 使用关系运算符查询某一时间段的数据 实例112 计算两日期间的月份数 第5章 复杂查询技术 5.1 使用子查询 实例113 将子查询作为表达式 实例114 用子查询作为派生表 实例115 通过子查询关联数据 实例116 ...
  • 实例111 使用关系运算符查询某一时间段的数据 实例112 计算两日期间的月份数 第5章 复杂查询技术 5.1 使用子查询 实例113 将子查询作为表达式 实例114 用子查询作为派生表 实例115 通过子查询关联数据 实例116 ...

空空如也

空空如也

1 2
收藏数 36
精华内容 14
关键字:

表单校验时某一个不校验