Java学习笔记

java环境搭建

安装下载

jdk里面包含jre,只需要下载jdk就可以了,【注意细节】安装时不安装公共JRE,因为JDK本身就含有JRE

不要按默认目录安装,因为里面还有空格,可以安装到D盘

https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html

配置path路径

D:\Dev\Java\jdk1.8.0_231\bin

D:\Dev\Java\jdk1.8.0_231\jre\bin

开发工具

https://www.eclipse.org/downloads/packages/

自动提示

打开window->preference 搜索content assist ,在java里面找到Auto Activation 下 Auto activation trigger for Java :替换成:

.abcefghijklmnopqrstuvwxyz(,0123456789
常用快捷键

代码助手:Alt+/
快速修正:Ctrl+1
删除选中的行:Ctrl+D
组织导入:Ctrl+Shift+O
格式化代码:Ctrl+Shift+F

查看某个类的源代码:Ctrl+点进去
快速Outline:Ctrl+O
打开继承体系:Ctrl+T

打开资源:Ctrl+Shift+R
打开类型:Ctrl+Shift+T
上下移动选中的行:Alt+Up/Down
上下复制选中的行:Ctrl+Alt+Up/Down

单行注释:Ctrl+/
多行注释:Ctrl+Shift+/
取消多行注释: Ctrl+Shift+
变为大/小写:Ctrl+Shift+X/Y

Alt+Shift+R:重命名

如何查看快捷键

断点调试
F5:Step Into/进入
F6:Step over/跳过
F7:Step return/返回
F8:Resume/继续

Javaweb

javaweb就是:web应用程序,属于动态页面

环境配置

需要的软件:Apache Tomcat,eclipse,jdk8

Apache Tomcat

下载:https://tomcat.apache.org/download-80.cgi#8.5.72

支持的版本

Apache Tomcat version 8.5 implements the Servlet 3.1 and JavaServer Pages 2.3

运行Tomcat

打开Tombcat所在目录,找到bin目录下的startup.bat运行文件

在Eclipse中配置

Window>Preferences>Server>Runtime Environments>Add>选择:找到Tomcat的根目录>Apply and close

XML

可扩展标记语言

特殊符号的表示
约束文档书写规则

DTD

Schema

解析XML

使用dom4j

下载地址:https://dom4j.github.io/

示例:

import java.net.URL;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;

public class Foo {

    public Document parse(URL url) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(url);
        return document;
    }
}
public void bar(Document document) throws DocumentException {

    Element root = document.getRootElement();

    // iterate through child elements of root
    for (Iterator<Element> it = root.elementIterator(); it.hasNext();) {
        Element element = it.next();
        // do something
    }

    // iterate through child elements of root with element name "foo"
    for (Iterator<Element> it = root.elementIterator("foo"); it.hasNext();) {
        Element foo = it.next();
        // do something
    }

    // iterate through attributes of root
    for (Iterator<Attribute> it = root.attributeIterator(); it.hasNext();) {
        Attribute attribute = it.next();
        // do something
    }
 }
项目默认配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>项目名称</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>
初始化参数配置
<init-param>
    <param-name>Encoding</param-name>
    <param-value>UTF-8</param-value>
</init-param>
配置404页面
<error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
</error-page>

http协议

规定了一系列浏览器访问服务器的规则,规定请求和响应的数据规则,什么样的数据以及数据的排列规则

网址:

IP地址:

端口号:

请求和响应就是数据的交流

请求

数据包:访问的网址

request 客户端> 服务器端

请求头:Request Headers

请求方式  地址  HTTP版本
GET /web01/ HTTP/1.1 

域名
Host: localhost:8080 

Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1

客户端信息:浏览器版本
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

Cookie
Cookie: JSESSIONID=F5B83E5D7963125AB9DE8C9F7509F8C0
带有参数的请求
http://localhost:8080/web01/?username=sunao&password=12345
jsp里面可以接收参数
<%
String username = request.getParameter("username");
System.out.println(username);
String password = request.getParameter("password");
System.out.println(username);
%>
Post请求
POST /web01/login.jsp HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 23
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: http://localhost:8080
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/web01/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: JSESSIONID=2FE0CE80CF51439132319D34667183BB

Form Data

username=12&password=12
响应

数据包:网页的资源

response 服务器端> 客户端

响应头

Response Headers

HTTP/1.1 200
Content-Type: text/html;charset=utf-8
Content-Length: 200
Date: Mon, 11 Oct 2021 12:50:03 GMT
Keep-Alive: timeout=20
Connection: keep-alive
响应状态码

200

404

响应体




<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
欢迎你







www.sunao.com


	
www.sunao.com


</body>
</html>

JSP

Java服务器页面,一个简化的servlet

java EE的入门课程

用来开发动态页面

创建jsp项目

jsp是java和HTML的组合

Dynamic Web Project

new>other>web>Dynamic Web Project

选择Severlet版本

新建网站入口:index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>

</body>
</html>
编码设置

选择jsp文件>右击>选择Properties>修改Other里面的选择为UTF-8

手动修改:utf-8

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
欢迎你
</body>
</html>
运行web项目

选择项目>Run as>Run On Server>选择配置好的Tomcat版本

在jsp页面书写java代码

使用<% %>

这里面可以调用jsp的内置对象,也可以调用java的对象

<%@page import="java.util.Date"%>
<%@page import="javax.xml.crypto.Data"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
欢迎你
<%
// 这里可以任意书写java代码
// out是jsp里面的内置对象
	out.println("当前登录用户:SIKI");
	// 显示在客户端
	out.println(new Date());
	// 显示在服务器
	System.out.println(new Date());
%>

</body>
</html>
注释
注释java

注释jsp里面的java代码,和java里面的注释一样

<%@page import="java.util.Date"%>
<%@page import="javax.xml.crypto.Data"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
欢迎你
<%
// 这里可以任意书写java代码
// out是jsp里面的内置对象
	/*out.println("当前登录用户:SIKI");
	// 显示在客户端
	out.println(new Date());
	*/
	// 显示在服务器
	System.out.println(new Date());
%>

</body>
</html>
注释HTML

注释HTML代码,也可以注释java代码

<%@page import="java.util.Date"%>
<%@page import="javax.xml.crypto.Data"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
欢迎你
<%-- 注释HTML代码 --%>
    
<%
// 这里可以任意书写java代码
// out是jsp里面的内置对象
	/*out.println("当前登录用户:SIKI");
	// 显示在客户端
	out.println(new Date());
	*/
	// 显示在服务器
	System.out.println(new Date());
%>

</body>
</html>
java包的引入
<%@page import="java.util.Date"%>
<%--
 多个包的时候使用 逗号 隔开 
--%>
<%@page import="java.util.Date,java.util.Math"%>
jsp变量
理解jsp

每个jsp页面可以看做一个java类,实际是每个jsp页面都会对应一个类,是系统自动生成的一个类,当访问jsp页面的时候就会访问这类的代码

jsp里面的成员变量/定义表达式
<%! 
	// 定义java代码
	// 成员变量 可以保存下来
	int count = 0; 
%>
jsp里面的局部变量
<%
	// 局部变量  
	// 运行一次初始化一次
	int number = 0;
	count++;
	number++;
	out.println("count:"+count);
	out.println("number:"+number);
%>
jsp表达式
组合页面表达式

可以传递参数,来表示当前哪个页面引入的header.jsp。在header.jsp页面可以获取参数,通过jstl表达式参数判断控制class来控制css样式

<jsp:include page="header.jsp">
	<jsp:param value="0" name="flag"/>
</jsp:include>
<c:if test="${param.flag==0 }">class="active"</c:if>
输出表达式

作用:专门往页面上输出内容的

<%
String str = "www.sunao.com";
%>

<%=str %>
定义表达式
<%! 
	// 定义java代码
	// 成员变量 可以保存下来
	int count = 0; 
%>
与java代码的混合使用
<%@page import="com.sun.util.DBUtil"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

<%
String username = request.getParameter("username");
String password = request.getParameter("password");
String repassword = request.getParameter("repassword");
int age = Integer.parseInt(request.getParameter("age"));
String sex = request.getParameter("sex");

