首页 文章 精选 留言 我的

精选列表

搜索[后台管理模板],共10000篇文章
优秀的个人博客,低调大师

后台(19)——事务Transaction

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 事务简介 事务(Transaction)是数据库操作中并发控制的基本单位。事务是一个操作序列,这个序列中的所有数据库操作要么都成功执行,要么都不执行,它是一个不可分割的工作单位。 在数据库中与事务相关的操作有: 开启事务:start transaction 提交事务:commit 回滚事务:rollback 事务的特性 原子性 事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 一致性 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。比如:两个账户相互转账,那么转账前和转账后的总金额不变。 隔离性 多个用户并发访问数据库时,数据库为每一个用户开启的事务不能被其他事务的操作数据所干扰;即多个并发事务之间要相互隔离。 持久性 事务一旦被提交,它对数据库中数据的改变就是永久性的,即使数据库发生故障也不应该对其有任何影响 事务的四大特性中原子性,一致性,持久性很好理解,在此不再赘述。 下面重点介绍一下事务的隔离级别。 在多个线程中各自开启事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。假如,事务不考虑隔离性可能会引发如下问题: 赃读 在一个事务中读取了另一个事务未提交的数据。 不可重复读 在一个事务内读取表中的某些数据,多次读取结果不同;即一个事务读取到了另一个事务提交后的数据。比如:开启事务后利用SQL语句查询数据,得到结果;立即再次查询得到的结果却与刚才不一样。通俗地说,不可重复读就是:自己的事务还没有提交,又读到了其它事务中执行了upate并提交的数据。 虚读 是指在一个事务内读取到了别的事务中执行insert并提交的数据,导致前后读取不一致。 数据库通过设置事务的隔离级别防止以上情况的发生,常用的事务级别有如下几种: 1、READ UNCOMMITTED 将事务级别设置为该级别后,赃读、不可重复读、虚读都有可能发生。 2、READ COMMITTED 将事务级别设置为该级别后,可避免赃读;但是不可重复读、虚读都有可能发生 3、REPEATABLE READ 将事务级别设置为该级别后,避免赃读、不可重复读;但是虚读有可能发生。 4、SERIALIZABLE 将事务级别设置为该级别后,可避免赃读、不可重复读以及虚读。 关于数据库的事务级别,请注意: 事务级别越高那么数据操作越安全但是操作性能越低 在MySQL中可利用SELECT @@TX_ISOLATION查看当前的事务隔离级别 在MySQL中可利用SET TRANSACTION ISOLATION LEVEL XXXXX 更改事务隔离级别 应在开启事务之前设置隔离级别 JDBC中控制事务以及操作事务 利用connection.setTransactionIsolation(int level)设置隔离级别 利用connection.setAutoCommit(false)开启事务 利用connection.commit( )提交事务 利用connection.rollback( )回滚事务

优秀的个人博客,低调大师

后台(17)——JSP(3)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 今天我们继续学习JSP中的EL和JSTL。 EL表达式 EL(expression language)表达式是JSP中获取数据的一种规范,它主要用于简化jsp中java代码开发。 利用EL表达式获取数据 我们利用EL表达式获取数据,但是请务必注意它只可以获取存在4个作用域中的数据。 语法格式:${ } 比如,我们在session中存了数据: session.setAttribute(“name”, “波少野结衣”); 那么我们可以利用EL表达式获取存的数据 ${name} 嗯哼,这里使用EL表达式就非常简单了,究其根本是因为${}背后执行的是pageContext.findAttribute( )。 与此类似,如果我们有一个User类,其中有name属性,user是该类的对象。现在将该对象保存到域中后,如果要获取该对象的name可以这么写: ${user.name} 该方式就等效于user.getName()。也就是说在EL表达式中.运算符相当于调了getter方法。同理如果User中有一个Address属性,Address中又有一个city,我们也可以通过该方式获取city的值 ${user.address.city} 还有一个功能与.运算符非常类似的运算符[],但它比.运算符要强大许多,在此不再赘述。 EL表达式的简单运算 我们还可以利用EL表达式做一些简单的运算。 利用empty判断null 它会将空字符串和没有元素的集合都判断为null即返回true,示例如下: ${empty object} EL的三元运算符 请看如下示例: ${empty user ? “未登录”:”已经登录”} EL表达式的隐式对象 在之前的文章中介绍了JSP的内置对象,在此列举几个EL表达式的常用对象 pageContext 对应于JSP页面中的pageContext对象 pageScope 代表page域中用于保存属性的Map对象 requestScope 代表request域中用于保存属性的Map对象 sessionScope 代表session域中用于保存属性的Map对象 applicationScope 代表application域中用于保存属性的Map对象 param 表示一个保存所有请求参数的Map对象 paramValues 表示一个保存了所有请求参数的Map对象,它对于某个请求参数返回一个string类型数组 header 表示一个保存了所有http请求头字段的Map对象 headerValues 表示一个保存了所有http请求头字段的Map对象,返回string类型数组 cookie 表示一个保存了所有cookie的Map对象 initParam 表示一个保存了所有web应用初始化参数的map对象 JSTL JSTL简介 从JSP 1.1规范开始JSP就支持使用自定义标签,使用自定义标签极大地降低了JSP页面的复杂度,同时增强了代码的重用性,所以自定义标签在WEB应用中被广泛使用。故,许多WEB应用厂商都开发出了自己的一套标签库,这导致出现了许多功能相同的标签,令开发人员手忙脚乱,无所适从。为了解决该问题,Apache开发了一套用于解决这些常用问题的自定义标签库,这套标签库被SUN公司定义为标准标签库(The JavaServer Pages Standard Tag Library),简称JSTL。在开发中可使用JSTL实现JSP页面中逻辑处理,如判断、循环等等操作。 添加JSTL <%@ taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %> 利用taglib指令设置JSTL的路径和前缀名 导入包jstl.jar和standard.jar JSTL常用标签 <c:set>标签 用于设置各种域中的属性 <c:out>标签 用于输出一段文本内容到客户端浏览器 <c:remove>标签 用于删除各种域中的属性 <c:if>标签 用于条件判断 <c:choose>标签 该标签非常类似于Java中的switch语句,用于多个条件选择。它必须与<c:when>和<c:otherwise>一起使用 <c:forEach>标签 用于对集合对象进行循环迭代操作 请看如下示例: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSTL</title> <style type="text/css"> </style> </head> <body> <!-- 测试set、remove、out --> <c:set var="number" value="9527" scope="session"/> number=<c:out value="${number}"/> <c:remove var="number" scope="session"/> number=<c:out value="${number}" default="没有取到number的值"/> </br> <!-- 测试if --> <c:if test="${9527>1234}"> zxx number is 9527 </c:if> </br> <!-- 测试choose --> <c:set var="size" value="${3}"></c:set> <c:choose> <c:when test="${size==1 }">The size is 1</c:when> <c:when test="${size==2 }">The size is 2</c:when> <c:when test="${size==3 }">The size is 3</c:when> <c:otherwise> The size is other </c:otherwise> </c:choose> </br> <!-- 测试forEach --> <c:forEach var="i" begin="1" end="20" step="3"> ${i}<br/> </c:forEach> </br> <% List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); request.setAttribute("list", list); %> <c:forEach items="${list}" var="listitem"> ${listitem}<br/> </c:forEach> <br/> <!-- 测试forEach --> <% List arrayList = new ArrayList(); arrayList.add("aaa"); arrayList.add("bbb"); arrayList.add("ccc"); arrayList.add("ddd"); arrayList.add("eee"); request.setAttribute("arrayList", arrayList); %> <table border="1"> <tr> <th>数据</th> <th>索引</th> <th>计数</th> <th>是否是第一个</th> <th>是否是最后一个</th> </tr> <c:forEach items="${arrayList}" var="item" varStatus="vs"> <tr> <td>${item}</td> <td>${vs.index}</td> <td>${vs.count}</td> <td>${vs.first}</td> <td>${vs.last}</td> </tr> </c:forEach> </table> </body> </html> 运行后效果如下图所示:

