JavaWeb-03

9、JavaBean

实体类

JavaBean有特定的写法:

  • 必须有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法

一般用来和数据库的字段做映射 ORM;

ORM:对象关系映射

  • 表 —> 类
  • 字段 —> 属性
  • 行记录 —> 对象

people表

idname阿格拉玛address
1王木1号14杭州
2王木2号23苏州
3王木3号22南京
class People {
    private int id;
    private String name;
    private int age;
    private String address;
    
}
Class A {
    new People(1,"王木1号",14,"杭州");
    new People(2,"王木2号",23,"苏州");
    new People(3,"王木3号",22,"南京");
}

10、MVC三层架构

什么是MVC:Model View Controller 模型、视图、控制器

10.1 早些年在这里插入图片描述

用户直接访问控制层,控制层可以直接操作数据库;

servlet -- CRUD-->数据库
弊端:程序十分臃肿,不利于维护     Servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
    
架构:没有什么是加一层解决不了的!
程序员调用
|
JDBC
|
MySQL ORacle SQLServer……

10.2 MVC三层架构在这里插入图片描述

Model

  • 业务处理:业务逻辑(Service)
  • 数据持久层:CRUD (Dao)

View

  • 展示数据
  • 提供链接发起Servlet请求(a,form,img……)

Controller

  • 接收用户的请求:(req:请求参数、Session信息……)

  • 交给业务层处理相应的代码

  • 控制视图的跳转

    登录--->接收用户的登录请求登录--->处理用户的请求(获取用户登录的参数,username,password)--->交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确--->数据库
    

11、Filter(重点)

Filter:过滤器,用来过滤网站的数据;

  • 处理中文乱码
  • 登录验证……
    在这里插入图片描述
    pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.kuang</groupId>
    <artifactId>javaweb-filter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--Servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <!--JSP依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>
        <!--JSTL表达式依赖-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--standard标签库-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!--连接数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
    </dependencies>
</project>

Filter开发步骤:

  1. 导包

  2. 编写过滤器

    1. 导包不要导错 在这里插入图片描述

    2. 实现Filter接口,重写对应的方法即可

      public class CharacterEncodingFilter implements Filter {
          // 初始化:web服务器启动,就已经初始化了,随时等待过滤对象出现
          public void init(FilterConfig filterConfig) throws ServletException {
              System.out.println("CharacterEncodingFilter初始化...");
          }
      
          // chain:链
          /*
          * 1. 过滤中的所有代码,在过滤特定请求的时候都会执行
          * 2. 必须要让过滤器继续通行
          *   chain.doFilter(request,response);
          * */
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              request.setCharacterEncoding("utf-8");
              response.setCharacterEncoding("utf-8");
              response.setContentType("text/html;charset=UTF-8");
              System.out.println("CharacterEncodingFilter执行前");
              chain.doFilter(request,response); // 让我们的请求继续走,如果不写,程序到这里就被拦截停止!
              System.out.println("CharacterEncodingFilter执行后");
          }
          // 销毁:web服务器关闭的时候,过滤器会销毁
          public void destroy() {
              System.out.println("CharacterEncodingFilter销毁...");
          }
      }
      
  3. 在web.xml中配置Filter

        </filter>
        <filter-mapping>
            <filter-name>CharacterEncodingFilter</filter-name>
            <!--只要是/servlet的任何请求,都会经过这个过滤器-->
            <url-pattern>/servlet/*</url-pattern>
        </filter-mapping>
    

12、监听器

实现一个监听器的接口

  1. 编写一个监听器

    实现监听器的接口

    // 统计网站在线人数:统计session
    public class OnlineCountListener implements HttpSessionListener {
        // 创建session监听
        // 一旦创建session,就会触发一次这个事件
        public void sessionCreated(HttpSessionEvent se) {
            ServletContext ctx = se.getSession().getServletContext();
    
            System.out.println(se.getSession().getId());
            Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
    
            if (onlineCount == null) {
                onlineCount = new Integer(1);
            } else {
                int count = onlineCount.intValue();
                onlineCount = new Integer(count + 1);
            }
    
            ctx.setAttribute("OnlineCount",onlineCount);
        }
    
        // 销毁session监听
        // 一旦销毁session,就会触发一次这个事件
        public void sessionDestroyed(HttpSessionEvent se) {
            ServletContext ctx = se.getSession().getServletContext();
            Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
    
            if (onlineCount == null) {
                onlineCount = new Integer(0);
            } else {
                int count = onlineCount.intValue();
                onlineCount = new Integer(count - 1);
            }
    
            ctx.setAttribute("OnlineCount",onlineCount);
        }
    
        /*
        * session销毁
        * 1.手动销毁  se.getSession().invalidate();
        * 2.自动销毁
        *       <session-config>
                <session-timeout>1</session-timeout>
                </session-config>
        * */
    }
    
  2. web.xml中注册监听器

    <!--注册监听器-->
    <listener>
        <listener-class>com.kuang.listener.OnlineCountListener</listener-class>
    </listener>
    
  3. 看情况是否使用!

13、 过滤器、监听器常见应用

监听器:GUI编程中经常使用

public class TestPanel  {
    public static void main(String[] args) {
        Frame frame = new Frame("中国必胜!"); // 新建一个窗体
        Panel panel = new Panel(null); // 面板
        frame.setLayout(null); // 设置窗体的布局
        
        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(0,0,246)); // 设置背景颜色
        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(0,246,0)); // 设置背景颜色

        frame.add(panel);
        frame.setVisible(true);

        // 监听事件,监听关闭事件
        frame.addWindowListener(new WindowListener() {
            public void windowOpened(WindowEvent e) {
                System.out.println("打开");
            }
            public void windowClosing(WindowEvent e) {
                System.out.println("关闭ing");
                System.exit(0);
            }
            public void windowClosed(WindowEvent e) {
                System.out.println("关闭ed");
            }
            public void windowIconified(WindowEvent e) {}
            public void windowDeiconified(WindowEvent e) {}

            public void windowActivated(WindowEvent e) {
                System.out.println("激活");
            }
            public void windowDeactivated(WindowEvent e) {
                System.out.println("未激活");
            }
        });
    }
}

