首页 文章 精选 留言 我的

精选列表

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

后台(32)——内省Introspector

探索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 内省(Introspector)简介 内省Introspector是一种特殊的反射技术,常用于操作JavaBean。 字段和属性以及JavaBean 先来看我们经常写的一种类: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; public class Girl { private String name; private int age; private int bust; private int waist; private int hip; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getBust() { return bust; } public void setBust(int bust) { this.bust = bust; } public int getWaist() { return waist; } public void setWaist(int waist) { this.waist = waist; } public int getHip() { return hip; } public void setHip(int hip) { this.hip = hip; } } 在该类中,我们定义了几个字段并且为它们生成了对应的getXXX()和setXXX()。在很多时候我们喜欢把name,age,waist这些东西叫属性。其实,更加规范的的说法应该是:把有getXXX()或者setXXX()的变量叫做属性,把没有getXXX()或者setXXX()的变量称作字段。 很多时候,我们会看到这样的类:里面只有属性及其对应的get和set方法,这样的类也被称为JavaBean,比如此处的Girl类。 内省Introspector的使用方式 在此介绍与内省Introspector相关的操作 /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ private static void testPropertyDescriptor1() throws IntrospectionException{ BeanInfo beanInfo = Introspector.getBeanInfo(Girl.class); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { System.out.println(propertyDescriptor.getName()); } } 在此,我们利用属性描述器PropertyDescriptor获取Bean的属性,结果如下: age bust class hip name waist 嗯哼,发现了么?我们不但获取到了Gril类的五个属性还获取到了它的父类Object的属性class。 继续来看下面的例子: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ private static void testPropertyDescriptor2() throws Exception{ Girl girl = new Girl(); PropertyDescriptor propertyDescriptor = new PropertyDescriptor("age", Girl.class); Method setter = propertyDescriptor.getWriteMethod(); setter.invoke(girl, 18); Method getter = propertyDescriptor.getReadMethod(); Object age = getter.invoke(girl, null); System.out.println("age="+age); } 输出结果: age=18 代码解析如下: 得到与属性对应的属性描述器PropertyDescriptor,请参见代码第7行 得到该属性的set方法后为对象赋值,请参见代码第8—9行 得到该属性的get方法后取出属性值,请参见代码第10—11行 Beanutils BeanUtils是Apache提供的操作JavaBean的工具,它使用简单,操作方便。如有需要,可至其官方网站详细了解;在此不再赘述。

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

后台(33)——注解Annotation

探索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 注解Annotation 关于注解,请参见《 详解Android主流框架不可或缺的基石》,在此不再赘述

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

后台(31)——反射Reflection

探索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 关于该部分内容,敬请参见《详解Android主流框架不可或缺的基石》,不再赘述

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

后台(27)——文件上传