boolean isSuccess = DBUtil.addUser(username, password,repassword, age, sex);
if(isSuccess) {
	//out.println("<h1>注册成功</h1>");
%>
	<h1>恭喜<%= username %>注册成功</h1>
	<a href="login.jsp">返回登录页面</a>
<%
}
else 
{
	//out.println("<h1>注册失败</h1>");
%>
	<h1>注册失败</h1>
	<%
}


%>

解决中文乱码问题

package com.sum.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.annotation.WebFilter;

/**
 * Servlet Filter implementation class EncodeFilter
 */
@WebFilter("/*")
public class EncodeFilter implements Filter {

    /**
     * Default constructor. 
     */
    public EncodeFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

		request.setCharacterEncoding("utf-8");
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

request.setCharacterEncoding("utf-8");

jsp内置对象

out

打印输出

out.println();
request
// 获取用户参数
String username = request.getParameter("username")
解决乱码问题
request.setCharacterEncoding("utf-8");
请求转发

把页面作为数据直接返回

session.setAttribute("user", user);
request.getRequestDispatcher("personCenter.jsp").forward(request, response);
response
// 给客户端数据
PrintWriter writer = response.getWriter();
writer.println("printWriter");

服务器之间的数据传递

客户端每次请求都是不同的request,只有重定向之后才可以把数据传给另一个jsp文件

//需要传递的数据 k V
request.setAttribute(key,value);
request.getRequestDispatcher("login.jsp").forward(request,response);
// 需要接收的数据
Object data = request.getAtrribute(key);

Session会话

生命周期:可以设置

作用

让当前登录的用户,在任何页面都可以显示用户信息

把用户信息保存下来,每个页面都可以访问

存储的位置:

同一个客户端访问的时候,session的地址相同,不同的客户端session不同

<%
User user =(User)session.getAttribute("user");
if(user!=null){
%>
当前登录用户:<%=user.getUsername() %><br>
<%
}
%>
appliction

整个服务器端就存在一个application对象,相当于网站

所有客户端访问的都是同一个application

作用

存储所有客户端都需要的数据

比如:登录客户端个数,当前用户登录个数

int number = 0;
//application.setAttribute("usercount", arg1);
if(application.getAttribute("userNumber")!=null){
number = (Integer)application.getAttribute("userNumber");
}
number++;
application.setAttribute("userNumber", number);
	
page

只在当前页面生效的对象,等于当前jsp的页面的this

pageContext

页面的容器

// 四个域对象:page request session application 作用域从左到右依次增大
// pageContext获取四大域对象
pageContext.getOut();
pageContext.getRequest();
pageContext.getResponse();
pageContext.getSession();//httpSession
pageContext.getServletContext();//application

// 设置属性
pageContext.setAttribute("key", "sun");
// 指定域 设置属性
pageContext.setAttribute("user", "ss", pageContext.SESSION_SCOPE);

Servlet

作用:更加适合做逻辑处理

jsp更加做展示

创建servlet
package com.sun.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 注解 访问路径
@WebServlet("/demo_do")
// 继承 HttpServlet
public class DemoServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.getWriter().append("我的doget方法");
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.getWriter().append("doPost");
	}
}

Servlet获取application
ServletContext application = this.getServletContext();
Servlet获取session
HttpSession session = request.getSession();
通过配置文件配置servlet访问路径

在xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">
	<servlet>
		<servlet-name>LoginServlet</servlet-name>
		<servlet-class>com.sun.servlet.LoginServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>LoginServlet</servlet-name>
		<url-pattern>/login_do</url-pattern>
	</servlet-mapping>
	<servlet>
		<servlet-name>RegisterServlet</servlet-name>
		<servlet-class>com.sun.servlet.RegisterServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>RegisterServlet</servlet-name>
		<url-pattern>/register_do</url-pattern>
	</servlet-mapping>

</web-app>

生命周期
package com.sun.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public TestServlet() {
        super();
        System.out.println("构造方法");
    }
    
    @Override
    public void init() throws ServletException {
    	// TODO Auto-generated method stub
    	super.init();
    	System.out.println("init方法");
    }
    
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	// TODO Auto-generated method stub
    	super.service(req, resp);
    	System.out.println("service方法");
    }
    
    @Override
    public void destroy() {
    	// TODO Auto-generated method stub
    	super.destroy();
    	System.out.println("destroy方法"); 
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet方法");
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost方法");
	}

}

构造方法
init方法
doGet方法
service方法
十月 13, 2021 11:08:51 上午 org.apache.catalina.core.StandardContext reload
信息: 已开始重新加载名为[/web03]的上下文
destroy方法

重定向

重定向是客户端需要处理的地址

所有不需要传递数据的都可以使用重定向

servlet与 :servlet、jsp之间可以互相重定向,以及请求转发

直接访问这个页面

重定向和请求转发的区别

重定向:客户给你一个维修部门的电话号码,让你自己打

请求转发:客户帮你接通维修部门的电话

request.setAttribute("msg", "注册成功,请登录");
//request.getContextPath() 根目录
response.sendRedirect(request.getContextPath()+"login.jsp");

jsp 内置标签

jsp:include

作用:可以包含内置页面,重复的页面比如头部和底部可以重复利用,便于维护

<jsp:include page="head.jsp"></jsp:include>

路径

相对路径

缺点:在请求转发的时候会存在路径不对的问题

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/style.css" type="text/css" />
<title>Insert title here</title>
</head>
<body>

<h1>我是path页面</h1>


</body>
</html>
绝对路径
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="/web04/css/style.css" type="text/css" />
<title>Insert title here</title>
</head>
<body>

<h1>我是path页面</h1>


</body>
</html>
动态绝对路径

客户端路径一律使用绝对路径,开发中使用的方式

<link rel="stylesheet" href="<%=request.getContextPath() %>/css/style.css" type="text/css" />
客户端路径