为避免new WindowListener()要重写大部分放方法,可以使用WindowListener的实现类WindowAdapter,选择要重写的方法即可!

// 监听事件,监听关闭事件
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
            }
        });

用户登录之后才能进入主页!用户注销后就不能进入主页了!

  1. 用户登录之后,向Session中放入用户的数据
  2. 进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    //Object userSession = request.getSession().getAttribute("USER_SESSION");
    if (request.getSession().getAttribute(Constant.USER_SESSION) == null) {
        response.sendRedirect("/error.jsp");
    }
    chain.doFilter(request,response);
}

14、JDBC

在这里插入图片描述
需要jar包的支持:

  • java.sql
  • javax.sql
  • mysql-connector-java……连接驱动(必须要导入)

实验环境搭建:

CREATE TABLE users(
	id INT PRIMARY KEY,
	`name` VARCHAR(40),
	`password` VARCHAR(40),
	email VARCHAR(60),
	birthday DATE
);

INSERT INTO users(id,`name`,`password`,`email`,`birthday`) VALUES(1,'jackwon','123456','wonjack@166.com','2020-2-2');
INSERT INTO users(id,`name`,`password`,`email`,`birthday`) VALUES(2,'李四','123456','ls@166.com','2021-1-1');
INSERT INTO users(id,`name`,`password`,`email`,`birthday`) VALUES(3,'张三','123456','zs@166.com','2022-3-3');

导入数据库依赖

<!--mysql的驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

IDEA中连接数据库
在这里插入图片描述
JDBC固定步骤

  1. 加载驱动
  2. 连接数据库,connection代表数据库
  3. 向数据库发送SQL的对象Statement:DRUD
  4. 编写SQL(根据业务,不同的SQL)
  5. 执行SQL
  6. 关闭连接
public class TestJdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 配置信息
        // 解决中文乱码问题
        String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "123456";

        // 1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        // 3.向数据库发送SQL对象 Statement:CRUD
        Statement statement = connection.createStatement();

        // 4.编写SQL
        String sql = "select * from users";
        /*
        String sql = "DELETE FROM users WHERE id = 2";
        // 受影响的行数,增删改都是用executeUpdate
        int i = statement.executeUpdate(sql);
        */

        // 5.执行查询SQL,返回一个ResultSet:结果集
        ResultSet rs = statement.executeQuery(sql);
        while (rs.next()) {
            System.out.println("id=" + rs.getObject("id") );
            System.out.println("name=" + rs.getObject("name") );
            System.out.println("password=" + rs.getObject("password") );
            System.out.println("email=" + rs.getObject("email") );
            System.out.println("birthday=" + rs.getObject("birthday") );
        }
        
        // 6.关闭连接,释放资源(一定要做)先开后关
        rs.close();
        connection.close();
    }
}

预编译SQL

public class TestJDBC2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 配置信息
        // 解决中文乱码问题
        String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "123456";

        // 1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        // 3.编写SQL
        String sql = "insert into users(id, name, password, email, birthday) values(?,?,?,?,?)";

        // 4.预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1,4); // 给第一个占位符 ? 的值赋值为4;
        preparedStatement.setString(2,"王老五"); // 给第二个占位符 ? 的值赋值为王老五;
        preparedStatement.setString(3,"88888888"); // 给第三个占位符 ? 的值赋值为88888888;
        preparedStatement.setString(4,"8888@88hua.com"); // 给第四个占位符 ? 的值赋值为8888@88hua.com;
        preparedStatement.setDate(5,new Date(new java.util.Date().getTime())); // 给第五个占位符 ? 的值赋值为new Date(new java.util.Date().getTime());

        // 5.执行SQL
        int i = preparedStatement.executeUpdate();
        if (i > 0) {
            System.out.println("插入成功!");
        }
        // 6.关闭连接,释放资源(一定要做)先开后关
        preparedStatement.close();
        connection.close();
    }
}

事务

要么都成功,要么都失败!

ACID原则:保证数据的安全。

开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务

转账:
A:1000
B:1000

A(900) --100--> B(1100)

Junit单元测试

依赖:

<!--单元测试-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

简单实用

@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行!

@Test
public void test() {
    System.out.println("Hello");
}

在这里插入图片描述
失败的时候是红色的:
在这里插入图片描述
搭建一个环境:

public class TestJDBC3 {
    @Test
    public void test() {
        Connection connection = null; // 提升作用域
        try {
            // 配置信息
            // 解决中文乱码问题
            String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
            String username = "root";
            String password = "123456";

            // 1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2.连接数据库,代表数据库
            connection = DriverManager.getConnection(url, username, password);

            // 3.通知数据库开启事务
            connection.setAutoCommit(false);
            String sql = "update account set money = money-100 where name = 'A'";
            connection.prepareStatement(sql).executeUpdate();

            // 制造错误
            int i = 1/0;
            String sql2 = "update account set money = money+100 where name = 'B'";
            connection.prepareStatement(sql2).executeUpdate();
            connection.commit(); // 以上两条SQL都执行成功了,就提交事务!
            System.out.println("success");
        } catch (Exception e) {
            try {
                // 如果出现异常,就通知数据库回滚事务
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值