优秀的个人博客,低调大师

后台(12)——Servlet(4)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 在前几篇博客中我们学习了Tomcat,Http,Servlet,HttpServletResponse在此基础上我们来深入学习Servlet的请求即HttpServletRequest HttpServletRequest的简单使用 HttpServletRequest代表客户端的请求,当客户端通过HTTP协议访问服务器时与请求相关的所有信息都将被封装在这个对象中,所以我们可通过该对象获得客户端的相关信息。 常用的方法如下: getRequestURL():返回客户端发出请求时的完整URL getRequestURI():返回请求行中的资源名部分 getContextPath():返回请求的上下文路径 getQueryString():返回请求行中的参数部分 getParameter():返回参数中的具体值 getRemoteAddr():返回发出请求的客户端的IP地址 getRemoteHost():返回发出请求的客户端的完整主机名 getRemotePort():返回客户端所使用的网络端口号 getMethod():返回客户端使用的请求方式 getHeaderNames():返回此请求包含的所有头的名称 getHeader():返回指定的请求头的值 请看如下示例: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { getRequestInfo(request); getRequestHeader(request); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } //获取与请求相关的信息 private void getRequestInfo(HttpServletRequest request){ String method=request.getMethod(); StringBuffer requestURL = request.getRequestURL(); String requestURI = request.getRequestURI(); String contextPath = request.getContextPath(); String queryString = request.getQueryString(); String name=request.getParameter("name"); String remoteAddr = request.getRemoteAddr(); String remoteHost = request.getRemoteHost(); int remotePort = request.getRemotePort(); System.out.println("----> method="+method); System.out.println("----> requestURL="+requestURL); System.out.println("----> requestURI="+requestURI); System.out.println("----> contextPath="+contextPath); System.out.println("----> queryString="+queryString); System.out.println("----> remoteAddr="+remoteAddr); System.out.println("----> remoteHost="+remoteHost); System.out.println("----> remotePort="+remotePort); } //获取请求的Header中的信息 private void getRequestHeader(HttpServletRequest request){ Enumeration<String> headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()){ String headKey=headerNames.nextElement(); String headValue=request.getHeader(headKey); System.out.println(headKey+":"+headValue); } } } 代码写好了,我们现在通过浏览器发出请求: http://localhost:8081/TestServlet03/helloServlet?name=lucy 在Console中观察输入结果: —-> method=GET —-> requestURL=http://localhost:8081/TestServlet03/helloServlet —-> requestURI=/TestServlet03/helloServlet —-> contextPath=/TestServlet03 —-> queryString=name=lucy —-> name=lucy —-> remoteAddr=127.0.0.1 —-> remoteHost=127.0.0.1 —-> remotePort=63484 host:localhost:8081 connection:keep-alive cache-control:max-age=0 accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 upgrade-insecure-requests:1 user-agent:Mozilla/5.0 (Windows NT 10.0;Win64; x64)Chrome/47.0.2526.111 accept-encoding:gzip, deflate, sdch accept-language:zh-CN,zh;q=0.8 嗯哼,结合这些输出结果再回过头看这些方法就能有更好的体会。在此,再次强调一下:请注意getRequestURL()和getRequestURI()以及getContextPath()、getQueryString()这四个方法的区别 getRequestURL()返回的是请求的路径,但是不含请求的参数部分 getRequestURI()返回请求行中的资源名部分,但是不含有请求的主机和端口以及请求的参数部分 getContextPath()返回请求的上下文,即/+项目名称,比如此处的/TestServlet03 在前几篇博客中我们学习了Tomcat,Http,Servlet,HttpServletResponse在此基础上我们来深入学习Servlet的请求即HttpServletRequest HttpServletRequest处理表单请求 在刚才的示例中,我们利用getParameter()获取GET请求中请求参数中的具体值,那么在POST请求时又该怎么获取传递给服务端的值呢?请看如下示例 先准备一个表单: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Welcome</title> </head> <body> <form action="/TestServlet03/form" method="post"> 用 户:<input type="text" name="username"/> <br/><br/> 密 码:<input type="password" name="password"/> <br/><br/> 性 别:<input type="radio" name="gender" value="男" />男 <input type="radio" name="gender" value="女" checked="checked"/>女 <br/><br/> 爱 好:<input type="checkbox" name="hobby" value="摄影"/>摄影 <input type="checkbox" name="hobby" value="唱歌"/>唱歌 <input type="checkbox" name="hobby" value="拍照"/>拍照 <br/><br/> 城 市: <select name="city"> <option>------请选择------</option> <option value="dj">东京</option> <option value="db">大阪</option> <option value="xt">仙台</option> </select> <br/><br/> <input type="submit" value="欢迎注册VIP会员"/> </form> </body> </html> 再实现服务端的代码: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestForm extends HttpServlet{ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { testForm1(request); } private void testForm1(HttpServletRequest request)throws ServletException,IOException { request.setCharacterEncoding("UTF-8"); Enumeration<String> parameterNames = request.getParameterNames(); while(parameterNames.hasMoreElements()){ String name = parameterNames.nextElement(); String[] values = request.getParameterValues(name); for(int i=0;values!=null&&i<values.length;i++){ System.out.println("name="+name+" "+"value="+values[i]); } } } } 代码解析如下: 利用setCharacterEncoding()设置编码方式 利用getParameterNames()获取所有请求参数的名称,请参见代码第28行 对于此处的表单POST提交而言传递的参数的名称分别为username,password,gender,hobby,city 获取每个参数对于的值,请参见代码第29-35行 嗯哼,现在我们通过浏览器来发起一个请求: 在Console观察打印信息: name=username value=杉原杏璃 name=password value=123456789 name=gender value=女 name=hobby value=摄影 name=hobby value=拍照 name=city value=dj 在实际开发中,我们可能需要将这些传递给服务端的信息封装成实体,请看如下示例: 先准备一个实体Entity: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.Serializable; import java.util.Arrays; public class User implements Serializable{ private String username; private String password; private String gender; private String[] hobby; private String city; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String[] getHobby() { return hobby; } public void setHobby(String[] hobby) { this.hobby = hobby; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "User [username=" + username + ", password=" + password + ", gender=" + gender + ", hobby=" + Arrays.toString(hobby) + ", city=" + city + "]"; } } 请注意,该实体中字段的名字必须与表单中各个name的值相对应 再来看服务端的代码: private void testForm2(HttpServletRequest request)throws ServletException,IOException { try { request.setCharacterEncoding("UTF-8"); User user = new User(); Map<String,String[]> parameterMap = request.getParameterMap(); for (Map.Entry<String, String[]> map : parameterMap.entrySet()) { String name = map.getKey(); String[] values = map.getValue(); PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, User.class); Method method = propertyDescriptor.getWriteMethod(); if(values.length==1&&!name.equals("hobby")){ method.invoke(user, values[0]); }else{ method.invoke(user, (Object)values); } } System.out.println("------> "+user); } catch (Exception e) { e.printStackTrace(); } } 代码解析如下: 利用getParameterMap()得到请求中所有的参数及其对应的值,请参见代码第5行 注意:有的参数只有一个值,比如该示例中的username;有的参数会有多个值,比如该示例中的hobby 获取每个参数及其对应的值,请参见代码第7-8行 反射出每个参数在实体中的setter()方法,请参见代码第9-10行 设置每个参数对应的值,请参见代码第11-15行 请求重定向与请求转发的区别 我们知道: 利用response.sendRedirect()实现请求的重定向 利用request.getRequestDispatcher().forward()实现请求的转发 请注意它们的区别: 重定向时浏览器中的地址栏会发生变化,但是请求转发时浏览器中地址栏不会发生改变。从本质上来讲:重定向是两次不同的请求,而请求转发只向服务端的发送了一次请求由服务端的内部实现请求的跳转。 重定向可以跳转到应用的外部,而重定向的范围只能是应用的内部 请求转发可利用request.setAttribute()将数据传递到下一个Servlet且下一个Servlet可用request.getAttribute()取出数据;但是重定向不可以也没有道理这么做。至于为什么,请参考第一点。