客户端路径一律使用绝对路径,否则在请求转发的时候会出现404页面,原因:是因为在客户端解析的路径是以访问地址[ http://localhost:8080/web04/product/list.jsp ]为开始路径,在请求转发的时候路径还是转发之前的路径,不会改变到当前jsp页面的路径

解析相对路径
<a href="test1.jsp">进入test1</a>

结果

<a href="test1.jsp">进入test1</a>
解析绝对路径
<a href="<%=request.getContextPath() %>/test1.jsp">进入test1</a>

结果

这里会加上项目路径

<a href="/web04/test1.jsp">进入test1</a>
服务器路径

服务器需要解析的路径,使用相对路径即可

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<jsp:include page="head.jsp"></jsp:include>
<%
pageContext.setAttribute("key", "sun");
pageContext.setAttribute("user", "ss", pageContext.SESSION_SCOPE);
out.println(session.getAttribute("user"));


%>
<jsp:include page="footer.jsp"></jsp:include>
</body>
</html>

MVC

模型层Model

存放数据

不同的数据分类成不同的数据模型,对java类进行分类

每个数据模型在数据库中都对应一个表

用户:

课程

视图层View

存放jsp页面

控制层Controller

存放servlet

JavaEE架构层
web层

MVC

service层

业务逻辑

注册登录

dao层

数据库交互

EL表达式

取数据

让jsp页面变得更优雅,美观

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
page request session application
    作用:直接取得四大域里面的数据,域名+Scope
<%
request.setAttribute("number", 2000);
session.setAttribute("user", "sunao");
application.setAttribute("count", 80000);
%>

当前在线人数:${requestScope.number}
<hr/>
用户名:${sessionScope.user};
<hr/>
</body>
</html>
之前的写法
<%
Object o = request.getAttribute("msg");
if(o!=null) out.println(o+"<br/>");
%>

el表达式
${requestScope.msg}
调用对象的属性和方法

调用数据时,其属性必须有get方法

<%
User user = (User)session.getAttribute("user");
%>
<h3>欢迎<%=user.getUsername() %>!</h3><br/>
<h3>欢迎${user.username}!</h3><br/>
<h3>欢迎${user.getUsername()}!</h3><br/>
调用map里面的数据
<%
Map<String,String> map = new HashMap<String,String>();
map.put("name", "sun");
request.setAttribute("map", map);
%>
使用map调用name:${map.name }

list集合中
<%
List<User> list = new ArrayList<User>();
list.add(new User("sun","ai1",12,"baoy",false));
list.add(new User("sun1","a2i",12,"baoy",false));
list.add(new User("sun2","a3i",12,"baoy",false));

request.setAttribute("list", list);
%>
<p></p>
list1内容:${list[1].getUsername()}
<p></p>
list2内容:${list[2].username}
获取项目路径
// 之前使用的是 request.getContextPath() 
// 只要是get方法 el表达式都可以使用
// 首先获得request对象,通过pageContext对象
${pageContext.request.contextPath}

局限性:只能取数据,和简单的运算

${empty user} 返回true或false
${1+1}

jstl表达式

标签库,用来存储数据的,以及逻辑处理

下载jar包:http://www.java2s.com/Code/Jar/j/Downloadjstlapi12jar.htm

放到lib文件夹下边,将自动放到Libraries库中

jsp页面引入jstl

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
jstl标签

设置数据,移除数据、输出数据

<c:set var="username" value="sikiedu" scope="request"></c:set>
${requestScope.username}
<c:remove var="username"></c:remove>
${username }
<c:out value="哈哈哈哈哈哈"></c:out>
条件语句
<c:set var="age" value="2" scope="request"></c:set>

// if语句
<c:if test="true">true</c:if>

//相当于if else
<c:choose>
<c:when test="${age>=18 }">已经成年了</c:when>
<c:otherwise>你是未成年</c:otherwise>
</c:choose>
组合页面表达式

可以传递参数,来表示当前哪个页面引入的header.jsp。在header.jsp页面可以获取参数,通过jstl表达式参数判断控制class来控制css样式

<jsp:include page="header.jsp">
	<jsp:param value="0" name="flag"/>
</jsp:include>
<c:if test="${param.flag==0 }">class="active"</c:if>
控制分页
<!-- 分页 -->
<div>
	<div style='text-align:center;'>
		<a class='btn btn-info' <c:if test="${p.pageNumber==1}">disabled</c:if> <c:if test="${p.pageNumber!=1}">href="${pageContext.request.contextPath}/recoment_goods?pageNo=1&id=${id}" </c:if>>首页</a>
		<a class='btn btn-info' <c:if test="${p.pageNumber==1}">disabled</c:if> <c:if test="${p.pageNumber!=1}">href="${pageContext.request.contextPath}/recoment_goods?pageNo=${p.pageNumber-1}&id=${id}"</c:if> >上一页</a>
		<h2 style='display:inline;'>[${p.pageNumber}/${p.totalPage}]</h2>
		<h2 style='display:inline;'>[${p.totalCount}]</h2>
		<a class='btn btn-info' <c:if test="${p.pageNumber==p.totalPage}">disabled</c:if> <c:if test="${p.pageNumber!=p.totalPage}">href="${pageContext.request.contextPath}/recoment_goods?pageNo=${p.pageNumber+1}&id=${id}"</c:if> >下一页</a>
		<a class='btn btn-info' <c:if test="${p.pageNumber==p.totalPage}">disabled</c:if> <c:if test="${p.pageNumber!=p.totalPage}">href="${pageContext.request.contextPath}/recoment_goods?pageNo=${p.totalPage}&id=${id}"</c:if>>尾页</a>
						<input type='text' class='form-control' style='display:inline;width:60px;' value=''/><a class='btn btn-info'  οnclick='location.href="${pageContext.request.contextPath}/new_goods?&id=${id}&pageNo="+(this.previousSibling.value)'>GO</a>
					</div>
				</div>
for循环
<c:forEach var="i" begin="1" end="10">
${i}<br/>
</c:forEach>

利用el表达式和jstl表达foreach循环配合使用,遍历集合

items:集合对象

var:集合里面的元素

<c:forEach items="${list}" var="user">
${user.username}:${user.password}:${user.age}
</c:forEach>
通过for循环控制商品显示列表
<c:forEach items="${p.list}" var="g">
							<div class="product-grid">
								<a href="${pageContext.request.contextPath }/goods_detail?goodsid=${g.id}">				
									<div class="more-product"><span> </span></div>						
									<div class="product-img b-link-stripe b-animate-go  thickbox">
										<img src="${pageContext.request.contextPath }${g.cover}" class="img-responsive" alt="${g.name }" width="240" height="240">
										<div class="b-wrapper">
											<h4 class="b-animate b-from-left  b-delay03">							
												<button>查看详情</button>
											</h4>
										</div>
									</div>
								</a>				
								<div class="product-info simpleCart_shelfItem">
									<div class="product-info-cust prt_name">
										<h4>${g.name }</h4>								
										<span class="item_price">¥${g.price}</span>
										<input type="button" class="item_add items" value="加入购物车" οnclick="buy(6)">
										<div class="clearfix"> </div>
									</div>												
								</div>
							</div>
						</c:forEach>

EL与jstl混合使用

中间没有任何java代码

<%@page import="com.sun.model.User"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<h1>首页</h1>
<hr/>

<c:choose>
<c:when test="${empty user}">
<a href="${pageContext.request.contextPath }/login.jsp">登录<a/>
<a href="${pageContext.request.contextPath }/register.jsp">注册</a>

</c:when>
<c:otherwise>
<h3>当前登录用户:${user.username}!</h3><br/>
</c:otherwise>
</c:choose>
各种商品的展示
</body>
</html>

JSON数据格式

json基础数据

字符串:“siki” “ww.sikidedu.com” " " “我是中国人”
数字:100 200
空: null
布尔: true / false

复杂数据

对象:都是成对出现的数据

可以包含对象数组和基础数据类型

{ 
	"key":"基础数据/对象",
	"name":"Michel",
	"age":20,
	"成绩":{
			"数学":200
		},
	"数组":[100,200,200,300],
	"数组2":[{"对象":1},{"hh":1}]
}  

数组:都是单身狗

可以包含对象数组和基础数据类型

[ 100,200,200,300] 长度为4 索引从0开始
[] 空数组

下载jar包

https://www.json.org/json-en.html

JSON的序列化与反序列化

序列化
// 序列化 持久化
Goods goods = new Goods("香蕉", "夏威夷", 100, 400);
String json = JSON.toJSONString(goods);
System.out.println(json);
序列化

每个对象类型 {“username”:“make”,“age”:12}的数据

都要与之对应的数据模型(比如User、Goods)

// 反序列化  反持久化
String s = "{\"des\":\"夏威夷\",\"inventory\":400,\"name\":\"香蕉\",\"price\":100}";
Goods goods = JSON.parseObject(s, Goods.class);
System.out.println(goods.getName());
System.out.println(goods.getDes());
System.out.println(goods.getPrice());

如果是多个对象组成的数组JSON数据,需要使用parseArray(string,class)解析数据

String s = "[{\"username\":\"make\",\"age\":12},"
				+ "{\"username\":\"make\",\"age\":12},"
				+ "{\"username\":\"make\",\"age\":12}]";
		
List<UserTest> list = JSON.parseArray(s, UserTest.class);
for (UserTest user : list) {
	System.out.println(user);
}
		

Ajax动态请求

在页面不进行跳转和刷新的情况下向服务器发起请求

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.6.0.min.js"></script>
<script>
$(function(){
	$("input[name=username]").blur(verifyUsername);
})
// 验证方法
function verifyUsername(){
	$.ajax({
		url:"${pageContext.request.contextPath}/verifyUsername",//请求地址
		type:"post",//请求方式
		data:{//请求的数据 json格式
			username:$("input[name=username]").val()
		},
		dataType:"json",//接收的数据格式类型
		//cache:false,
		success:function(msg){//响应成功执行的方法
			if(msg.isSuccess){
				$("#username").html("<font color='green'>用户名可用</font>");
			}else{
				$("#username").html("<font color='red'>用户名重复</font>");
			}
			
		}
	})
}
</script>
</head>
<body>
<h1>注册</h1>
<hr/>
${msg}
<form action="<%=request.getContextPath() %>/register_do" method="post">
用户名<input type="text" name="username"><span id="username"></span><br/>
密码<input type="password" name="password"><br/>
年龄<input type="text" name="age"><br/>
性别:男<input type="radio" name="sex" value="" checked="checked"><input type="radio" name="sex" value=""><br/>
<input type="submit" value="注册" ><br/>
</form>
</body>
</html>

服务器端的servlet处理

package com.sun.controller;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.service.UserServise;

@WebServlet("/verifyUsername")
public class VerifyUsernameServlet extends HttpServlet {
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取用户名,验证是否存在
		boolean exst = new UserServise().isExst(request.getParameter("username"));
		System.out.println(exst);
        // 这里响应一个json的数据给客户端
		response.getWriter().append("{\"isSuccess\":"+!exst+"}");
	}
}

