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}¤ttype=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配置
- 创建hibernate.cfg.xml
- 配置驱动、数据库url、用户名、密码
- 数据库方言
- 将sql显示在控制台
- 配置自动生成数据库表
- 添加实体映射
<?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) log₂n=log₂9∗log9n>>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) nlog₂n>>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),不需要扩容,节省内存
循环链表