优秀的个人博客,低调大师

后台(11)——Servlet(3)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 在前几篇博客中我们已经对Tomcat,Http,Servlet等方面有了简单的接触,在此基础上我们来深入学习Servlet的响应即HttpServletResponse. Request、Response简介 Web服务器接收到客户端的http请求后会针对每一次请求创建用于代表请求的request对象以及代表响应的response对象。故,若要获取客户机提交的数据,只需要处理request对象就行;若要向客户端输出数据,只需要处理response对象即可。 HttpServletResponse的简单使用 在此以HttpSerlet为例,介绍HttpServletResponse的使用方式,请看如下示例: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ public class TestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("GBK"); response.setContentType("text/html;chartset=GBK"); PrintWriter writer = response.getWriter(); writer.write("佐佐木希写真全集"); response.addHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Expires", "0"); response.setHeader("refresh", "10;url=http://blog.csdn.net/lfdfhl"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } } 在这段代码中对Get请求做出响应,代码解析如下: 设置将发送到客户端的响应内容的字符编码,请参见代码第9行 在此将字符编码设置为GBK 设置将发送到客户端的响应内容的类型,请参见代码第10行 在此将内容的类型设置为text/html;chartset=GBK 设置客户端不缓存,请参见代码第13-15行 设置客户端在几秒钟后自动跳转,请参见代码第16行 亦可利用response.setContentType()设定发送到客户端的响应内容的类型,即: response.setContentType(“text/html;chartset=GBK”); 与此类似,也可设置重定向 response.setStatus(302); response.setHeader(“location”,”http://blog.csdn.net/lfdfhl“); 或者利用response.sendRedirect( )设置重定向 response.sendRedirect(“http://blog.csdn.net/lfdfhl“); 同理,我们可用ServletOutputStream向客户端返回字节流 response.setCharacterEncoding("GBK"); response.setContentType("text/html;chartset=GBK"); ServletOutputStream outputStream = response.getOutputStream(); outputStream.write("大泽玛利亚摄影写真".getBytes("GBK")); HttpServletResponse返回下载文件 刚才的示例中,我们只是返回了简单的文字,现在我们来返回一张照片给客户端,请看如下示例: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.FileInputStream; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestResponsePhoto extends HttpServlet{ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path=getServletContext().getRealPath("/WEB-INF/ZXM.jpg"); FileInputStream fileInputStream = new FileInputStream(path); ServletOutputStream outputStream = response.getOutputStream(); int len=0; byte [] b=new byte[1024]; while((len=fileInputStream.read(b))!=-1){ outputStream.write(b, 0, len); } outputStream.close(); fileInputStream.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } } 代码解析如下: 得到文件路径,请参见代码第20行 得到文件输入流,请参见代码第21行 从response中获取到ServletOutputStream作为输出流,请参见代码第22行 将图片返回给客户端,请参见代码第23-29行 运行后,效果如下图所示: 嗯哼,看到了吧:浏览器中显示了从服务端获取的我女朋友的照片 但是,如果想让用户下载这张照片该怎么办呢?请看如下示例: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DownPhoto extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path=getServletContext().getRealPath("/WEB-INF/zxm.jpg"); System.out.println("-----------------> path="+path); String fileName=path.substring(path.lastIndexOf("\\")+1); fileName=URLEncoder.encode(fileName, "UTF-8"); response.setHeader("content-disposition", "attachment;filename="+fileName); response.setHeader("content-type", "image/jpeg"); FileInputStream fileInputStream = new FileInputStream(path); ServletOutputStream outputStream = response.getOutputStream(); int len=0; byte [] b=new byte[1024]; while((len=fileInputStream.read(b))!=-1){ outputStream.write(b, 0, len); } outputStream.close(); fileInputStream.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } } 代码解析如下: 获取到文件名称,请参见代码第23行 设置Header指示客户端下载文件,请参见代码第24行 利用Header设置响应的内容的类型 嗯哼,待用户输入地址后即可下载对应的文件。 除此以外,我们可利用画笔在内存中创作一张图片BufferedImage然后再返回给客户端;有的网站登录时的验证码正是采用该方式实现的。 HttpServletResponse的几个细节问题 getOutputStream()和getWriter()分别用于得到输出字节流和输出字符流的ServletOuputStream、Printwriter。但是请注意:getOutputStream()和getWriter()这两个方法互相排斥,调用了其中任意一个方法后就不能再调用另一方法;否则系统抛出异常。 在Servlet中向ServletOutputStream对象或PrintWriter对象写入的数据将被Servlet引擎(如Tomcat)从response里面获取,然后Servlet引擎再将这些数据当作响应消息的正文且与响应状态行和响应头组合并输出到客户端。这也就是说:并不是response将响应消息传递给了客户端,而是Servlet引擎将响应消息封装到了response中再由Servlet引擎传递给客户端 Serlvet的service()结束后,Servlet引擎将检查getWriter()或getOutputStream()返回的输出流对象是否已经调用过close();如果未关闭则Servlet引擎将调用close()关闭该流对象,如果已经关闭则不作处理