探索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 文件上传概述 文件上传通常指的是用户在浏览器中通过表单form将文件上传至服务端 但是请注意该表单必须满足如下三个条件: form的method必须是post form的enctype必须是multipart/form-data form中利用input type=”file”提供上传的入口 Commons-fileupload简介 Commons-fileupload是Apache提供的一个用来处理表单文件上传的一个开源组件。该组件操作简单、API通俗易懂、性能优异。 使用Commons-fileupload需要导入两个jar包: commons-fileupload commons-io Commons-fileupload使用示例 我们先来准备一个表单form <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>文件上传</title> </head> <body> <form enctype="multipart/form-data" action="${pageContext.request.contextPath }/servlet" method="post" > 文件描述:<input type="text" name="description"/><br/><br/> 选择文件:<input type="file" name="photo"/><br/><br/> <input type="submit" value="上传"/><br/><br/> </form> </body> </html> 运行后效果如下图所示: 再来写一个处理文件上传的Servlet /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FilenameUtils; public class UploadServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 判断表单是否支持文件上传 boolean isMultipartContent = ServletFileUpload.isMultipartContent(request); if (isMultipartContent) { DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload servletFileUpload = new ServletFileUpload(factory); servletFileUpload.setHeaderEncoding("UTF-8"); try { //得到并处理表单中的每个项 List<FileItem> fileItems = servletFileUpload.parseRequest(request); for (FileItem fileitem : fileItems) { if (fileitem.isFormField()) { processFormField(fileitem); } else { processUploadField(fileitem); } } } catch (Exception e) { e.printStackTrace(); } } } // 处理普通表单项 private void processFormField(FileItem fileitem) { try { String fieldName = fileitem.getFieldName(); String fieldValue = fileitem.getString("UTF-8"); System.out.println(fieldName + "=" + fieldValue); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } //处理上传表单项 private void processUploadField(FileItem fileItem) { try { //创建存放上传文件的目录 String folderName="upload"; String folderPath = getServletContext().getRealPath("/WEB-INF/"+folderName); File folder = new File(folderPath); if (!folder.exists()) { folder.mkdirs(); } //生成不重复的文件名 String fileName = fileItem.getName(); if (fileName != null) { fileName = FilenameUtils.getName(fileName); } fileName = UUID.randomUUID() + "_" + fileName; //按照日期生成子文件名称 String dateDirectory = makeDateDirectory(folder); //存放被上传的文件 File file=new File(folder, dateDirectory + File.separator + fileName); fileItem.write(file); } catch (Exception e) { e.printStackTrace(); } } //依据日期生成子文件夹 private String makeDateDirectory(File folder) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date=new Date(); String dateDirectory = simpleDateFormat.format(date); File file = new File(folder, dateDirectory); if (!file.exists()) { file.mkdirs(); } return dateDirectory; } } 嗯哼,鉴于该示例比较简单和代码里已有的注释,在此不再对代码作详解。 文件上传的注意事项 实际开发中,在处理文件上传时请注意以下问题: 将保存上传文件的目录放在用户直接访问不到的地方,比如WEB-INF 上传文件重名的处理,可用UUID+文件名的方式 将上传文件合理地存入子目录中,比如按照日期 限制上传文件的大小,比如3M

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

后台(26)——Filter(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 在这篇博客中我们利用Filter一并解决POST和GET请求的中文乱码。 测试表单 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Welcome</title> </head> <body> <form action="${pageContext.request.contextPath}/loginServlet" method="post"> <br/> 用 户:<input type="text" name="username"/><br/><br/> 密 码:<input type="password" name="password"/><br/><br/> <input type="submit" value=" 登 录 " /><br/> </form> </body> </html> 该页面非常简单,在点击”登录”之后跳转到loginServlet 测试Servlet /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGetAndPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGetAndPost(req, resp); } private void doGetAndPost(HttpServletRequest req, HttpServletResponse resp){ String username=req.getParameter("username"); System.out.println("---> username="+username); } } 在该页面中利用getParameter( )测试是否乱码 利用Filter过滤乱码 嗯哼,终于轮到今天的主角上场了 /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; public class TestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest) req; HttpServletResponse response=(HttpServletResponse) res; request=new MyHttpServletRequest(request); chain.doFilter(request, response); } @Override public void destroy() { } } class MyHttpServletRequest extends HttpServletRequestWrapper{ HttpServletRequest request; boolean isFirst=true; public MyHttpServletRequest(HttpServletRequest request) { super(request); this.request=request; } @Override public String getParameter(String name) { Map<String, String[]> parameterMap=getParameterMap(); String[] values=parameterMap.get(name); String value=values[0]; return value; } @Override public String[] getParameterValues(String name) { Map<String, String[]> parameterMap=getParameterMap(); String[] values=parameterMap.get(name); return values; } @Override public Map<String, String[]> getParameterMap() { Map<String, String[]> parameterMap = request.getParameterMap(); if(isFirst){ Set<Entry<String, String[]>> entrySet = parameterMap.entrySet(); for(Entry<String, String[]> entry:entrySet){ String[] values = entry.getValue(); for(int i=0;i<values.length;i++){ String value=values[i]; try { value=new String(value.getBytes("iso8859-1"),"UTF-8"); values[i]=value; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } isFirst=false; } return parameterMap; } } 在该类中通过继承HttpServletRequestWrapper实现自己的HttpServletRequest,即文中的MyHttpServletRequest。 覆写getParameter( )使其最终调用getParameterMap( ) 覆写getParameterValues( )使其最终调用getParameterMap( ) 在getParameterMap( )中将每个请求参数用UTF-8重新编码 配置文件 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter> <filter-name>TestFilter</filter-name> <filter-class>cn.com.TestFilter</filter-class> </filter> <filter-mapping> <filter-name>TestFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>loginServlet</servlet-name> <servlet-class>cn.com.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/loginServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 嗯哼,至此利用Filter同时解决了Post和Get请求时带来的中文乱码问题。

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

后台(25)——Filter(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、Filter、C3P0、MD5、HttpSession、Cookie实现等技术实现自动登录。 请看,本次示例的项目结构 在此,详解项目中的核心代码。 /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.com.bean.User; import cn.com.service.UserService; import cn.com.service.impl.UserServiceImpl; import cn.com.util.MD5Utils; public class LoginServlet extends HttpServlet { private final String MESSAGE="message"; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username=request.getParameter("username"); String password=request.getParameter("password"); password=MD5Utils.md5(password); UserService userService=new UserServiceImpl(); User user=userService.findUser(username, password); if(user!=null){ String autologin=request.getParameter("autologin"); Cookie cookie=new Cookie("userinfo", user.getUsername()+"&"+user.getPassword()); cookie.setPath("/"); if(autologin==null){ cookie.setMaxAge(0); }else{ cookie.setMaxAge(60*60*24*3); } response.addCookie(cookie); request.getSession().setAttribute("user", user); request.getRequestDispatcher("/home.jsp").forward(request, response); }else{ request.setAttribute(MESSAGE, "用户名或者密码错误,请重新登录"); request.getRequestDispatcher("/login.jsp").forward(request, response); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } } 获取表单传递过来的参数,请参见代码第24-25行 从数据库查询用户,请参见代码第28行 生成Cookie并返回给客户端,请参见代码第30-38行 依据是否自动登录设置Cookie的MaxAge,请参见代码第33-37行 将用户User保存到Session中,请参见代码第39行 /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.com.bean.User; import cn.com.service.UserService; import cn.com.service.impl.UserServiceImpl; public class LoginFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest) req; HttpServletResponse response=(HttpServletResponse) res; String path = request.getContextPath(); String uri = request.getRequestURI(); path = uri.substring(path.length()); if (!("/login.jsp".equals(path) || "/loginServlet".equals(path))) { User user=(User) request.getSession().getAttribute("user"); if(user==null){ String username=null; String password=null; Cookie[] cookies = request.getCookies(); for(int i=0;cookies!=null&&i<cookies.length;i++){ Cookie cookie=cookies[i]; String name=cookie.getName(); if("userinfo".equals(name)){ String value = cookie.getValue(); String[] strings = value.split("&"); username=strings[0]; password=strings[1]; break; } } UserService userService=new UserServiceImpl(); User u = userService.findUser(username, password); if(u!=null){ request.getSession().setAttribute("user", u); } } } chain.doFilter(request, response); } @Override public void destroy() { } } 如果访问的不是登录相关的资源那么就考虑是否自动登录,请参见代码第39-62行 如果用户没有登录过则开始自动登录,请参见代码第40-61行 自动登录成功后将User保存到Session中,请参见代码第59行 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter> <filter-name>loginFilter</filter-name> <filter-class>cn.com.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>loginServlet</servlet-name> <servlet-class>cn.com.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/loginServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 在web.xml中配置Servlet和Filter

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

后台(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()取出数据;但是重定向不可以也没有道理这么做。至于为什么,请参考第一点。

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

后台(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

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

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

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册