精华内容
下载资源
问答
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...

     CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。

    我们每天将都会精选CSDN站内技术文章供大家学习,帮助大家系统化学习IT技术。

    这里写图片描述

    jsp简介

    • JSP(Java Server Pages)是JavaWeb服务器端的动态资源,它与html页面的作用是相同的,显示数据和获取数据。
    • jsp: 作为请求发起页面,例如显示表单、超链接。 
      : 作为请求结束页面,例如显示数据。
    • Servlet: 
      作为请求中处理数据的环节。
    • jsp的组成 
      • jsp = html + java脚本 + jsp标签(指令)
      • jsp中可直接使用的对象一共有9个,被称之为9大内置对象
    • 3种java脚本: 
      <%…%>:写java代码片段,(类似方法) 
      <%=…%>:用于输出,用于输出一条表达式(或变量)的结果。 
      <%!…%>:声明,用来创建类的成员变量和成员方法(类似与类)
    • jsp注释:<%– … –%> 
      当服务器把jsp编译成java文件时已经忽略了注释部分!

    jsp原理(看源码)

    • jsp其实是一种特殊的Servlet 
      • 当jsp页面第一次被访问时,服务器会把jsp编译成java文件
      • 然后再把java编译成.class
      • 然后创建该类对象
      • 最后调用它的service()方法
      • 第二次请求同一jsp时,直接调用service()方法。

    jsp三大指令

    page

    <%@page language=”java” info=”xxx”…%>**

    • pageEncoding和contentType: 
      pageEncoding:它指定当前jsp页面的编码,只要不说谎,就不会有乱码!在服务器要把jsp编译成.java时需要使用pageEncoding! 
      contentType:它表示添加一个响应头:Content-Type!等同与response.setContentType(“text/html;charset=utf-8”); 
      如果两个属性只提供一个,那么另一个的默认值为设置那一个。 
      如果两个属性都没有设置,那么默认为iso
    • import:导包!可以出现多次
    • errorPage和isErrorPage 
      errorPage:当前页面如果抛出异常,那么要转发到哪一个页面,由errorPage来指定 
      isErrorPage:它指定当前页面是否为处理错误的页面!当该属性为true时,这个页面会设置状态码为500!而且这个页面可以使用9大内置对象中的exception!
    <error-page>有两种使用方式:
    <error-code>和<location>子元素;
    <exception-type>和<location>子元素;
    其中<error-code>是指定响应码;<location>指定转发的页面;<exception-type>是指定抛出的异常类型。
     <error-page>
        <error-code>404</error-code>
        <location>/error/errorPage.jsp</location>
     </error-page>
          <error-page>
     <exception-type>java.lang.RuntimeException</exception-type>
            <location>/index.jsp</location>
          </error-page>
    • autoFlush和buffer 
      autoFlush:指定jsp的输出流缓冲区满时,是否自动刷新!默认为true,如果为false,那么在缓冲区满时抛出异常! 
      buffer:指定缓冲区大小,默认为8kb,通常不需要修改!
    • isELIgnored:是否忽略el表达式,默认值为false,不忽略,即支持!
    • (以下了解即可): 
      language:指定当前jsp编译后的语言类型,默认值为java。 
      info:信息! 
      isThreadSafe:当前的jsp是否支持并发访问! 
      session:当前页面是否支持session,如果为false,那么当前页面就没有session这个内置对象! 
      extends:让jsp生成的servlet去继承该属性指定的类!

    include –> 静态包含

    • 与RequestDispatcher的include()方法的功能相似!
    • <%@include%> 它是在jsp编译成java文件时完成的!他们共同生成一个java(就是一个servlet)文件,然后再生成一个class!
    • RequestDispatcher的include()是一个方法,包含和被包含的是两个servlet,即两个.class!他们只是把响应的内容在运行时合并了!
    • 作用:把页面分解了,使用包含的方式组合在一起,这样一个页面中不变的部分,就是一个独立jsp,而我们只需要处理变化的页面。

    taglib –> 导入标签库

    • 两个属性: 
      prefix:指定标签库在本页面中的前缀!由我们自己来起名称! 
      uri: 指定标签库的位置! 
      <%@taglib prefix=”s” uri=”/struts-tags”%> 前缀的用法 <s:text>

    九大内置对象

    • 在jsp中无需声明即可直接使用的9个对象 
      • out(JspWriter):等同与response.getWriter(),用来向客户端发送文本数据;
      • config(ServletConfig):对应“真身”中的ServletConfig;
      • page(当前JSP的真身类型):当前JSP页面的“this”,即当前对象,引用为Object类型;
      • pageContext(PageContext):页面上下文对象,它是最后一个没讲的域对象;
      • exception(Throwable):只有在错误页面中可以使用这个对象;
      • request(HttpServletRequest):即HttpServletRequest类的对象;
      • response(HttpServletResponse):即HttpServletResponse类的对象;
      • application(ServletContext):即ServletContext类的对象;
      • session(HttpSession):即HttpSession类的对象,不是每个JSP页面中都可以使用,如果在某个JSP页面中设置<%@page session=”false”%>,说明这个页面不能使用session。
    • pageContext(一个顶9个!) 
      • Servlet中有三大域,而JSP中有四大域! 
        ServletContext:整个应用程序 
        session:整个会话(一个会话中只有一个用户) 
        request:一个请求链! 
        pageContext:一个jsp页面!这个域是在当前jsp页面和当前jsp页面中使用的标签之间共享数据! 
        域对象 
        代理其他域:pageContext.setAttribute(“xxx”, “XXX”, PageContext.SESSION_SCOPE); 
        全域查找:pageContext.findAttribute(“xxx”);从小到大,依赖查找! 
        获取其他8个内置对象:

    JSP动作标签

    动作标签是由tomcat(服务器)来解释执行!而html标签由浏览器来执行!

    • <jsp:include> 
      例如:<jsp:include page="xxx"/>,用来包含指定的页面。假如有两个jsp. 分别为a.jsp和b.jsp,他们分别编码成Servlet,然后在执行Servlet时才会执行包含过程。这也是include指令与include标签的区别。 
      • 注意:<jsp:include page="<%=myfile%>">,这是可以的!因为include指令是在执行时才完成的包含,在执行时已经可以确定myfile这个变量的值。
      • 该标签内部使用的是RequestDispatcher#include()方法完成的包含
    • <jsp:forward> 
      例如:<jsp:forward page="xxx"/>,用来转发到指定页面 
      例如在a.jsp中存在如下内容:<jsp:fowrad page="b.jsp"/> 
      a.jsp中的内容不会显示在浏览器上,而只是显示b.jsp的内容。而且在<jsp:forwad>标签下面的内容不会被执行。
    • <jsp:param> 
      该标签是和的子标签,用来向其他页面传递参数。
    <jsp:include page="/b.jsp">
        <jsp:param value="zhangSan" name="username"/> 
    </jsp:include>

    在b.jsp中可以使用request.getParameter(“username”)来获取参数值。

    javaBean

    • 必须有public的无参的构造器
    • 如果成员变量提供了getter/setter方法,那么称之为javabean属性。

    JavaBean主要是用来通过反射操作的类! 
    因为需要通过Class的newInstance()方法来创建类的实例,所以要求类必须提供public的无参构造器

    内省

    • 内省类 –> Bean信息 –> 属性描述符 –> 属性的get/set对应的Method! — > 反射 
      1. 通过Class对象获取BeanInfo 
        BeanInfo info = Introspector.getBeanInfo(User.class);
      2. 通过BeanInfo获取所有属性描述符对象 
        PropertyDescriptor[] pds = info.getPropertyDescriptors();
      3. PropertyDescriptor: 
        • String name getName():获取当前属性名称
        • Method getReadMethod():获取get方法反射对象
        • Method getWriteMethod():获取set方法反射对象
      1. jar包 commons-beanutils.jar、commons-logging.jar
      2. 通过反射设置Javabean 
        Class<User> clazz = User.class; 
        Object user = clazz.newInstance(); 
        BeanUtils.setProperty(user, “username”, “admin”); 
        BeanUtils.setProperty(user, “password”, “admin123”);
      3. 获取属性值 
        String username = BeanUtils.getProperty(user, “username”);
      4. 把Map数据封装到JavaBean对象中
    Map<String,String> map = new HashMap<String,String>();
    map.put("username", "admin");
    map.put("password", "admin123");

    User user = new User(); 
    BeanUtils.populate(user, map);

    要求:map的key名称必须与User类的属性名称相同。不要无法赋值!

    JSP中与JavaBean相关的标签

    • <jsp:useBean>
    • <jsp:setProperty>
    • <jsp:getProperty>
    <jsp:useBean id="user1" class="cn.domain.User" />

    查看page域中是否存在user1这个域属性,如果存在,那么直接获取。 
    如果不存在,那么创建之! 
    等同与: 
    User user1 = pageContext.getAttribute(“user1”); 
    if(user1 == null) { 
    user1 = new User();//创建user1对象 
    pageContext.setAttribute(“user1”, user1);//保存到page域 
    }

    • 可以通过scope属性来指定操作 

      设置属性值:
    <jsp:setProperty property="username" name="user1" value="admin"/>
    • name:指定名为user1的JavaBean
    • property:指定要设置的属性名称
    • value:指定要设置的属性值 
      等同与 
      User user1 = (User)pageContext.getAttribute(“user1”); 
      user1.setUsername(“admin”);
    **<jsp:getProperty>**

    获取属性值

    <jsp:getProperty property="username" name="user1"/>

    输出user1这个javaBean的username属性值

    等同与 
    User user1 = (User)pageContext.getAttribute(“user1”); 
    out.print(user1.getUsername());

    EL表达式

     

    •  
    • EL:Expression Language,它是可以在JSP页面中直接使用的语言! 
      JSP页面也可以忽略EL:<@page isELIgnored=”true”%> 
      EL用来代替<%=…%>
    • EL 11个内置对象 

     

    EL可以输出的东西都在11个内置对象中!11个内置对象,其中10个是Map!pageContext不是map,它就是PageContext类型,1一个顶九个

    • ${pageScope.xxx}、
    • ${requestScope.xxx}、
    • ${sessionScope.xxx}、
    • ${applicationScope.xxx}
    • param:对应参数,它是一个Map,其中key参数名,value是参数值,适用于单值的参数。
    • paramValues:对应参数,它是一个Map,其中key参数名,value是多个参数值,适用于多值的参数。
    • header:对应请求头,它是一个Map,其中key表示头名称,value是单个头值,适用于单值请求头
    • headerValues:对应请求头,它是一个Map,其中key表示头名称,value是多个头值,适用于多值请求头
    • initParam:获取<context-param>内的参数!
    • cookie:Map<String,Cookie>类型,其中key是cookie的name,value是cookie对象。 ${cookie.username.value}
    • pageContext:它是PageContext类型!${pageContext.request.contextPath}

    • EL操作四大域的内置对象:它们是Map类型 
      pageScope 
      requestScope 
      sessionScope 
      applicationScope

       

    ${pageScope.user}:输出pageContext.getAttribute("user")
    ${requestScope.user}:输出request.getAttribute("user");
    ${sessionScope.user}:输出session.getAttribute("user");
    ${applicationScope.user}:输出application.getAttribute("user");

    ${user} 
    依次在pageScope、requestScope、sessionScope、applicationScope中查找user 
    如果查找到,那么立刻停止查找。

    • 操作JavaBean 
      <% 
      User user = new User(); 
      user.setUsername(“zhangSan”); 
      user.setPassword(“123”); 
      pageContext.setAttribute(“user”, user); 
      %>
    ${pageScope.user.username}
    ${pageScope.user.password}
    • 操作List 
      <% 
      User user = new User(); 
      user.setUsername(“zhangSan”); 
      user.setPassword(“123”); 
      List list = new ArrayList(); 
      list.add(user); 
      pageContext.setAttribute(“list”, list); 
      %>
    ${pageScope.list[0].username}
    ${pageScope.list[0].password}
    • 操作Map 
      <% 
      User user = new User(); 
      user.setUsername(“zhangSan”); 
      user.setPassword(“123”); 
      Map map = new HashMap(); 
      map.put(“u1”, user); 
      pageContext.setAttribute(“map”, map); 
      %>
    ${pageScope.map['u1'].username}
    ${pageScope.map['u1'].password}
    
    ${pageScope.map.u1.username}
    ${pageScope.map.u1.password}

    EL操作参数内置对象:Map类型

    param:Map<String,String>
    paramValues:Map<String,String[]>
    ${param.username}:request.getParameter("username")
    ${paramValues.hobby}:request.getParameterValues("hobby");

    EL操作请求头内置对象:Map类型

    header:Map<String,String>
    headerValues:Map<String,String[]>
    
    ${header.UserAgent}
    ${headerValues.UserAgener[0]
    • 与Cookie相关的内置对象:Map类型
    cookie:Map<String,Cookie>,其中key是Cookie的名称,而值是Cookie对象
    ${cookie.jsessionid.value}:获取sessionid

    • pageContext内置对象:PageContext类型
    ${pageContext.request},等同pageContext.getRequest()
    ${pageContext.session},等同pageContext.getSession()
    
    ${pageContext.request.contextpath},获取项目名
    ${pageContext.session.id},获取sessionId

    • EL中最重要的就是操作四大域! 
      使用EL函数库需要在JSP页面中导入标签库: 
      导入标签库:<%@ tablib prefix=”fn” uri=”http://java.sun.com/jsp/jstl/functions”%> 
      String toUpperCase(String input):把参数转换成大写 
      String toLowerCase(String input):把参数转换成小写 
      int indexOf(String input, String substring):从大串,输出小串的位置! 
      boolean contains(String input, String substring):查看大串中是否包含小串 
      boolean containsIgnoreCase(String input, String substring):忽略大小写的,是否包含 
      boolean startsWith(String input, String substring):是否以小串为前缀 
      boolean endsWith(String input, String substring):是否以小串为后缀 
      String substring(String input, int beginIndex, int endIndex):截取子串 
      String substringAfter(String input, String substring):获取大串中,小串所在位置后面的字符串 
      substringBefore(String input, String substring):获取大串中,小串所在位置前面的字符串 
      String escapeXml(String input):把input中“<”、”>”、”&”、”’”、”“”,进行转义 
      String trim(String input):去除前后空格 
      String replace(String input, String substringBefore, String substringAfter):替换 
      String[] split(String input, String delimiters):分割字符串,得到字符串数组 
      int length(Object obj):可以获取字符串、数组、各种集合的长度! 
      String join(String array[], String separator):联合字符串数组!
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/function"%>
    
    <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    …
    String[] strs = {"a", "b","c"};
    List list = new ArrayList();
    list.add("a");
    pageContext.setAttribute("arr", strs);
    pageContext.setAttribute("list", list);
    %>
    ${fn:length(arr) }<br/><!--3-->
    ${fn:length(list) }<br/><!--1-->
    ${fn:toLowerCase("Hello") }<br/> <!-- hello -->
    ${fn:toUpperCase("Hello") }<br/> <!-- HELLO -->
    ${fn:contains("abc", "a")}<br/><!-- true -->
    ${fn:containsIgnoreCase("abc", "Ab")}<br/><!-- true -->
    ${fn:contains(arr, "a")}<br/><!-- true -->
    ${fn:containsIgnoreCase(list, "A")}<br/><!-- true -->
    ${fn:endsWith("Hello.java", ".java")}<br/><!-- true -->
    ${fn:startsWith("Hello.java", "Hell")}<br/><!-- true -->
    ${fn:indexOf("Hello-World", "-")}<br/><!-- 5 -->
    ${fn:join(arr, ";")}<br/><!-- a;b;c -->
    ${fn:replace("Hello-World", "-", "+")}<br/><!-- Hello+World -->
    ${fn:join(fn:split("a;b;c;", ";"), "-")}<br/><!-- a-b-c -->
    
    ${fn:substring("0123456789", 6, 9)}<br/><!-- 678 -->
    ${fn:substring("0123456789", 5, -1)}<br/><!-- 56789 -->
    ${fn:substringAfter("Hello-World", "-")}<br/><!-- World -->
    ${fn:substringBefore("Hello-World", "-")}<br/><!-- Hello -->
    ${fn:trim("     a b c     ")}<br/><!-- a b c -->
    ${fn:escapeXml("<html></html>")}<br/> <!-- <html></html> -->

    自定义函数库

    • 写一个java类,类中可以定义0~N个方法,但必须是static,而且有返回值的!
    • 在WEB-INF目录下创建一个tld文件
      <function>
        <name>fun</name>
        <function-class>haha.fn.MyFunction</function-class>
        <function-signature>java.lang.String fun()</function-signature>
      </function>
    • 在jsp页面中导入标签库 
      <%@ taglib prefix=”it” uri=”/WEB-INF/tlds/haha.tld” %>
    • 在jsp页面中使用自定义的函数:${it:fun() }

    JSTL

    • JSTL是apache对EL表达式的扩展

    jstl标签库

    • core:核心标签库,
    • fmt:格式化标签库
    • sql:数据库标签库,过时;
    • xml:xml标签库,过时。

    <c:core>

    • <c:out value=”aaa”/> 输出字符串aaa
    • <c:out value="${aaa}”/> 输出域属性aaa,其中与${aaa}相同
    • <c:out value="${aaa}” default=”xxx”/>如果${aaa}不存在,那么输出xxx字符串
    • <c:out value="${aaa}" escapeXml=”true”/>如果${aaa}中包含特殊字符,那么转义它。这可以防止javascript攻击

    <c:set>

    • <c:set var=”a” value=”hello”/> 创建名为a,值为hello的域属性,范围:page
    • <c:set var=”a” value=”hello” scope=”session”/> 范围为session(page、request、session、application)

    <C:remove>

    • <c:remove var=”a”/> 删除名为a的域属性
    • <c:remove var=”a” scope=”page”/> 删除page域中名为a的域属性

    <C:url>

    • <c:url value=”/AServlet”/> 输出URL:/项目名/AServlet
    • <c:url value=”/AServlet” var=”url” scope=”page”/> 把生成的url保存到page域中,而不会输出
    • 子标签:<c:param>,用来给url后面添加参数,例如:
        <c:url value="/index.jsp">
          <c:param name="username" value="张三"/>  <!--可以对参数进行url编码!!-->
        </c:url>
    结果为:/day13_1/index.jsp?username=%ED%2C%3F%ED%2C%3F
    

    * var:指定变量名,一旦添加了这个属性,那么url标签就不会再输出到页面,而是把生成url保存到域中。 
    * scope:它与var一起使用,用来保存url。

    <C:if>

    *<c:if test=”${条件}”> 当条件为true时执行标签体内容 
    hello 

    <c:choose>

    <c:set var="score" value="${param.score }"/>
    <c:choose>
        <c:when test="${score > 100 || score < 0}">错误的分数:${score }</c:when>[if]
        <c:when test="${score >= 90 }">A级</c:when>
        <c:when test="${score >= 80 }">B级</c:when>
        <c:when test="${score >= 70 }">C级</c:when>
        <c:when test="${score >= 60 }">D级</c:when>
        <c:otherwise>E级</c:otherwise>[else]
    </c:choose>

    <c:forEach>

    <c:forEach var="i" begin="1" end="10">
        ${i}
      </c:forEach>

    属性: 
    * var:循环变量 
    * begin:设置循环变量从几开始。 
    * end:设置循环变量到几结束。 
    * step:设置步长!等同与java中的i++,或i+=2。step默认为1

    • 遍历集合或数组方式:
    <%
    String[] names = {"zhangSan", "liSi", "wangWu", "zhaoLiu"};
    pageContext.setAttribute("ns", names);
    %>
    <c:forEach var="item" items="${ns }">
        <c:out value="name: ${item }"/><br/>
    </c:forEach>
    • 遍历List
    <%
        List<String> names = new ArrayList<String>();
        names.add("zhangSan");
        names.add("liSi");
        pageContext.setAttribute("ns", names);
    %>
    <c:forEach var="item" items="${ns }">
        <c:out value="name: ${item }"/><br/>
    </c:forEach>
    • 遍历Map
    <%
        Map<String,String> stu = new LinkedHashMap<String,String>();
        stu.put("number", "N_1001");
        stu.put("name", "zhangSan");
        pageContext.setAttribute("stu", stu);
    %>
    <c:forEach var="item" items="${stu }">
        <c:out value="${item.key }: ${item.value }"/><br/>
    </c:forEach>
    • 循环状态

    循环状态变量有如下属性: 
    * count:循环元素的个数 
    * index:循环元素的下标 
    * first:是否为第一个元素 
    * last:是否为最后一个元素 
    * current:当前元素

    <c:forEach items="${list }" var="ele" varStatus="vs">
        ${vs.index} ${vs.count } ${vs.first } ${vs.last } ${vs.current }<br/>
    </c:forEach>

    fmt库

    • <fmt:formatDate value=”” pattern=”“> 
      value:指定一个Date类型的变量 
      pattern:用来指定输出的模板!例如:yyyy-MM-dd HH:mm:ss 
      <fmt:formatNumber value=”${num1}” pattern=”0.00”> 
      保留小数点后2位,它会四舍五入!如果不足2位,以0补位! 
      <fmt:formatNumber value=”${num1}” pattern=”#.##”> 
      保留小数点后2位,它会四舍五入!如果不足2位,不补位!

    自定义标签(实现SimpleTag接口,即简单标签)

    步骤: 
    1. 标签处理类:继承SimpleTagSupport类 
    public class HelloTag extends SimpleTagSupport { 
    public void doTag() throws JspException, IOException { 
    this.getJspContext().getOut().write(“<p>Hello SimpleTag!</p>“) ; 

    }

    标签描述符文件(tld) 
    /WEB-INF/tlds/haha.tld

    <?xml version="1.0" encoding="UTF-8"?>
    <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xml="http://www.w3.org/XML/1998/namespace" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
                            http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd ">
    
        <tlib-version>1.0</tlib-version> 
        <short-name>haha</short-name> 
        <uri>http://www.haha.cn/tags</uri> 
        <tag> 
            <name>hello</name> <!--标签名称-->
            <tag-class>cn.haha.tag.HelloTag</tag-class> <!--标签处理类名称-->
            <body-content>empty</body-content> <!--标签体为空,即空标签-->
        </tag>
    </taglib>
    1. jsp页面中使用自定义标签
    <%@ taglib prefix="it"  uri="/WEB-INF/hello.tld"  %>
    ......
    <it:hello/>

    有标签体的标签

    1. 标签处理类 
      public class HelloTag extends SimpleTagSupport { 
      public void doTag() throws JspException, IOException { 
      PageContext pc = (PageContext) this.getJspContext(); 
      HttpServletRequest req = (HttpServletRequest) pc.getRequest(); 
      String s = req.getParameter(“exec”); 
      if(s != null && s.endsWith(“true”)) { 
      // 获取标签体对象 
      JspFragment body = this.getJspBody() ; 
      // 执行标签体 
      body.invoke (null); 
      }


      }

    2. tld

    <tag>
            <name>hello</name>
            <tag-class>cn.itcast.tags.HelloTag</tag-class>
            <body-content>scriptless</body-content> <!--标签体内容不可以是java脚本,但可以是el、jstl等-->
        </tag>

    不执行标签下面的页面内容

    public void doTag() throws JspException, IOException {
        this.getJspContext().getOut().print("<h1>只能看到我!</h1>");
        throw new SkipPageException();
    }
    

    带有属性的标签

    public class IfTag extends SimpleTagSupport { 
    private boolean test;//设置属性,提供getter/setter方法 
    public boolean isTest() { 
    return test; 

    public void setTest (boolean test) { 
    this.test = test; 

    @Override 
    public void doTag() throws JspException, IOException { 
    if(test) {//如果test为true,执行标签体内容 
    this.getJspBody().invoke(null); 


    }

    <tag> 
        <name>if</name> 
        <tag-class>cn.haha.tag.IfTag</tag-class> 
        <body-content>scriptless</body-content>
        <!--部署属性-->
        <attribute> 
            <name>test</name> <!--属性名-->
            <required>true</required> <!--属性是否为必须的-->
            <rtexprvalue>true</rtexprvalue> <!--属性值是否可以为EL或JSTL等-->
        </attribute> 
    </tag>

     

    关于CSDN软件工程师能力认证

          CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。C系列认证的宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家数字化战略贡献力量。

     

    了解详情可点击:CSDN软件工程师能力认证介绍

     

    本文出处:https://blog.csdn.net/yeiweilan/article/details/69948491?ops_request_misc=&request_id=&biz_id=102&utm_term=jsp&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-69948491.pc_search_result_before_js&spm=1018.2226.3001.4187

    展开全文
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...

    CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。

    我们每天将都会精选CSDN站内技术文章供大家学习,帮助大家系统化学习IT技术。

    简述

    Python有时候太慢,如果手动编译C或者是C++来写#include<Python.h>的文件也比较麻烦。
    CPython无疑是一个比较好的选择。

    这篇教程是基于

    改进的理由

    来源于link1的

    1. 每一行的计算量很少,因此python解释器的开销就会变的很重要。
    2. 数据的局部性原理:很可能是,当使用C的时候,更多的数据可以塞进CPU的cache中,因为Python的元素都是Object,而每个Object都是通过字典实现的,cache对这个数据不很友好。

    项目

    Hello World项目

    第一个项目是Hello world。

    创建一个文件helloworld.pyx,内容如下:

    print("Hello world!")
    

    保存后,创建setup.py文件,内容如下:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules = cythonize("helloworld.pyx")
    )
    

    保存后,命令行进入setup.py所在目录,并输入python setup.py build_ext --inplace,如下:

    PS D:\Code\CPython\Test> python setup.py build_ext --inplace
    Compiling helloworld.pyx because it changed.
    [1/1] Cythonizing helloworld.pyx
    running build_ext
    building 'helloworld' extension
    creating build
    creating build\temp.win-amd64-3.6
    creating build\temp.win-amd64-3.6\Release
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Users\lijy2\AppData\Local\Programs\Python\Python36\include -IC:\Users\lijy2\AppData\Local\Programs\Python\Python36\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\cppwinrt" /Tchelloworld.c /Fobuild\temp.win-amd64-3.6\Release\helloworld.obj
    helloworld.c
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\HostX86\x64\link.exe /nologo
    /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Users\lijy2\AppData\Local\Programs\Python\Python36\libs /LIBPATH:C:\Users\lijy2\AppData\Local\Programs\Python\Python36\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.16299.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.16299.0\um\x64" /EXPORT:PyInit_helloworld build\temp.win-amd64-3.6\Release\helloworld.obj /OUT:D:\Code\CPython\Test\helloworld.cp36-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.6\Release\helloworld.cp36-win_amd64.lib
      正在创建库 build\temp.win-amd64-3.6\Release\helloworld.cp36-win_amd64.lib 和对象 build\temp.win-amd64-3.6\Release\helloworld.cp36-win_amd64.exp
    正在生成代码
    已完成代码的生成
    

    在该目录下的命令行进入Python操作界面,导入包之后,就会自动输出Hello world!,如下:

    PS D:\Code\CPython\Test> python
    Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import helloworld
    Hello world!
    

    这就完成了一个简单的CPython的扩展书写。下面再举例子。

    Fibonacci Function项目

    斐波那契数列:1, 1, 2, 3, 5,…
    前两位为1,之后每个数等于前面两个数之和。

    创建fib.pyx,内容如下:

    from __future__ import print_function
    
    def fib(n):
        a, b = 0, 1
        while b < n:
            print(b, end=' ')
            a, b = b, a + b
        print()
    

    创建setup.py文件,内容如下:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules = cythonize("fib.pyx")
    )
    

    通过命令python setup.py build_ext --inplace,生成出来的文件:

    import fib
    fib.fib(100)
    

     

    输出:

    1 1 2 3 5 8 13 21 34 55 89
    
    • 但是经过测试之后,发现速度并没有很高的提升,很可能是操作本来就很简单,数值也很小,没什么优化的空间了。

    Primes项目

    给一个数值n,输出前n个质数(list)。

    写到primes.pyx中:

    def primes(int nb_primes):
        cdef int n, i, len_p
        cdef int p[1000]
        if nb_primes > 1000:
            nb_primes = 1000
        
        len_p = 0
        n = 2
        while len_p < nb_primes:
            for i in p[:len_p]:
                if n % i == 0:
                    break
            else:
                p[len_p] = n
                len_p += 1
            n += 1
        result_as_list = [prime for prime in p[:len_p]]
        return result_as_list
    

    同理,setup.py文件内容为:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules = cythonize("primes.pyx")
    )
    
    •  

    在参考的link中给出了测试的案例,有些解释的不太好,我这边描述一下

    • 直接使用Python实现版本,平均用时23ms
    • Python版本用CPython编译(对,直接把Python文件名字像pyx一样放进去就好了), 平均用时11ms
    • pyx的CPython编译版本,平均用时1.6ms

    Stat项目

    注意,这里不能直接使用stat,因为似乎是有这个库了emmmm

    stat_.pyx:

    from libc.math cimport sqrt
    
    def mean(list arr):
        cdef:
            int i
            int sz
            double tmp
        tmp = 0
        sz = len(arr)
        for i in range(sz):
            tmp += arr[i]
        return tmp / sz
    
    def std(list arr):
        cdef:
            double m = mean(arr)
            int sz, i
            double tmp
        sz = len(arr)
        tmp = 0
        for i in range(sz):
            tmp += (arr[i] - m) ** 2
        return sqrt(tmp)
    

    setup.py:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules = cythonize("stat_.pyx")
    )
    

    命令还是一样的:python setup.py build_ext --inplace

    测试:

    >>> import stat_
    >>> a = [1,2,3]
    >>> stat_.mean(a)
    2.0
    >>> stat_.std(a)
    1.4142135623730951

     

    关于CSDN软件工程师能力认证

          CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。C系列认证的宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家数字化战略贡献力量。

     

    了解详情可点击:CSDN软件工程师能力认证介绍

     

    本文出处:https://blog.csdn.net/a19990412/article/details/93130293?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161421800016780261942815%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161421800016780261942815&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-93130293.pc_search_result_before_js&utm_term=CPython&spm=1018.2226.3001.4187

    展开全文
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...

    CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。

    我们每天将都会精选CSDN站内技术文章供大家学习,帮助大家系统化学习IT技术。


    为什么要用vue

    传统的网页形式是浏览器脚本语言js连接了各种各样的Html,css,但缺乏正规的组织形式,比如在页面元素非常多,结构很庞大的网页中,数据和视图如果全部混杂在一起,像传统开发一样全部混合在HTML中,那么要对它们进行处理会十分的费劲,并且如果其中有几个结构之间存在藕断丝连的关系,那么会导致代码上出现更大的问题,比如juqery中使用的

    $('#xxx').parent().parent().parent()


    一开始很好查找,但当页面结构发生变化,也就是说DOM的关联与嵌套层次要发生改变,那么之前的代码可能就会变成这样了:

    $('#xxx').parent().parent().parent().parent().parent()

     


    这样产品迭代后,对dom节点的查找操作等行为会有很大的性能损耗。

    vue是一款友好的、多用途的且高性能的js框架,它可以帮你创建可维护性和可测试性更强的代码库。官网对vue的优点描述是这样的:

    å¨è¿éæå¥å¾çæè¿°
    1.易用:
    学习曲线平缓,api简洁,容易上手。学习过程较react来说比较容易,不那么痛苦

    2.灵活:
    如果你已经有一个现成的服务端框架,你可以将vue作为其中的一部分嵌入,带来更加丰富的交互系统 ,或者你希望将更多业务逻辑放到前端来实现,那么vue的核心库及其生态系统也可以满足你的各式需求,vue允许你将网页分割成可复用的组件,每个组件都可以包含自身的html,css,js文件,以用来渲染网页中相应的地方。

    3.高效:
    虚拟dom: 其数据全部在内存中,只有js引擎参与其中
    而真实dom会有浏览器渲染层在其中
    你的知道浏览器的虚拟DOM与真实DOM的区别(注意:需不需要虚拟DOM,其实与框架的DOM操作机制有关):

    虚拟DOM不会进行排版与重绘操作

    虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分(注意!),最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗

    真实DOM频繁排版与重绘的效率是相当低的

    虚拟DOM有效降低大面积(真实DOM节点)的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部(同2)

    使用虚拟DOM的损耗计算:

    总损耗 = 虚拟DOM增删改 + (与Diff算法效率有关)真实DOM差异增删改 + (较少的节点)排版与重绘

    直接使用真实DOM的损耗计算:

    总损耗 = 真实DOM完全增删改 + (可能较多的节点)排版与重绘

    只能说 虚拟DOM 只是减少了一些情况下, 对真实DOM操作的 次数.

    虚拟DOM只是个 JavaScript object

    它会在 对比 后再选择更新哪些DOM, 而不会像有些时候, 全部删除再重建.

    获取/修改 大量DOM元素的时候,就会先在 虚拟DOM 里 取值 对比.

    虚拟dom是在内存中维护的dom树,是在实体dom之上的一层抽象。有了这层抽象,不管是查询操作还是修改操作,都是先操作内存中的虚拟dom,在这个过程中可以做很多优化,从而减少对实体dom的操作。举两个例说明,1. 查询一个text标签的值,可以直接从虚拟dom中查找得到,根本不需要查询实体dom。2. 在一次操作中,要修改列表中的两条记录,要修改的元素会先把变更同步到虚拟dom上,然后根据最新的虚拟dom,一次性渲染出最终的实体dom,如果没有虚拟dom,两条记录的修改至少要对应两次对实体dom的操作,显然操作实体dom越频繁,网页速度越慢。

    对于vue.js的Virtual DOM,目前业界有着褒贬不一的评价。有人认为Vue.js作为一个轻量级框架,引入Virtual DOM会加大Vue.js本身的代码尺寸,也会消耗更多CPU(手机上会更耗电)(注意:消耗更多的CPU并不意味着会更卡,因为JavaScript计算是后台计算,他的计算量还不至于让DOM操作变得卡顿),并且在操作单个DOM元素的时候,反而多了一道计算工序,会更慢。但也有人认为基本上会用Vue.js开发的都是页面中内容很多的元素,肯定操作的DOM量级普遍较大,平均一下还是比较划算的。

    4.社区和第三方组件库丰富


    社区
    论坛(https://forum.vuejs.org/) - 提问答疑的最好地方。
    Gitter(https://gitter.im/vuejs/vue) - 开发者聊天室。在这里你可以提问,不过最好在论坛提问,因为论坛有版块。
    Github(https://github.com/vuejs) - 报告问题,提交请求,为你所做的任何贡献表示深深感谢!
    vue组件库:
    element-ui Mint UI
    muse-ui


    vue是什么


    1.Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。


    这里渐进式框架也就是上边vue特点中的灵活一项,使用vue,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;

    比如说刚开始用数据绑定做一个表单,后来控制整个页面的dom,再后来用router控制路由做单页应用,组件配合,vuex与数据配合等等,使用vue,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用。

    模åä¸å¯å¤ç¨ç»ä»¶

    2.Vue 只关注视图层, 采用自底向上增量开发的设计。
    视图层:
    那么HTML中的DOM其实就是视图,一个网页就是通过DOM的组合与嵌套,形成了最基本的视图结构,再通过CSS的修饰,在基本的视图结构上“化妆”让他们看起来更加美观。最后涉及到交互部分,就需要用到JavaScript来接受用户的交互请求,并且通过事件机制来响应用户的交互操作,并且在事件的处理函数中进行各种数据的修改,比如说修改某个DOM中的innerHTML或者innerText部分。

    我们把HTML中的DOM就可以与其他的部分独立开来划分出一个层次,这个层次就叫做视图层。

    MVVM
    是Model-View-ViewModel 的缩写,由 Model,View,ViewModel 三部分构成,Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。

    å¨è¿éæå¥å¾çæè¿°

    å¨è¿éæå¥å¾çæè¿°

    Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

    MVC
    控制器负责对模型中的数据进行更新,而视图向模型中请求数据;当有用户的行为触发操作时,会有控制器更新模型,并通知视图进行更新,在这时视图向模型请求新的数据

    å¨è¿éæå¥å¾çæè¿°
    3.Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
    响应的数据绑定:
    就是vue.js会自动响应数据的变化情况,并且根据用户在代码中预先写好的绑定关系,对所有绑定在一起的数据和视图内容都进行修改。而这种绑定关系,在图上是以input 标签的v-model属性来声明的,因此你在别的地方可能也会看到有人粗略的称vue.js为声明式渲染的模版引擎。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>vue.js测试 -</title>
    	<script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
    	<div id="app">
    		<input type="text" name="" value="" placeholder="在这里输入文字,下面会跟着变化" v-model="message">
    		<hr>
    		<p>{{ message }}</p>
    	</div>
    	<script type="text/javascript">
    		var app = new Vue({
    		  el: '#app',
    		  data: {
    		    message: 'Hello Vue!'
    		  }
    		})
    	</script>
    </body>
    </html>
    
    

    组合的视图组件:
    Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component)中,我们只要先在父级应用中写好各种组件标签(占坑),并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现(填坑).

    组件自由组合形成功能完整的界面,当不需要某个组件,或者想要替换某个组件时,可以随时进行替换和删除,而不影响整个应用的运行(组件化)

    å¨è¿éæå¥å¾çæè¿°

    组件化优点:
    提高开发效率
    方便重复使用
    简化调试步骤
    提升整个项目的可维护性
    便于协同开发
    ————————————————

    关于CSDN软件工程师能力认证

          CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。C系列认证的宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家数字化战略贡献力量。

     

    了解详情可点击:CSDN软件工程师能力认证介绍


    原文链接:https://blog.csdn.net/weixin_38318244/article/details/85037067

    展开全文
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...

    CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。

    我们每天将都会精选CSDN站内技术文章供大家学习,帮助大家系统化学习IT技术。

    1.1 排序

    通过order by语句,可以将查询出的结果进行排序。放置在select语句的最后。
    格式:
    SELECT * FROM 表名 ORDER BY 排序字段ASC|DESC;
    ASC 升序 (默认)
    DESC 降序

    1.查询所有商品信息,使用价格排序(降序)

    SELECT * FROM product ORDER BY price DESC;

    2.在价格排序(降序)的基础上,以分类排序(降序)

    SELECT * FROM product ORDER BY price DESC,category_id DESC;

    3.显示商品的价格(去重复),并排序(降序)

    SELECT DISTINCT price FROM product ORDER BY price DESC;

    1.2 聚合

    之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,他是对查询后的结果的列进行计算,然后返回一个单一的值;另外聚合函数会忽略空值。
    今天我们学习如下五个聚合函数:
     count:统计指定列不为NULL的记录行数;
     sum:计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
     max:计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
     min:计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
     avg:计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;

    1 查询商品的总条数

    SELECT COUNT(*) FROM product;

    2 查询价格大于200商品的总条数

    SELECT COUNT(*) FROM product WHERE price > 200;

    3 查询分类为'c001'的所有商品价格的总和

    SELECT SUM(price) FROM product WHERE category_id = 'c001';

    4 查询分类为'c002'所有商品的平均价格

    SELECT AVG(price) FROM product WHERE category_id = 'c002';

    5 查询商品的最大价格和最小价格

    SELECT MAX(price),MIN(price) FROM product;

    1.3 分组

    分组查询是指使用group by字句对查询信息进行分组。
     格式:
    SELECT 字段1,字段2… FROM 表名GROUP BY分组字段 HAVING 分组条件;
    分组操作中的having子语句,是用于在分组后对数据进行过滤的,作用类似于where条件。

     having与where的区别:
     having是在分组后对数据进行过滤.
    where是在分组前对数据进行过滤
     having后面可以使用统计函数过滤数据
    where后面不可以使用统计函数。

    0 统计所有商品的个数

    1 统计各个分类商品的个数

    SELECT category_id ,COUNT(*) FROM product GROUP BY category_id ;

    2 统计各个分类商品的个数,且只显示个数大于1的信息

    SELECT category_id ,COUNT() FROM product GROUP BY category_id HAVING COUNT() > 1;

    1.4 分页查询

    分页查询在项目开发中常见,由于数据量很大,显示屏长度有限,因此对数据需要采取分页显示方式。例如数据共有30条,每页显示5条,第一页显示1-5条,第二页显示6-10条。
     格式:
    SELECT 字段1,字段2… FROM 表明 LIMIT M,N
    M: 整数,表示从第几条索引开始,计算方式 (当前页-1)*每页显示条数
    N: 整数,表示查询多少条数据
    SELECT 字段1,字段2… FROM 表明 LIMIT 0,5
    SELECT 字段1,字段2… FROM 表明 LIMIT 5,5

    第2章 SQL备份与恢复

    2.1 SQL备份

    选中数据库,右键”备份/导出”,指定导出路径,保存成.sql文件即可。

     

     

    2.2 SQL恢复

    数据库列表区域右键“从SQL转储文件导入数据库”,指定要执行的SQL文件,执行即可。

     

     

    第3章 SQL约束

    3.1 数据完整性

    添加数据完整性=添加表约束
    分类:实体完整性,域完整性,引用完整性
    实体完整性: 对数据行的约束,比如:主键约束,唯一约束
    域完整性: 对数据列的约束,比如:该列的数据类型, 默认约束,非空约束
    引用完整性: 外键约束(多表的关系)

    3.2 主键约束

    PRIMARY KEY 约束唯一标识数据库表中的每条记录,每条记录中被主键约束 约束的字段不能相同。
    主键必须是唯一的值。
    主键列不能是 NULL 值。
    每个表都应该有且只能有一个主键。

    3.2.1 添加主键约束

     方式一:创建表时,在字段描述处,声明指定字段为主键:
    CREATE TABLE Persons
    (
    Id_P int PRIMARY KEY,
    LastName varchar(255),
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
    )
     方式二:创建表时,在constraint约束区域,声明指定字段为主键:
     格式:[constraint 名称] primary key (字段列表)
     关键字constraint可以省略,如果需要为主键命名,constraint不能省略,主键名称一般没用。
     字段列表需要使用小括号括住,如果有多字段需要使用逗号分隔。声明两个以上字段为主键,我们称为联合主键。
    CREATE TABLE Persons
    (
    FirstName varchar(255),
    LastName varchar(255),
    Address varchar(255),
    City varchar(255),
    CONSTRAINT pk_PersonID PRIMARY KEY (FirstName,LastName)
    )

    CREATE TABLE Persons
    (
    FirstName varchar(255),
    LastName varchar(255),
    Address varchar(255),
    City varchar(255),
    PRIMARY KEY (FirstName)
    )

     方式三:创建表之后,通过修改表结构,声明指定字段为主键:
    ALTER TABLE Persons ADD [CONSTRAINT 名称] PRIMARY KEY (字段列表)

    CREATE TABLE Persons
    (
    FirstName varchar(255),
    LastName varchar(255),
    Address varchar(255),
    City varchar(255)
    )
    ALTER TABLE Persons ADD PRIMARY KEY (FirstName)

    3.2.2 删除主键约束

    如需撤销 PRIMARY KEY 约束,请使用下面的 SQL:
    ALTER TABLE Persons DROP PRIMARY KEY

    3.3 自动增长列

    我们通常希望在每次插入新记录时,数据库自动生成字段的值。
    我们可以在表中使用 auto_increment(自动增长列)关键字,自动增长列类型必须是整形,自动增长列必须为键(一般是主键)。
     下列 SQL 语句把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键
    CREATE TABLE Persons
    (
    P_Id int PRIMARY KEY AUTO_INCREMENT,
    LastName varchar(255),
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
    )
     向persons添加数据时,可以不为P_Id字段设置值,也可以设置成null,数据库将自动维护主键值:
    INSERT INTO Persons (FirstName,LastName) VALUES ('Bill','Gates')
    INSERT INTO Persons (P_Id,FirstName,LastName) VALUES (NULL,'Bill','Gates')
     面试:delete和truncate的区别
     Delete删除表中的数据,但不重置auto-increment记录数。
     Truncate删除表中的数据,auto-increment记录数将重置。Truncate其实先删除表然后再创建表。
     扩展:默认地,AUTO_INCREMENT 的开始值是 1,如果希望修改起始值,请使用下列 SQL 语法:
    ALTER TABLE Persons AUTO_INCREMENT=100

    3.4 非空约束NOT NULL

    NOT NULL 约束强制列不接受 NULL 值。
    NOT NULL 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。
     方式一:创建表,下面的 SQL 语句强制 "Id_P" 列和 "LastName" 列不接受 NULL 值:
    CREATE TABLE Persons
    (
    Id_P int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
    )

     方式二:修改表结构
    添加非空约束 ALTER TABLE student MODIFY LastName varchar(255) NOT NULL

    删除非空约束 ALTER TABLE student MODIFY LastName varchar(255) 
    

    3.5 唯一约束

    UNIQUE 约束唯一标识数据库表中的每条记录。
    UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。
    PRIMARY KEY 拥有自动定义的 UNIQUE 约束。
    请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。

    3.5.1 添加唯一约束

    与主键添加方式相同,共有3种,
     方式1:创建表时,在字段描述处,声明唯一:
    CREATE TABLE Persons
    (
    Id_P int UNIQUE,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
    )
     方式2:创建表时,在约束区域,声明唯一:
    CREATE TABLE Persons
    (
    Id_P int,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255),
    CONSTRAINT 名称UNIQUE (Id_P)
    )

     方式3:创建表后,修改表结构,声明字段唯一:
    ALTER TABLE Persons ADD [CONSTRAINT 名称] UNIQUE (Id_P)

    3.5.2 删除唯一约束

     如需撤销 UNIQUE 约束,请使用下面的 SQL:
    ALTER TABLE Persons DROP INDEX 约束名称
     如果添加唯一约束时,没有设置约束名称,默认是当前字段的字段名。

    唯一约束与主键约束的区别:
    主键:唯一、不能为空、一个表只能有一个主键,非业务数据
    唯一:唯一、可以有空值,但只能有一个空值。一个表可以有多个唯一约束。

    3.6 默认约束

    在添加数据中,如果该字段不指定值,采用默认值处理
     方式一: 创建表,字段处声明
    CREATE TABLE Persons
    (
    Id_P int,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255) DEFAULT '北京',
    City varchar(255)
    )
     方式二: 修改表结构
    ALTER TABLE Persons MODIFY Address VARCHAR(255) DEFAULT '北京'
    删除默认约束ALTER TABLE Persons MODIFY Address VARCHAR(255)

     

    关于CSDN软件工程师能力认证

          CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。C系列认证的宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家数字化战略贡献力量。

     

    了解详情可点击:CSDN软件工程师能力认证介绍

     

    本文出处:https://blog.csdn.net/u011676417/article/details/86568017?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161405184416780265449431%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161405184416780265449431&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-86568017.pc_search_result_before_js&utm_term=SQL查询&spm=1018.2226.3001.4187

    展开全文
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • 摘要:CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,我们每天都会精选CSDN站内技术文章供大家学习。 对于入门java将近两年的时间,曾经迷惘过,一直想知道java的具体学习路线,看过了许许多多...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家...
  • 摘要:CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家...
  • CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家...
  • CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...
  • CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 132
精华内容 52
关键字:

CSDN软件工程师能力认证