优秀的个人博客,低调大师

后台(10)——Servlet(2)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 在上一篇博客中,我们已经对Servlet有了基础的简单的了解,在深入认识Servlet之前,我们来一起学习HTTP协议。 HTTP简介 HTTP协议(HyperText Transfer Protocol)又叫作超文本传输协议,它是用于从服务器传输超文本到浏览器的传送协议。HTTP不仅保证计算机正确、高效、快速地传输超文本文档还可确定传输文档中的哪一部分内容优先显示。 HTTP是一个应用层协议,一次HTTP通信由请求和响应构成。客户端向服务器发送一个请求,在该请求中包含:请求的方法、URL、用户信息、协议版本、等等信息。服务器在接收到请求后发对此作出响应并返回一个答复消息,该消息包括:响应的时间、请求成功或失败的标识、协议的版本、回复的内容等等信息。 HTTP的特点 标准的HTTP协议是无连接的,无状态的。无连接指的是:每次连接只处理一个请求。服务器处理完客户的请求并收到客户的应答后即断开连接。无状态指的是:协议对于请求的处理没有记忆能力,也就是说每次请求都是独立的,它的执行结果与之前和之后的请求是无直接关系的 标准HTTP协议既有优点也有缺点:优点在于极大地减轻了服务器的压力,每一次请求不会造成不必要连接占用;缺点在于繁复地建立连接和断开连接,请求会传输大量重复的信息,所以随后出现了Keep-Alive、Cookie、Session在某些程度上弥补了标准HTTP的缺点。 HTTP的请求与响应 我们知道:每一次HTTP的请求都由请求(request)和响应(response)构成,在此对这两部分作进一步的说明。 HTTP的请求 HTTP请求由三部分组成:请求消息行、请求消息头、请求消息体 请求消息行 示例如下: GET /HelloWeb/test.html HTTP/1.1 请求消息行包含三部分内容: 请求方式,比如此处的GET 资源URI,比如此处的/HelloWeb/test.html 协议及其版本号,比如此处的HTTP/1.1 请求消息头 示例如下: Host:localhost Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Accept-Charset: UTF-8 Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.6 Cache-Control: max-age=0 Cookie:JSESSIONID=97C4302F3350676F65B5E4409ABA87CF Referer: http://blog.csdn.net/lfdfhl Content-Type:application/x-www-form-urlencoded If-Modified-Since: Wed, 02 Feb 2011 12:04:56 GMT User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36 Connection: keep-alive Date: Tue, 15 Nov 2017 01:12:31 GMT 请求消息头中内容较多,现将常用和重要的字段介绍如下: Host:发起请求的主机名及其端口号 Accept:客户端可接收的文档类型。其中,*/*表示可接收任何类型 Accept-Charset: 客户端可接受的字符编码集 Accept-Encoding: 客户端支持的压缩格式 Accept-Language:客户端可接受的语言 Cache-Control:设置请求和响应遵循的缓存机制 Cookie:HTTP请求发送时会把保存在该请求域名下的所有cookie值一起发送至服务器。 Referrer:发起HTTP请求的页面的URL Content-Type:请求时所传递的内容的类型 Content-Length:请求时所传递的内容的长度 If-Modified-Since:该值与响应消息头的Last-Modified字段相对应。Last-Modified与If-Modified-Since都是用来记录页面的最后修改时间。当客户端访问页面时,服务器会将页面最后修改时间通过Last-Modified由服务器发往客户端,客户端会记录下该值;当客户端再次发起请求时,客户端会通过 If-Modified-Since将此前服务器端发过来的最后修改时间戳发送回去;服务器通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的则返回新的内容,如果是最新的则返回304告诉客户端其本地cache的页面是最新的,于是客户端就可直接从本地加载页面。 User-Agent:表示发出该请求的客户端的相关信息,比如操作系统及版本、CPU类型、浏览器及版本、浏览器渲染引擎、浏览器语言等等 Connection: 表示是否需要持久连接,HTTP 1.1默认进行持久连接。 Date: 请求发送的日期和时间 Range:用于告知服务器只需返回部分内容,故用该Range描述这部分内容的范围;该字段对于断点续传等功能非常实用 其实,从这里可以看出来:在每次请求时,客户端需要告诉服务器:自身支持的字符集,压缩格式,语言;请求的消息内容,长度等等众多信息,从而尽量清楚地表达自身的条件和需求以便服务器做出相应的响应。 请求消息体 username=大泽玛利亚&hobby=摄影 当请求方式是POST方式时可见消息正文,假若是GET方式则请求消息体中无内容 HTTP的响应 HTTP响应由三部分组成:响应消息行、响应消息头、响应消息体 响应消息行 HTTP/1.1 200 OK 响应消息行由三部分组成: 协议及其版本号,比如此处的 HTTP/1.1 响应状态码,比如此处的200 常用的状态码有:200(正常)、02/307(临时重定向)、304(未修改)表示客户端缓存的版本是最新的,客户端无需到服务器请求、404(找不到)、500(服务器内部错误) 响应码的描述,比如此处的OK 响应消息头 Accept-Ranges: bytes Content-Encoding: gzip Content-Length: 4533 Content-Language: en,zh Content-Type: text/html Date: Sun, 06 Sep 2015 07:56:07 GMT Last-Modified: Fri, 04 Sep 2015 13:37:55 GMT Server: apache tomcat Location: http://blog.csdn.net/lfdfhl Refresh: 5; url=http://www.csdn.net/ Content-Disposition: attachment; filename=test.zip Set-Cookie: UserID=tom; Max-Age=3600; Version=1 Expires: Thu, 01 Dec 2015 12:20:00 GMT Cache-Control: no-cache Pragma: no-cache Connection: keep-alive 响应消息头中内容较多,现将常用和重要的字段介绍如下: Accept-Ranges: 表明服务器是否支持指定范围请求及哪种类型的分段请求。假若服务器想告诉浏览器不要使用Range,则返回Accept-Range: none;假若服务器想告诉浏览器可使用以byte为单位的Range的请求,则返回Accept-Range:bytes Content-Encoding: 服务器的返回内容的压缩编码类型 Content-Length: 服务器的返回内容的的长度 Content-Language: 服务器的返回内容的语言 Content-Type: 服务器的返回内容的类型 Date:服务器发出响应的时间 Last-Modified: 返回的内容的最后修改时间 Server: 服务器的类型 Location:指示被请求的资源的位置,常和请求消息头一起使用完成请求重定向 Refresh:延时跳转到某个页面或者定时刷新本页面 Content-Disposition: 指示客户端下载文件 Set-Cookie: 服务器端发送给客户端的Cookie Expires: 响应过期的时间 Cache-Control: 指定响应遵循的缓存机制 Pragma: 用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache-Control:no-cache相同 Connection: 表示是否需要持久连接,HTTP 1.1默认进行持久连接。 响应消息体 响应消息体中表示响应的的具体内容。比如,响应的内容是网页,那么响应消息体的内容和网页右键”查看网页源代码”所看到的内容一样。 后会有期 在此简单地介绍了HTTP协议,但也不会如此仓促地完结。我们将在后续的博客中结合Servlet对与HTTP紧密相关的Cookie和Session进行详细的学习,再会。