过滤器

设置所有的访问路径的限制

@WebFilter("/*")
public class EncodeFilter implements Filter {

	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	//设置所有访问的页面的编码
		request.setCharacterEncoding("utf-8");
		chain.doFilter(request, response);
	}
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

servlet是被访问的,filter是用来过滤访问路径

配置文件过滤访问路径

通过配置文件配置需要过滤访问路径

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>web05</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
    <filter-name>Test1Filter</filter-name>
    <filter-class>com.sun.filter.Test1Filter</filter-class>
  </filter>
  <filter>
    <filter-name>AdminFilter</filter-name>
    <filter-class>com.sun.filter.AdminFilter</filter-class>
  </filter>
  <filter>
    <filter-name>EncodeFilter</filter-name>
    <filter-class>com.sun.filter.EncodeFilter</filter-class>
    <init-param>
      <param-name>Encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>Test1Filter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>EncodeFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>AdminFilter</filter-name>
    <url-pattern>/admin/*</url-pattern>
  </filter-mapping>
</web-app>

通过过滤路径从而达到过滤请求的内容

过滤器的调用先后顺序和配置文件里面的配置先后顺序有关

chain.doFilter(request, response);//放行

利用重定向设置拒绝访问

httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
设置访问权限
package com.sun.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.annotation.WebFilter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.sun.model.User;
import com.sun.service.UserServise;

/**
 * Servlet Filter implementation class AdminFilter
 */
//@WebFilter("/*")
public class AdminFilter implements Filter {

    /**
     * Default constructor. 
     */
    public AdminFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here
		HttpServletRequest httpReq = (HttpServletRequest) request;
		HttpServletResponse httpResp = (HttpServletResponse) response;
		Object o = httpReq.getSession().getAttribute("user");
		if (o!=null) {
			User user = (User)o;
			if (user.isAdmin()) {
				chain.doFilter(request, response);//放行
			}else {
				httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
			}
		}else {
			httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
		}
		// pass the request along the filter chain
		
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

监听器

监听

作用:是用来实时获取以及设置四大域的属性值的,request session application

//通过application 域让每个页面都能获取到typelist
@WebListener
public class ApplicationListener implements ServletContextListener {
	
	private TypeService tService = new TypeService();
	
    public void contextDestroyed(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
    }
    	
    public void contextInitialized(ServletContextEvent arg0)  { 
    	List<Type> list = tService.selectAll();
    	// 获取application对象 
    	arg0.getServletContext().setAttribute("typeList", list);
    	
    	
    }
	
}

配置监听器

注解和配置文件不能同时存在,否则报错

<listener>
  <listener-class>com.sun.listener.SessionListener</listener-class>
</listener>
配置session生命周期
<session-config>
  <session-timeout>1</session-timeout>
</session-config>

BeanUtils快速获取表单参数

快速获取request.parameter()的所有参数

下载:commons-beanutils-1.9.3.jar

依赖:commons-logging-1.2.jar

注意:参数名称必须和user对象的字段保持一致

package com.sum.model;

public class User {
	private int id;
	private String username;
	private String password;
	private String email;
	private String name;
	private String phone;
	private String address;
	private boolean isadmin;
	private boolean isvalidate;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	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 getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public boolean isIsadmin() {
		return isadmin;
	}
	public void setIsadmin(boolean isadmin) {
		this.isadmin = isadmin;
	}
	public boolean isIsvalidate() {
		return isvalidate;
	}
	public void setIsvalidate(boolean isvalidate) {
		this.isvalidate = isvalidate;
	}
	public User(int id, String username, String password, String email, String name, String phone, String address,
			boolean isadmin, boolean isvalidate) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
		this.email = email;
		this.name = name;
		this.phone = phone;
		this.address = address;
		this.isadmin = isadmin;
		this.isvalidate = isvalidate;
	}
	public User( String username, String password, String email, String name, String phone, String address
			) {
		super();
		this.username = username;
		this.password = password;
		this.email = email;
		this.name = name;
		this.phone = phone;
		this.address = address;
		this.isadmin = false;
		this.isvalidate = false;
	}
	public User() {
		super();
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", name="
				+ name + ", phone=" + phone + ", address=" + address + ", isadmin=" + isadmin + ", isvalidate="
				+ isvalidate + "]";
	}
	
}

User user = new User();
		
