目录
9.JavaBean
实体类:
javaBean有特定写法:
- 必须有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来和数据库的字段做映射 ORM !
ORM:对象关系映射
- 表--->类
- 字段-->属性
- 行-->对象
People表:
id | name | age | address |
1 | 小步 | 15 | 湖北省 |
2 | 小黑 | 14 | 黑龙江 |
3 | 小白 | 12 | 白灵市 |
对应映射的类:
public class People{
private int id;
private String name;
private int age;
private String address;
}
jsp:useBean标签:
<%
People people = new People(1, "小步", 15, "湖北省");
%>
<%--该标签等价于上面的对象--%>
<jsp:useBean id="people" class="com.tang.pojo.People" scope="page"/>
<%-- 相当于给对象赋值 --%>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="name" property="id" value="小步"/>
<jsp:setProperty name="age" property="id" value="15"/>
<jsp:setProperty name="people" property="address" value="湖北"/>
i d:<jsp:getProperty name="people" property="id"/>
姓名:<jsp:getProperty name="people" property="name"/>
年龄:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>
10.MVC三层架构
什么是mvc? Model view Controller 模型,视图,控制器
10.1早些年的架构:
用户直接访问控制层,控制层就可以直接访问数据库;
Servlet--CRUD(增删改查)-->数据库
弊端:
程序十分臃肿不利于维护
Servlet的代码中:处理请求,响应,视图跳转,处理JDBC,处理业务代码,处理逻辑代码
架构:没有什么是加一层解决不了的
10.2MVC三层架构:
Model:
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD(Dao)
View:
- 展示数据
- 提供链接发起Servlet请求
Controller(Servle):
- 接收用户的请求(req:请求参数,Session信息...)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录-->接收用户的登录请求-->处理用户的登录请求(获取用户登录数:username,password)--> 交给业务层处理登录业务(判断用户名密码是否正确:事务)-->Dao层查询用户名密码是否正确-->数据库
11.Filter(重点)
Filter:过滤器,用来过滤网站的数据;
- 处理中文乱码
- 登录验证....
Filter开发步骤
- 导包
- 编写过滤器
- 导包不要错
- 实现Filter接口重写对应的方法
package com.example.filter; import jakarta.servlet.*; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; public class CharacterEncodingFilter implements Filter { //初始化:当web对象启动的时候就启动初始化,随时等待过滤对象 @Override public void init(FilterConfig filterConfig) throws ServletException { try { System.out.println(URLDecoder.decode("CharacterEncodingFilter初始化", "GB2312")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } /** * 过滤 * filterChain:过滤中的所有代码,在过滤特定请求的时候都会执行 * 必须要让过滤器继续同行 */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //设置编码 servletRequest.setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8"); System.out.println("filterChain过滤前..."); filterChain.doFilter(servletRequest, servletResponse);//让程序继续走,如果不写程序到这里被拦截,停止! System.out.println("filterChain过滤后..."); } //销毁:当web对象结束的时候才会销毁 @Override public void destroy() { try { System.gc();//通知垃圾回收站去清理垃圾 System.out.println(URLDecoder.decode("CharacterEncodingFilter销毁", "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }
- 导包不要错
4.配置对应过滤器xml
<!-- 过滤 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.example.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
12.监听器:
实现监听器的接口有N中如可以监听Session的会话创建,进行判断网站在线人数如:
package com.example.listener;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
//统计网站在线人数,统计session
public class OnlineCountListener implements HttpSessionListener {
//会话创建的时候,触发请求
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("进入OnlineCountListener进入的SessionId为:"+se.getSession().getId());
ServletContext servletContext = se.getSession().getServletContext();
Integer number_of_people =(Integer) servletContext.getAttribute("NumberOfPeople");
if (number_of_people==null){
number_of_people= 1;
}else {
int come = number_of_people;
number_of_people= come + 1;
}
servletContext.setAttribute("NumberOfPeople",number_of_people);
}
/**
* 回忆:
* Session销毁的两种情况
* 1.手动销毁:se.getSession().invalidate();
* 2.自动销毁:在mxl设置Session销毁时间
*/
//会话结束的时候,触发请求
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("结束OnlineCountListener");
ServletContext servletContext = se.getSession().getServletContext();
Integer number_of_people=(Integer)servletContext.getAttribute("NumberOfPeople");
if (number_of_people==null){
number_of_people=0;
}else {
number_of_people-=1;
}
servletContext.setAttribute("NumberOfPeople",number_of_people);
}
}
XML配置:
<!-- 注册监听 -->
<listener>
<listener-class>com.example.listener.OnlineCountListener</listener-class>
</listener>
<!-- 设置会话过期时间 分钟为单位-->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
13过滤器监听器常见应用
监听器:GUI编程中经常使用;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class test1 {
public static void main(String[] args) {
Frame frame = new Frame();
Panel panel = new Panel();
frame.setSize(1000,1000);
frame.setBackground(new Color(0,255,0));
frame.add(panel);
frame.setVisible(true);
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println("窗口打开");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口关闭1" );
//0正常退出,1异常退出
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("窗口关闭2");
}
@Override
public void windowIconified(WindowEvent e) {
System.out.println("窗口最小化");
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println("窗口从最小化打开");
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("窗口已激活");
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("窗口暂停使用");
}
});
}
}
用户登录之后才能进入主页!用户注销后就不能进入主页了!
- 用户登录后向Sesison放入用户的信息
- 进入主页的时候触发过滤器进行判断用户是否已经登录如:
package com.example.filter; import com.example.util.Constant; import jakarta.servlet.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class MainFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("启动过滤..."); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse; System.out.println("进入过滤器"); if (req.getServletContext().getAttribute(Constant.USER_SESSION)==null){ System.out.println("过滤成功..."); resp.sendRedirect("/r/Login.jsp"); } filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { System.out.println("结束过滤..."); } }
JDBC复习:
需要jar包的支持:
- java.SQL
- javax.SQL
- mysql-conneter-java... 链接驱动(必须要导入)
package com.example.TestJDBC;
import com.mysql.jdbc.Driver;
import java.sql.*;
public class TestJDBC {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
String url="jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai";
String username="root";
String password="98526";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.链接数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.创建预编译的对象进行编译
PreparedStatement preparedStatement = connection.prepareStatement("select * from users");
//4.执行sql代码返回结果集
ResultSet resultSet = preparedStatement.executeQuery();
//5.遍历结果集
while (resultSet.next()){
System.out.println(resultSet.getString("name"));
}
}
}
JDBC固定步骤:
- 加载驱动!
- 链接数据库,代表数据库
- 向数据库发送sql对象
- 编写sql
- 执行sql
- 关闭链接
事务复习:
要么都成功,要么都失败!
ACLD原则:原子性,一致性,隔离性,持久性(保证数据的安全)
开启事务 事务提交 事务回滚 关闭事务 如: 转账: A:1000元 B:1000元 A(900元) --转账100元--> B(1100元)
package com.example.TestJDBC;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TestJDBC2 {
@Test
void test() throws ClassNotFoundException, SQLException {
//配置信息
String url="jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai";
String username="root";
String password="98526";
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//链接数据库
Connection connection = DriverManager.getConnection(url, username, password);
//通知数据库开启事务(关闭自动提交)
connection.setAutoCommit(false);
String sql1="update accout set money=money-100 where name='A'";
String sql2="update accout set money=money+100 where name='B'";
PreparedStatement preparedStatement = connection.prepareStatement(sql1);
PreparedStatement preparedStatement1 = connection.prepareStatement(sql2);
try {
int i = preparedStatement.executeUpdate();
int i1 = preparedStatement1.executeUpdate();
if (i!=0&&i1!=0){
//提交
connection.commit();
}else {
//回滚
connection.rollback();
}
} catch (SQLException e) {
System.err.println("转账出错...");
//回滚
connection.rollback();
}finally {
//关闭链接
preparedStatement.close();
preparedStatement1.close();
connection.close();
//开启自动提交事务
connection.setAutoCommit(true);
}
}
}
Junit单元测试:
所需依赖:
<!-- junit依赖 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
简单使用:@Test该注解只能在方法和泛型上使用,加了该注解可直接运行方法里的区域如:
@Test
void test(){
System.out.println("帅");
}