优秀的个人博客,低调大师

后台(05)——MySQL(5)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 本文简介 在之前的博客中我们学习了MySQL的DDL、DML、DCL、DQL;还有数据的完整性、多表查询。在这篇博客中我们将一起学习MySQL中的函数、MySQL数据库的备份与恢复。 MySQL中的函数 MySQL提供了不少自带的函数,在此简要介绍,时间函数,字符串函数,数学函数。 时间函数 SELECT NOW(); SELECT DAY (NOW()); SELECT DATE (NOW()); SELECT TIME (NOW()); SELECT YEAR (NOW()); SELECT MONTH (NOW()); SELECT CURRENT_DATE(); SELECT CURRENT_TIME(); SELECT CURRENT_TIMESTAMP(); SELECT ADDTIME('14:23:12','01:02:01'); SELECT DATE_ADD(NOW(),INTERVAL 1 DAY); SELECT DATE_ADD(NOW(),INTERVAL 1 MONTH); SELECT DATE_SUB(NOW(),INTERVAL 1 DAY); SELECT DATE_SUB(NOW(),INTERVAL 1 MONTH); SELECT DATEDIFF('2013-12-30','2013-12-20'); 这些时间函数与Java中Date类提供的函数非常类似,故在此不再赘述,欲知其意观其名即可。 字符串函数 SELECT CONCAT ('星爷','9527'); SELECT INSTR ('星爷9527','9527'); SELECT LENGTH('本文作者:http://blog.csdn.net/lfdfhl'); 这些字符串函数与Java中String类提供的函数非常类似,故在此不再赘述,欲知其意观其名即可。 数学函数 SELECT BIN(2); SELECT ABS(-136); SELECT FLOOR(3.14); SELECT CEILING(3.14); 这些数学函数与Java中Math类提供的函数非常类似,故在此不再赘述,欲知其意观其名即可。 数据库的备份与恢复 在此简要介绍MySQL数据库的备份与恢复 MySQL数据库的备份 在DOS中使用mysqldump命令可以生成指定数据库的脚本文本,语法如下: mysqldump –u用户名 –p密码 数据库名>生成的脚本文件路径 但是请注意:脚本文本中只包含数据库的内容,而不存在创建数据库的语句!所以在恢复数据时需要自已手动创建一个数据库,然后再去恢复数据。 在此,备份这几天使用的数据库db1到D盘: C:\Users\lf>mysqldump -uroot -proot db1>d:\db1.sql 即下图所示: MySQL数据库的恢复 在DOS中使用source命令可执行数据库的恢复,语法如下: source 数据库脚本文件路径 再次提醒: 在恢复之前必须先创建数据库或者使用已有的数据库 在此,将刚才导出的数据库脚本恢复到新的数据库db2: mysql> create database db2; mysql> use db2; mysql> source d:\db1.sql 也可参见下图: 至此,关于MySQL的基础知识就全部结束完了,谢谢。