try {
    BeanUtils.copyProperties(user, request.getParameterMap());
} catch (IllegalAccessException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

<form class="form-horizontal" action="${pageContext.request.contextPath}/admin/user_add" method="post">
		<div class="form-group">
			<label for="input_name" class="col-sm-1 control-label">用户名</label>
			<div class="col-sm-6">
				<input type="text" class="form-control" id="input_name" name="username" required="required">
			</div>
		</div>
		<div class="form-group">
			<label for="input_name" class="col-sm-1 control-label">密码</label>
			<div class="col-sm-6">
				<input type="text" class="form-control" id="input_name" name="user.password" required="required">
			</div>
		</div>
		<div class="form-group">
			<label for="input_name" class="col-sm-1 control-label">电话</label>
			<div class="col-sm-6">
				<input type="text" class="form-control" id="input_name" name="user.phone" >
			</div>
		</div>
		<div class="form-group">
			<label for="input_name" class="col-sm-1 control-label">地址</label>
			<div class="col-sm-6">
				<input type="text" class="form-control" id="input_name" name="user.address" >
			</div>
		</div>
		<div class="form-group">
			<div class="col-sm-offset-1 col-sm-10">
				<button type="submit" class="btn btn-success">提交保存</button>
			</div>
		</div>
	</form>

URLEncode编码

在java代码中把中文变成编码,在request获取参数的时候会自动编码回来

String keyword = URLEncoder.encode(keyword,"utf-8")

在jsp页面获取编码后的中文

<h2>搜索`${param.keyword}`的结果</h2>

注意事项

路径问题

路径前面注意加 /

重定向请求的是绝对路径

重定向获取根路径
request.getContextPath()
jsp传参

<jsp:include page="../page.jsp">
	<jsp:param value="/admin/goods_list" name="path"/>
	<jsp:param value="&id=${id}" name="param"/>
</jsp:include>

接收

${param.path }
Parameter的类型数据权限要大于request设置的属性的数据

比如:通过jsp传递的参数,通过请求转发,在转发的过程中设置request相同参数名称的属性,再另一个页面接收的时候会只接受jsp传递的参数

<a href="option?type=${type}&goodsid=${g.id}&currenttype=1">加入条幅</a>//通过jsp传参
int currenttype = Integer.parseInt(request.getParameter("currenttype"));
request.setAttribute("type", currenttype);//java里面设置request的属性
request.getRequestDispatcher("/admin/goods_list").forward(request, response);
int type = Integer.parseInt(request.getParameter("type"));//这里优先接收jsp页面的参数名

数据库

tinyInt 适合数量小的数据存储类型

JDBC

安装MYSQL Connector for java

里面包含MySQL驱动

导入MySQL驱动

通过驱动里面的api访问MySQL数据库

中间人,翻译

找到C:\Program Files (x86)\MySQL\Connector J 8.0文件夹下的mysql-connector-java-8.0.26.jar包就是驱动

操作数据库的工具包:commons-dbutils-1.7.jar

导入到库

新建文件夹lib

复制到lib里面

右击build path

链接数据库
package com.sum.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JDBCUtils {
	private static String url = "jdbc:mysql://localhost:3306/cakeshop?userUnicode=true&characterEncoding=UTF8";
	private static String root = "root";
	private static String sql_password = "123456";
	
	// 创建连接
	public static Connection getConnection() {
		// 加载驱动
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			return DriverManager.getConnection(url,root,sql_password);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	// 关闭连接
	public static void closeAll(ResultSet rs, PreparedStatement state, Connection con) {
		try {
			if (rs!=null) rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		try {
			if (state!=null) state.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	
		try {
			if (con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}	
}

操作数据库
package com.sum.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCDemo01 {

	public static void main(String[] args) {
		//selectAll();
		//System.out.println(selectByUP("1", "1"));
		//selectUserByPage(1,10);
		//insert("hhh","hhj");
		//delete(19);
		update(12, "sdfsf");
	}
	
	public static void selectAll() {
		
		ResultSet rs = null;
		PreparedStatement state = null;
		Connection con = null;

		// 注册驱动 
		try {
			con = JDBCUtils.getConnection();
			
			String sql = "SELECT * FROM cakeshop.goods";
			// 执行SQL语句
			state = con.prepareStatement("SELECT * FROM cakeshop.goods");
			rs = state.executeQuery();
			
			// 输出结果
			while (rs.next()) {
				System.out.println(rs.getInt(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4));
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.closeAll(rs, state, con);
		}

	}

	public static boolean selectByUP(String username,String password) {
		Connection con = null;
		PreparedStatement pstate = null;
		ResultSet rs = null;
		try {
			con = JDBCUtils.getConnection();
			// 执行语句
			String sql = "select * from user where username=? and password=?";
			pstate = con.prepareStatement(sql);
			pstate.setString(1, username);
			pstate.setString(2, password);
			
			rs = pstate.executeQuery();
			// 输出结果
			if (rs.next()) {
				return true;
			}else {
				return false;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCUtils.closeAll(rs, pstate, con);
		}
		return false;
	}
	
	public static void selectUserByPage(int pageindex,int pagesize) {
		Connection con = null;
		PreparedStatement pstate = null;
		ResultSet rs = null;
		try {
			con = JDBCUtils.getConnection();
			
			// 执行语句
			String sql = "select * from user limit ?,?";
			pstate = con.prepareStatement(sql);
			pstate.setInt(1, (pageindex-1)*pagesize);
			pstate.setInt(2, pagesize);
			
			rs = pstate.executeQuery();
			// 输出结果
			while (rs.next()) {
				System.out.println(rs.getInt(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4));
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCUtils.closeAll(rs, pstate, con);
		}
	}
	
	public static void insert(String username,String password) {
		
		ResultSet rs = null;
		PreparedStatement pstate = null;
		Connection con = null;
		
		try {
			con = JDBCUtils.getConnection();
			
			String sql = "insert into user(username,password) value(?,?)";
			pstate = con.prepareStatement(sql);
			pstate.setString(1, username);
			pstate.setString(2, password);
			int update = pstate.executeUpdate();//返回值代表受到影响的行数
			System.out.println(update);
			
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			JDBCUtils.closeAll(rs, pstate, con);
		}
	}
	
	public static void delete(int id) {
		
		ResultSet rs = null;
		PreparedStatement pstate = null;
		Connection con = null;
		
		try {
			con = JDBCUtils.getConnection();
			
			String sql = "delete from user where id = ?";
			pstate = con.prepareStatement(sql);
			pstate.setInt(1, id);
			int num = pstate.executeUpdate();//返回值代表受到影响的行数
			if (num>0) {
				System.out.println("删除成功");
			}else {
				System.out.println("删除失败");
			};
			
		} catch (Exception e) {
			System.out.println(e);
		}finally {
			JDBCUtils.closeAll(rs, pstate, con);
		}
		
		
	}
	
	
	public static void update(int id,String password) {
		
		ResultSet rs = null;
		PreparedStatement pstate = null;
		Connection con = null;
		
		try {
			con = JDBCUtils.getConnection();
			
			String sql = "update user set password=? where id=?";
			pstate = con.prepareStatement(sql);
			pstate.setString(1, password);
			pstate.setInt(2, id);
			int update = pstate.executeUpdate();//返回值代表受到影响的行数
			if (update>0) {
				System.out.println("修改成功");
			}
			
		} catch (Exception e) {
			System.out.println(e);
		}finally {
			JDBCUtils.closeAll(rs, pstate, con);
		}
		
	}
	
}

事务

转账操作,保证多个操作要么同时成功要么同时失败

con.setAutoCommit(false);//开启事务
//-----------------------------------------------------------------------//		
String sql = "update user set balance= balance - ? where username=?";
pstate1 = con.prepareStatement(sql);
pstate1.setInt(1, money);
pstate1.setString(2, userame1);
int update = pstate1.executeUpdate();//返回值代表受到影响的行数
if (update>0) {
    System.out.println("修改成功");
}

String string = null;
string.toCharArray();

String sql2 = "update user set balance= balance + ? where username=?";
pstate2 = con.prepareStatement(sql2);
pstate2.setInt(1, money);
pstate2.setString(2, username2);
update = pstate2.executeUpdate();//返回值代表受到影响的行数
if (update>0) {
    System.out.println("修改成功");
}
//-----------------------------------------------------------------------//		
con.commit();//事务提交
			
连接池

第三方的连接池:dbcp c3p0

package com.sum.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class JDBCUtils {
	private static String url = "jdbc:mysql://localhost:3306/cakeshop?userUnicode=true&characterEncoding=UTF8";
	private static String root = "root";
	private static String sql_password = "123456";
	// 创建连接池
	private static ArrayList<Connection> conList = new ArrayList<Connection>();
	static {
		for (int i = 0; i < 5; i++) {
			conList.add(creatConnection());
		}
	}
	// 创建连接
	public static Connection getConnection() {
		if (conList.isEmpty() == false) {
			Connection con = conList.get(0);
			conList.remove(con);
			return con;
		} else {
			return creatConnection();
		}
	}
	
	// 创建连接
	private static Connection creatConnection() {
		// 加载驱动
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			return DriverManager.getConnection(url,root,sql_password);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	// 关闭连接
	public static void closeAll(ResultSet rs, PreparedStatement state, Connection con) {
		
		closeResultSet(rs);
		closePreparedStatement(state);
		closeConnection(con);
		
	}
	
	// 关闭连接
	public static void closeAll(ResultSet rs, PreparedStatement state1, PreparedStatement state2, Connection con) {
		
		closeResultSet(rs);
		closePreparedStatement(state1);
		closePreparedStatement(state2);
		closeConnection(con);
		
	}
	private static void closeResultSet(ResultSet rs) {
		try {
			if (rs!=null) rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	private static void closePreparedStatement(PreparedStatement state) {
		try {
			if (state!=null) state.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	private static void closeConnection(Connection con) {
//		try {
//			if (con!=null) con.close();
//		} catch (SQLException e) {
//			e.printStackTrace();
//		}
		conList.add(con);//归还连接
	}
	
	
}

c3p0-config

使用c3p0-config.xml文件进行快速连接数据库

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="jdbcUrl">
			<![CDATA[jdbc:mysql://localhost:3306/数据库名称?useUnicode=true&characterEncoding=UTF-8&useSSL=true]]>
		</property>
		<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
		<property name="user">root</property>
		<property name="password">用户密码</property>
		<property name="checkoutTimeout">30000</property>
		<property name="idleConnectionTestPeriod">30</property>
		<property name="initialPoolSize">10</property>
		<property name="maxIdleTime">30</property>
		<property name="maxPoolSize">100</property>
		<property name="minPoolSize">10</property>
		<property name="maxStatements">200</property>
	</default-config>
</c3p0-config>
c3p0连接池

需要引入c3p0和

package com.sum.jdbc;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0DateSource {
	private static String url = "jdbc:mysql://localhost:3306/cakeshop?userUnicode=true&characterEncoding=UTF8";
	private static String root = "root";
	private static String sql_password = "123456";
	
	private static ComboPooledDataSource ds;
	
	static {
		ds=new ComboPooledDataSource();
		try {
			ds.setDriverClass("com.mysql.cj.jdbc.Driver");
			ds.setJdbcUrl(url);
			ds.setUser(root);
			ds.setPassword(sql_password);
			
			ds.setInitialPoolSize(5);
			ds.setMaxPoolSize(20);
			ds.setMinPoolSize(1);
			
			
		} catch (PropertyVetoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static Connection getConnection() {
		try {
			return ds.getConnection();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	// 关闭连接
		public static void closeAll(ResultSet rs, PreparedStatement state, Connection con) {
			
			closeResultSet(rs);
			closePreparedStatement(state);
			closeConnection(con);
			
		}
		
		// 关闭连接
		public static void closeAll(ResultSet rs, PreparedStatement state1, PreparedStatement state2, Connection con) {
			
			closeResultSet(rs);
			closePreparedStatement(state1);
			closePreparedStatement(state2);
			closeConnection(con);
			
		}
		private static void closeResultSet(ResultSet rs) {
			try {
				if (rs!=null) rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		private static void closePreparedStatement(PreparedStatement state) {
			try {
				if (state!=null) state.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		private static void closeConnection(Connection con) {
			try {
				if (con!=null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	
}

【数据库连接池】使用dbutils和c3p0-config

快速配置数据库连接池,缺点事物的时候需要自己引入connection

使用dbutils的jar包

操作数据库的工具类

package com.sum.study;

import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapHandler;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.sun.org.apache.bcel.internal.generic.NEW;

public class TestQueryRunner {
	
	public static void main(String[] args) throws Exception{
		DataSource ds = new ComboPooledDataSource();//使用c3p0数据源
		// 生成工具类对象
		QueryRunner runner = new QueryRunner(ds);
		
		String sql = "select * from goods where id=?";
		// 把返回的数据处理成一个map集合,key是列名,value是id=3的列值
		Map<String, Object> map = runner.query(sql, new MapHandler(),3);
		// 遍历map
		for(String key:map.keySet()) {
			System.out.println(key+":"+map.get(key));
		}
		
	}
	
	
}

DBUtil查询操作
创建DBUtil工具类

创建DataSource对象

package com.sum.utils;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DBUtil {
	private static DataSource dsDataSource = new ComboPooledDataSource();
	
	public static DataSource getDataSource() {
		return dsDataSource;
	}
}
创建QueryRunner对象
package com.sum.dao;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.sum.model.Goods;
import com.sum.utils.DBUtil;

public class GoodsDao {
	QueryRunner r = new QueryRunner(DBUtil.getDataSource());
	//select g.id,g.name,g.cover,g.price,t.name typename from type t,recommend r,goods g where type=2 and r.goods_id=g.id and r.type=t.id;
	
}

MapHandler

返回一个Map对象

// 条幅商品查询
public Map<String, Object> getScrollGoods() throws SQLException {
		String sql = "select g.id,g.name,g.cover,g.price from recommend r,goods g where type=1 and r.goods_id=g.id";
		return r.query(sql, new MapHandler());
	}
MapListHandler

返回一个Map组成的List

public List<Map<String, Object>> getGoodsList(int recommendType) throws SQLException {
		String sql = "select g.id,g.name,g.cover,g.price,t.name typename from type t,recommend r,goods g where type=? and r.goods_id=g.id and r.type=t.id";
		return r.query(sql, new MapListHandler(),recommendType);
	}
BeanListHandler

返回一个对象的集合

数据库中的所有字段必须和返回的对象的字段一一对应

	// 查询全部类型的所有商品
	public List<Goods> selectAllTypeGoods(int pageNo,int pageSize) throws SQLException {
		String sql ="select * from goods limit ?,?";
		return r.query(sql,new BeanListHandler<Goods>(Goods.class),(pageNo-1)*pageSize,pageSize);
	}
	// 查询某个类型的所有商品
	public List<Goods> selectOneTypeGoods(int typeId,int pageNo,int pageSize) throws SQLException {
		String sql ="select * from goods g where type_id=?  limit ?,?";
		return r.query(sql,new BeanListHandler<Goods>(Goods.class),typeId,(pageNo-1)*pageSize,pageSize);
	}
ScalarHandler

注意返回只是Long对象

用来获取查询的个数与SQL语句count配合使用

// 查询某个系列商品个数
	public int selectOneTypeGoodsCount(int typeId) throws SQLException {
		String sql ="select count(*) from goods where type_id = ?";
		Long query = r.query(sql,new ScalarHandler<Long>(),typeId);
		if (query == null) {
			return 0;
		}
		return query.intValue();
	}
	
	// 查询所有商品个数
	public int selectAllTypeGoodsCount() throws SQLException {
		String sql ="select count(*) from goods";
		Long query = r.query(sql,new ScalarHandler<Long>());
		if (query == null) {
			return 0;
		}
		return query.intValue();
	}
创建QueryRunner的两种方式
自动引入connection

可以自动关闭connection

// ds提供数据源,ds.connection
DataSource ds = new ComboPooledDataSource();//使用c3p0数据源
QueryRunner runner = new QueryRunner(ds);
手动引入connnection

事务的时候用到

// 不提供数据源的方式
DataSource ds = new ComboPooledDataSource();//使用c3p0数据源
QueryRunner runner = new QueryRunner();
Connection connection = ds.getConnection();
String sql = "delete * from goods where id=?";
runner.update(connection,sql,2);//指定connection的方式,进行数据库操作
DbUtils.closeQuietly(connection);//关闭connection

SSH框架

框架简单的来说就是半成品,通过半成品可以更快的开发项目

Struts

基本用法

用来代替servlet

导入jar

在xml中配置filter,在struts2-core-2.5.16.jar库中找到org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter

启动Struts

在xml中配置访问Struts路径,用来启动Struts

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>StrutsForum</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>struts</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>struts</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
  
</web-app>
核心配置Struts.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <!-- name:配置包名 -->
	<package name="Mypackage" namespace="/虚拟根目录" extends="struts-default">
		<!-- 
		action 标签的属性:
            name 是访问虚拟根目录下的资源名称 loginAction ,和servlet中的@WebServlet注解一样
            classs 是java代码存放的地方
            method 是result标签需要接收的string返回值的方法
         result 标签的属性:  
			name 接收method的返回值为该值时,执行跳转
			type 是重定向的时候用到
		-->
		<action name="loginAction" class="com.sum.web.UserAction" method="execute">
			<result name="success" type="redirect">/index.html</result>
			<result name="error" type="redirect">/login.jsp</result>
		</action>	
	</package>
</struts>
Struts重定向

在result标签中增加type="redirect"属性即可重定向

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <!-- name:配置包名 -->
	<package name="Mypackage" namespace="/" extends="struts-default">
		<action name="loginAction" class="com.sum.web.UserAction" method="execute">
			<result name="success" type="redirect">/index.html</result>
			<result name="error" type="redirect">/login.jsp</result>
		</action>	
	</package>
</struts>

创建Action

action和servlet很像

package com.sum.web;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sum.domain.User;
import com.sum.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User>{
	
	public User user = new User();
	
	public String execute() throws Exception {
		
		System.out.println("=====================");
		
		UserService uService = new UserService();
		boolean r = uService.findUser(user);
		if (r) {
			return "success";
		}else {
			ServletActionContext.getRequest().setAttribute("error", "用户名密码错误");
			return "error";
		}
	}

	@Override
	public User getModel() {
		return user;
	}
	
	
	
}

动态方法调用配置

2个constant

一个global-allowed-methods

2个action属性 name=“loginAction_*” 属性method="{1}"

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!-- Struts2新特性,为了增加安全性 ,需要告诉Struts2需要动态方法调用-->
	<constant name="struts.devMode" value="true"></constant>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
    <!-- name:配置包名 -->
	<package name="Mypackage" namespace="/user" extends="struts-default">
		<!-- 配置动态方法变量 -->
		<global-allowed-methods>login,register</global-allowed-methods>
		<!-- 配置动态方法变量 -->
		<action name="loginAction_*" class="com.sum.web.UserAction" method="{1}">
			<!-- 默认请求转发 -->
			<result name="success" type="redirect">/index.html</result>
			<result name="error" type="redirect">/login.jsp</result>
		</action>	
	</package>
</struts>
action之间的请求转发
<action name="defaultAction" class="com.sum.web.DefaultAction" method="execute">
<!-- 
result 属性name为发起转发的action的method的返回值,即defaultAction的execute的返回值为impl
	   属性type="chain",
<result name="impl" type="chain">另一个action标签的name值</result>
-->
	<result name="impl" type="chain">implAction</result>
</action>
<action name="implAction" class="com.sum.web.ImplAction" method="execute"></action>
action之间的重定向
<action name="defaultAction_*" class="com.sum.web.DefaultAction" method="{1}">
    <!-- action之间的请求转发 -->
    <result name="implAction" type="chain">implAction</result>
    <!-- action之间的重定向到actionName loginAction_* -->
    <result name="toLogin" type="redirectAction">
        <param name="actionName">loginAction_login</param>
        <param name="username">${username}</param>
        <param name="password">${password}</param>
	</result>
</action>
参数接收
方式1:属性驱动
public String username;
public String password;
package com.sum.web;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sum.domain.User;
import com.sum.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User>{
	
	public String username;
	public String password;
	public String login() throws Exception {
		// 这里直接获取username和password即可
        syso(username:password)
	}

    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;
    }

}

方式2:模型驱动===最好用的方式
package com.sum.web;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sum.domain.User;
import com.sum.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User>{
	
	public User user = new User();
	public String login() throws Exception {
		//直接使用user对象即可
        syso(user.getUsername():user.getPassword())
	}
	@Override
	public User getModel() {
		return user;
	}

}
参数传递
ActionContext.getContext()

request,response,servletContext,request域,session域,application域,attr域,param域

生命周期符合木桶原理,和request保持一致

ActionContext.getContext().put("username",	"sum");
ActionContext.getContext().put("password",	"123");

Map<String, Object> session = ActionContext.getContext().getSession();
session.put("mySession", "这是session域");

Map<String, Object> application = ActionContext.getContext().getApplication();
application.put("myApplication", "这是application域");
ServletActionContext

可以获取原生的域对象

ServletActionContext.getRequest()

ServletActionContext.getRequest().setAttribute("username",	"sum");
ServletActionContext.getRequest().setAttribute("password",	"123");
与servlet的对比
启动
servlet:无

Struts:配置filter
创建
servlet:继承Httpservlet,
    	重写doget或dopost,
        添加注解或配置xml

Struts:继承ActionSupport 
    	实现ModelDriven接口,
    	写一个返回值为String且抛出异常
    	配置xml:如下
<struts>
    <!-- name:配置包名 -->
	<package name="Mypackage" namespace="/" extends="struts-default">
		<action name="loginAction" class="com.sum.web.UserAction" method="execute">
			<!-- 默认请求转发 -->
			<result name="success" type="redirect">/index.html</result>
			<result name="error" type="redirect">/login.jsp</result>
		</action>	
	</package>
</struts>
封装数据
servlet:
    需要引入commons-beanutils-1.8.3.jar包
    根据BeanUtils工具通过name封装,
    BeanUtils.populate(user,request.getParameterMap());(先把对象new出来)
	
Struts:
    不需要引入包  
    实现ModelDriven接口
    实现getModel方法,返回一个对象就是我们封装的数据对象(先把对象new出来)
转发与重定向
servlet:
 	response.sendRedirect(request.getContextPath() + "/index.html");
	request.getRequestDispatcher("/login.jsp");
Struts:通过添加属性来重定向,默认请求转发 type="redirect"
    <!-- 默认请求转发 -->
    <result name="success" type="redirect">/index.html</result>
    <result name="error" type="redirect">/login.jsp</result>

ognl表达式

流程
引入
<%@ taglib uri="/struts-tags" prefix="s"%>
相关标签
// 遍历
<s:iterator value="pasteList" var="paste">
    <div class="dvques">
        <div class="quesCount">
            <div class="count"> 
                // 获取属性值
                <s:property value="ansnum"/> 
            </div>
             // 条件判断                  
            <s:if test="ansnum%2==0">
                张大志
            </s:if>
            <s:else>
                孙傲
            </s:else>
            <div class="liulan">浏览(9) 30分钟前</div>
             
        </div>
</s:iterator>

创建拦截器

类似于filter

方式1:继承方式
package com.sum.intercept;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

public class UserIntercept extends MethodFilterInterceptor{

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {

		Map<String, Object> session = ActionContext.getContext().getSession();
		Object user = session.get("user");
		if (user!=null) {
			return invocation.invoke();
		}else {
			return "index";
		}
		
	}
	
}

方式2:实现接口方式
package com.sum.intercept;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class Intercept implements Interceptor{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		// 放行
		return invocation.invoke();
	}
	
}

配置拦截器

必须在package中配置

拦截器只能控制访问action

不能控制访问jsp页面

<!-- 配置拦截器 -->
<interceptors><!-- 注册拦截器 -->
<interceptor name="myIntercept" class="com.sum.intercept.MyIntercept"></interceptor>
<!-- 注册拦截栈 -->
<interceptor-stack name="myStack">
<!-- 引入自己创建的拦截器栈 -->
<interceptor-ref name="myIntercept">
<!-- 不拦截login方法 -->
<param name="excludeMethods">login</param>
</interceptor-ref>
<!-- 引入Struts给你写好的拦截器栈(20) -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 指定包中的默认拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<!-- 配置全局结果集 -->
<global-results>
			<result name="tologin" type="redirect">head.jsp</result>
</global-results>
完整版
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!-- Struts2新特性,为了增加安全性 ,需要告诉Struts2需要动态方法调用-->
	<constant name="struts.devMode" value="true"></constant>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
    <!-- name:配置包名 -->
	<package name="Mypackage" namespace="/" extends="struts-default">
		
		<!-- 配置拦截器 -->
		<interceptors>
			<!-- 注册拦截器 -->
			<interceptor name="myIntercept" class="com.sum.intercept.MyIntercept"></interceptor>
			<!-- 注册拦截栈 -->
			<interceptor-stack name="myStack">
				<!-- 引入自己创建的拦截器栈 -->
				<interceptor-ref name="myIntercept">
					<param name="excludeMethods" >login</param>
				</interceptor-ref>
				<!-- 引入Struts给你写好的拦截器栈(20) -->
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		<!-- 指定包中的默认拦截器栈 -->
		 <default-interceptor-ref name="myStack"></default-interceptor-ref>
		
		<global-results>
			<result name="toLogin" type="redirect">/login.jsp</result>
		</global-results>
		
		<!-- 配置动态方法变量 -->
		<global-allowed-methods>regex:.*</global-allowed-methods>
		<!-- 配置动态方法变量 -->
		
		<!-- 配置Action以及动态方法 -->
		<action name="loginAction_*" class="com.sum.web.UserAction" method="{1}">
			<!-- 默认请求转发 -->
			<result name="success" type="redirect">PasteAction_getAllPaste</result>
			<result name="error" type="redirect">/login.jsp</result>
		</action>	
		
		<!-- <action name="registerAction" class="com.sum.web.UserAction" method="register">
			默认请求转发
			<result name="success" type="redirect">/index.html</result>
			<result name="error" type="redirect">/login.jsp</result>
		</action>	 -->
		
		<action name="defaultAction_*" class="com.sum.web.DefaultAction" method="{1}">
			<!-- action之间的请求转发 -->
			<result name="implAction" type="chain">implAction</result>
			<!-- action之间的重定向到actionName loginAction_* -->
			<result name="toLogin" type="redirectAction">
				<param name="actionName">loginAction_login</param>
				<param name="username">${username}</param>
				<param name="password">${password}</param>
			</result>
		</action>
		<action name="implAction" class="com.sum.web.ImplAction" method="execute">
			<result name="defaultAction" type="chain">defaultAction_login</result>
		</action>
	</package>
	
	<package name="PastePackage" namespace="/" extends="struts-default">
		<global-allowed-methods>regex:.*</global-allowed-methods>
		<action name="PasteAction_*" class="com.sum.web.PasteAction" method="{1}">
			<result name="index" type="">/index.jsp</result>
		</action>
	</package>
	
</struts>

Hibernate

用来代替c3p0和dbutils,在Dao层

方便的操作数据库

hibernate配置

  1. 创建hibernate.cfg.xml
  2. 配置驱动、数据库url、用户名、密码
  3. 数据库方言
  4. 将sql显示在控制台
  5. 配置自动生成数据库表
  6. 添加实体映射
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
	
<hibernate-configuration>
	<!-- 负责初始化 -->
	<session-factory>
		<!-- 连接数据库驱动 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<!-- 数据库地址 -->
		<property name="hibernate.connection.url">jdbc:mysql:///study</property>
		<!-- 数据库用户名 -->
		<property name="hibernate.connection.username">root</property>
		<!-- 数据库密码 -->
		<property name="hibernate.connection.password">123456</property>
		<!-- 配置数据库方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL57InnoDBDialect</property>
		
		<!-- 将sql显示在控制台 -->
		<property name="hibernate.show_sql">true</property>
		<!-- 格式化hibernate生成sql语句 -->
		<property name="hibernate.format_sql">true</property>
		<!-- 配置hibernate自动创建表
			create: 自动创建表,每次框架运行都会创建一张新的表,原来的数据将丢失(开发时使用)			
			create-drop: 自动建表每次框架运行结束都会将所有表删除.(开发环境中测试使用)
			update(推荐): 自动生成表,如果表已经存在则更新数据,如果表不存在则创建表
			validate:
			-->
		<property name="hibernate.hbm2ddl.auto">update</property>
		
		
		<!-- 映射hbm文件 -->
		<mapping resource="com/sum/model/User.hbm.xml"/>
	
	</session-factory>
</hibernate-configuration>

配置实体xml

配置实体相关属性,每个属性对应数据库中的字段。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
	
<hibernate-mapping>
	<class name="com.sum.model.User" table="user" >
		<!-- id标签 
			name:实体中的属性
			column(可选):数据库中的列名
			type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
					     每个类型有三种填法:java类型|hibernate类型|数据库类型
			length(可选):配置数据库中列的长度.
						默认值:使用数据库类型的最大长度
			
		 -->
		<id name="iduser" column="iduser"  >
			<!-- 主键生成策略 -->
			<generator class="assigned"></generator>
		</id>
		
		<!-- 
			property:除了id之外的普通属性
					name:实体中的属性
					column(可选):数据库中的列名
					type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
					     	     每个类型有三种填法:java类型|hibernate类型|数据库类型
					length(可选):配置数据库中列的长度.
								默认值:使用数据库类型的最大长度
		 -->
		<property name="username" column="username"></property>
		<property name="password" column="password"></property>
		<property name="name" column="name"></property>
		<property name="email" column="email"></property>
		<property name="phone" column="phone"></property>
	</class>
</hibernate-mapping>

与c3p0和dbutils对比

创建
c3p0

c3p0-config.xml

配置驱动、数据库url、用户名、密码

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="jdbcUrl">
			<![CDATA[jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=UTF-8&useSSL=true]]>
		</property>
		<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
		<property name="user">root</property>
		<property name="password">123456</property>
		<property name="checkoutTimeout">30000</property>
		<property name="idleConnectionTestPeriod">30</property>
		<property name="initialPoolSize">10</property>
		<property name="maxIdleTime">30</property>
		<property name="maxPoolSize">100</property>
		<property name="minPoolSize">10</property>
		<property name="maxStatements">200</property>
	</default-config>
</c3p0-config>
添加实体:
hibernate

需要实体与表的映射文件xxx.hbm.xml

需要配置属性与字段的对应,添加主键生成策略

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
	
<hibernate-mapping>
	<class name="com.sum.model.User" table="user" >
		<id name="iduser" column="iduser" >
			<!-- 主键生成策略 -->
			<generator class="assigned"></generator>
		</id>
		<property name="username" column="username"></property>
		<property name="password" column="password"></property>
		<property name="name" column="name"></property>
		<property name="email" column="email"></property>
		<property name="phone" column="phone"></property>
	</class>
</hibernate-mapping>
c3p0

操作数据库:
hibernate

不需写sql语句

package com.sum.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.sum.model.User;

public class UserDao {
	
	
	public void addUser(User user) {
		// 使用hibernate
		// 得到配置信息
		Configuration cf = new Configuration().configure();
		// 创建sessionFactiory对象
		SessionFactory sFactory = cf.buildSessionFactory();
		// 获得session
		Session session = sFactory.openSession();
		// 打开事务
		Transaction beginTransaction = session.beginTransaction();
		// 存储user对象
		session.save(user);
		// 提交事务
		beginTransaction.commit();
		// 关闭资源
		session.close();
	}

}

c3p0和dbutils

通过QueryRunner和ComboPooledDataSource获取连接池

package com.sum.dao;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.sum.domain.User;

public class UserDao {
	// 创建连接池
	private QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
	public User findUser(User user) throws SQLException {
		String sql="select * from user where username=? and password=?";
		return runner.query(sql, new BeanHandler<User>(User.class),user.getUsername(),user.getPassword());
	}

}

配置

数据结构与算法

什么是算法

算法是用于解决特定问题的一系列执行步骤

使用不同的算法,解决同一个问题,效率可能相差非常大

比如:求第N个斐波那契数(fibonacci number)

package com.mj;

import javax.xml.transform.Templates;

public class Main {

	/*
	 * 0 1 1 2 3 5 8 13 .....
	 * 
	 * 
	 */
	
	/*性能极差*/
	public static int fib(int n) {
		if (n<=1) return n;
		return fib(n-1)+fib(n-2);
	}
	/*性能完美*/
	public static int fib2(int n) {
		int first = 0;
		int second = 1;
		for (int i = 0; i < n-1; i++) {
			int temp = first;
			first = second;
			second = temp+second;
		}		
		return second;
	}
	
	public static void main(String[] args) {
		System.out.println(fib2(64));	
		
	}

}

评估算法

正确性,可读性,健壮性(对不合理输入的反应能力和处理能力)

时间复杂度

估算程序指令的执行次数(执行时间)

空间复杂度

估计所需占用的存储空间

大O表示法

时间复杂度和空间复杂度

低阶的部分直接省略

常数阶: 忽 略 常 数 > > O ( 1 ) ; 忽略常数>>O(1); >>O(1);对应无循环

system.out.println("..");

线性阶: 2 n + 3 > > O ( n ) ; 2n+3>>O(n); 2n+3>>O(n); 一个循环n次的代码+一个有限的代码

for(int i=0;i<n;i+=i){
    system.out.println("..");
}

平方阶: n ² + 2 n + 3 > > O ( n ² ) ; n²+2n+3>>O(n²); n²+2n+3>>O(n²);两个嵌套循环n的代码

for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
    	system.out.println("..");
	}
}

立方阶: 4 n ³ + n ² + 2 n + 3 > > O ( n ³ ) 4n³+n²+2n+3>>O(n³) 4n³+n²+2n+3>>O(n³) 三个循环n次的代码

for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
    	for(int k=0;k<l;k++){
            system.out.println("..");
        }
	}
}

对数阶一般省略底数, l o g 2 n log_2n log2n l o g 8 n log_8n log8n统称 l o g n logn logn

对数阶: l o g ₂ n = l o g ₂ 9 ∗ l o g 9 n > > O ( l o g n ) log₂n = log₂9*log_9n>>O(logn) logn=log9log9n>>O(logn) 循环条件为: i < n , i = 2 i ; n = 2 n i<n,i = 2i; n = 2^n i<n,i=2i;n=2n

for(int i=0;i<n;i+=i){
    system.out.println("..");
}

nlogn阶: n l o g ₂ n > > O ( n l o g n ) nlog₂n >>O(nlogn) nlogn>>O(nlogn)

for(int i=0;i<n;i++){
    for(int i=0;i<m;i+=i){
        system.out.println("..");
    }
}

指数阶: 2 n > > O ( 2 n ) 2^n>>O(2^n) 2n>>O(2n)


O ( 1 ) < O ( l o g n ) < O ( n ) < O ( n l o g n ) < O ( n ² ) < O ( n ³ ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2^n)<O(n!)<O(n^n) O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2n)<O(n!)<O(nn)

算法网站

https://leetcode-cn.com/problemset/algorithms/

线性表

动态数组

特点:增改查复杂度为O(1),增加数据如果需要扩容复杂度是O(n)

缺点:添加数据需要扩容O(n),插入删除数据复杂度为O(1~n)

链表

特点:增删改查,O(1~n),不需要扩容,节省内存

循环链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

语音不识别

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值