优秀的个人博客,低调大师

后台(03)——MySQL(3)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl DQL 在上一篇博客中我们学习了DDL、DML、DCL在本篇博客中我们将着重讨论MySQL中非常重要的DQL。 数据库执行DQL语句并不会对数据进行改变,而是从数据库返回结果集给客户端;该结果集是一张存在于内存的虚拟表。 DQL语法: SELECT 列名 FROM 表名【WHERE—GROUP BY—HAVING—ORDER BY】 在正式进入这部分之前,我们先准备一下稍后会用到的数据。 CREATE TABLE student ( sid CHAR(6), sname VARCHAR(50), age INT, gender VARCHAR(50) ); 创建学生表student INSERT INTO student VALUES(‘S_1001’, ‘liuYi’, 14, ‘male’); INSERT INTO student VALUES(‘S_1002’, ‘chenEr’, 15, ‘female’); INSERT INTO student VALUES(‘S_1003’, ‘zhangSan’, 13, ‘male’); INSERT INTO student VALUES(‘S_1004’, ‘liSi’, 16, ‘female’); INSERT INTO student VALUES(‘S_1005’, ‘wangWu’, 17, ‘male’); INSERT INTO student VALUES(‘S_1006’, ‘zhaoLiu’, 18, ‘female’); INSERT INTO student VALUES(‘S_1007’, ‘sunQi’, 13, ‘male’); INSERT INTO student VALUES(‘S_1008’, ‘zhouBa’, 15, ‘female’); INSERT INTO student VALUES(‘S_1009’, ‘wuJiu’, 11, ‘male’); INSERT INTO student VALUES(‘S_1010’, ‘zhengShi’, 15, ‘female’); INSERT INTO student VALUES(‘S_1011’, ‘xxx’, NULL, NULL); 向学生表student中插入数据。 CREATE TABLE emp( empno int, ename varchar(50), job varchar(50), mgr int, hiredate date, sal decimal(7,2), comm decimal(7,2), deptno int ); 建立员工表emp INSERT INTO emp values(7369,’SMITH’,’CLERK’,7902,’1980-12-17’,800,NULL,20); INSERT INTO emp values(7499,’ALLEN’,’SALESMAN’,7698,’1981-02-20’,1600,300,30); INSERT INTO emp values(7521,’WARD’,’SALESMAN’,7698,’1981-02-22’,1250,500,30); INSERT INTO emp values(7566,’JONES’,’MANAGER’,7839,’1981-04-02’,2975,NULL,20); INSERT INTO emp values(7654,’MARTIN’,’SALESMAN’,7698,’1981-09-28’,1250,1400,30); INSERT INTO emp values(7698,’BLAKE’,’MANAGER’,7839,’1981-05-01’,2850,NULL,30); INSERT INTO emp values(7782,’CLARK’,’MANAGER’,7839,’1981-06-09’,2450,NULL,10); INSERT INTO emp values(7788,’SCOTT’,’ANALYST’,7566,’1987-04-19’,3000,NULL,20); INSERT INTO emp values(7839,’KING’,’PRESIDENT’,NULL,’1981-11-17’,5000,NULL,10); INSERT INTO emp values(7844,’TURNER’,’SALESMAN’,7698,’1981-09-08’,1500,0,30); INSERT INTO emp values(7876,’ADAMS’,’CLERK’,7788,’1987-05-23’,1100,NULL,20); INSERT INTO emp values(7900,’JAMES’,’CLERK’,7698,’1981-12-03’,950,NULL,30); INSERT INTO emp values(7902,’FORD’,’ANALYST’,7566,’1981-12-03’,3000,NULL,20); INSERT INTO emp values(7934,’MILLER’,’CLERK’,7782,’1982-01-23’,1300,NULL,10); 向员工表emp中插入数据 CREATE TABLE dept( deptno INT, dname varchar(14), loc varchar(13) ); 建立部门表dept INSERT INTO dept values(10, ‘ACCOUNTING’, ‘NEW YORK’); INSERT INTO dept values(20, ‘RESEARCH’, ‘DALLAS’); INSERT INTO dept values(30, ‘SALES’, ‘CHICAGO’); INSERT INTO dept values(40, ‘OPERATIONS’, ‘BOSTON’); 向部门表dept中插入数据 基本查询 查询所有列 SELECT * FROM student; 查询指定列 SELECT sid, sname, age FROM student; 条件查询 在进行条件查询时需在WHERE子句使用以下运算符和关键字: =、!=、<、<=、>、>= BETWEEN…AND IN(value1,value2,….valueN) NOT IN(value1,value2,….valueN) IS NULL IS NOT NULL AND OR NOT 请看如下示例: 查询性别为女,并且年龄小于20的记录 SELECT * FROM student WHERE gender = ‘female’ AND age<20; 查询学号为S_1001或者姓名为liSi的记录 SELECT * FROM student WHERE sid=’S_1001’ OR sname=’liSi’; 查询学号为S_1001,S_1002,S_1003的记录 SELECT * FROM student WHERE sid IN (‘S_1001’,’S_1002’,’S_1003’); 查询学号不为S_1001,S_1002,S_1003的记录 SELECT * FROM student WHERE sid NOT IN (‘S_1001’,’S_1002’,’S_1003’); 查询年龄为null的记录 SELECT * FROM student WHERE age IS NULL; 查询姓名不为null的记录 SELECT * FROM student WHERE sname IS NOT NULL; 查询年龄在14到16之间的记录 SELECT * FROM student WHERE age>=14 AND age<=16; SELECT * FROM student WHERE age BETWEEN 14 AND 16; 查询性别非男的记录 SELECT * FROM student WHERE gender !=’male’; SELECT * FROM student WHERE NOT gender =’male’; 模糊查询 模糊查询常使用关键字LIKE 通配符_表示任意一个字符 通配符%表示任意0—N个字符 请看如下示例: 查询姓名由5个字母构成的记录 SELECT * FROM student WHERE sname LIKE “_____”; 查询姓名由5个字母构成且第5个字母为i的记录 SELECT * FROM student WHERE sname LIKE “____i”; 查询姓名以“z”开头的记录 SELECT * FROM student WHERE sname LIKE “z%”; 查询姓名中第2个字母为i的记录 SELECT * FROM student WHERE sname LIKE “_i%”; 查询姓名中包含a字母的记录 SELECT * FROM student WHERE sname LIKE “%a%”; 字段控制查询 请看如下示例: 利用DISTINCT去除重复记录 SELECT DISTINCT job FROM emp; 利用函数IFNULL把NULL转换成数值0 SELECT IFNULL(comm,0) FROM emp; 查看雇员的月薪与佣金之和 SELECT sal+IFNULL(comm,0) FROM emp; 利用关键字AS给列名添加别名 SELECT sal+IFNULL(comm,0) AS total FROM emp; SELECT sal AS salary ,ename AS NAME FROM emp; 在使用AS给列名添加别名,可空格代替AS;但不推荐这么做。 排序 常用的两种排序方式 ORDER BY 列名 ASC ORDER BY 列名 DESC 请看如下示例: 查询所有学生记录,按年龄降序排序 SELECT * FROM student ORDER BY age DESC; 查询所有雇员,按月薪降序排序,若月薪相同时按员工编号降序排序 SELECT * FROM emp ORDER BY sal DESC,empno DESC; 聚合函数 聚合函数用于纵向(即列)运算;它具有自动滤空的功能,若某一个值为NULL,那么会自动将其过滤使其不参与运算。 常用的聚合函数如下: COUNT( ):统计指定列其值不为NULL的记录行数 MAX( ):计算指定列的最大值,如果指定列是字符串类型则使用字符串排序运算 MIN( ):计算指定列的最小值,如果指定列是字符串类型则使用字符串排序运算 SUM( ):计算指定列的数值和,如果指定列类型不是数值类型则计算结果为0 AVG( ):计算指定列的平均值,如果指定列类型不是数值类型则计算结果为0 请看如下示例: 查询emp表中记录数 SELECT COUNT(*) FROM emp; 查询emp表中有佣金的人数 SELECT COUNT(comm) AS total FROM emp; 查询emp表中月薪大于2000的人数 SELECT COUNT(*) FROM emp WHERE sal>2000; 查询月薪与佣金之和大于2000的人数 SELECT COUNT(*) FROM emp WHERE (sal+IFNULL(comm,0))>2000; 查询有佣金的人数,有领导的人数 SELECT COUNT(comm), COUNT(mgr) FROM emp; 查询所有雇员月薪的总和 SELECT SUM(sal) FROM emp; 查询所有雇员月薪和,以及所有雇员佣金之和 SELECT SUM(sal) , SUM(comm) FROM emp; 统计所有员工平均工资 SELECT AVG(sal) FROM emp; 查询所有员工中的最高工资 SELECT MAX(sal) FROM emp; 查询所有员工中的最低工资 SELECT MIN(sal) FROM emp; 分组查询 当分组查询时需使用GROUP BY子;例如,查询每个部门的工资总和,此时需用部门来进行分组 请看如下示例: 查询每个部门的部门编号和每个部门的工资和 SELECT deptno,SUM(sal) FROM emp GROUP BY deptno; 查询每个部门的部门编号以及每个部门的人数 SELECT deptno,COUNT(*) FROM emp GROUP BY deptno; 查询每个部门的部门编号以及每个部门工资大于2000的人数 SELECT deptno,COUNT(*) FROM emp WHERE sal>2000 GROUP BY deptno; 请务必注意: 在MySQL中使用SQL时,如果某列名和聚合函数同时出现在了SELECT与FROM之间,那么该列名一定要写在group by 之后。 还是来看刚才的例子: 查询每个部门的部门编号和每个部门的工资和,SQL语句如下: SELECT deptno,SUM(sal) FROM emp GROUP BY deptno; 如果按照下面的写法: SELECT ename,COUNT(*) FROM emp GROUP BY deptno; 在MySQL中执行时不会报错,但是查询出来的结果明显不对,稀奇古怪的样子;而且该写法在其他数据库中执行时会报错! 关于这个注意事项需要多加体会。 HAVING子句 HAVING子句用于在GROUP BY分组之后对数据再次筛选。 请看如下示例: 查询工资总和大于10000的部门编号以及工资和 SELECT deptno, SUM(sal) FROM emp GROUP BY deptno HAVING SUM(sal) >10000; LIMIT LIMIT用来限定查询结果的起始行和总行数,常用于分页。 请看如下示例: 从student表中查询5行记录,起始行从2开始 SELECT * FROM student LIMIT 2, 5; 查询代码的书写顺序和执行顺序 查询语句的书写顺序: select – from – where – group by – having – order by – limit 查询语句的执行顺序: from – where – group by – having - select - order by – limit

优秀的个人博客,低调大师

Simple Admin 分布式后台管理系统 v0.2.1 发布,新增三端UUID代码生成

更新内容: simple admin core 升级至 v0.2.1 新增: Ent UUIDMixin 修复: 用户和token采用UUID 优化: ErrorCtx 和 OkJsonCtx simple admin backend ui 升级至 v0.2.1 修复:token 和 user 的 UUID 支持 优化:优化代码运行速度 simple admin tools 升级至 v0.1.5 新增: 基于 UUID 的三端代码生成 修复: Ent生成数据类型错误 优化: interface{} 改为 any 近期规划: 优化 multiple rpc group 优化 proto 文件拆分 UUIDMixin文档: https://doc.ryansu.pro/zh/guide/feature/ORM/ent.html#mixin-%E4%BB%8B%E7%BB%8D

优秀的个人博客,低调大师

web-flash 1.2 发布,基于 Spring Boot&Vue.js 的前后端分离后台管理系统

web-flash 发布将近半年,系统已经趋于稳定,本次没有重大功能更新,主要进行性能的优化和部分组件的例行升级以及bug修复 本次更新内容如下: Change 删除角色时判断是有用户使用该角色,如果有则不允许删除 Change 简化手机站点api地址配置 Change baseService增加缓存功能 Update 升级element-ui至2.11.0 Update 升级Vue全家桶:vue.js(2.6.10),vuex(3.1.1),vue-router(3.0.3),axios(0.18.1),"vue-loader(15.7.0),vue-template-compiler(2.6.10) Change 完善在线文档 Fix bug 本次发布版地址:https://gitee.com/enilu/web-flash/releases/1.2

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册