0
点赞
收藏
分享

微信扫一扫

数据库的增删改查(一)

乱世小白 2023-06-04 阅读 71

今日内容

零、复习昨日

一、接收请求

需求: html页面中写一个表单,发送请求,后台服务器接收所有请求数据

1.1 编写页面

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>演示表单发送请求,后台接收请求数据</h2>
<%--
    action路径,需要加上项目名
        /项目名/请求路径
    单选,复选框默认选中是 添加checked属性
    下来框默认选中是 option中添加selected属性
--%>
<form action="/day39/req" method="get">

    用户名<input type="text" name="username"><br>
    密码<input type="password" name="password"><br>
    邮箱<input type="email" name="email"><br>
    性别<input type="radio" name="sex" value="1" checked><input type="radio" name="sex"value="2"><br>
    爱好<input type="checkbox" name="hobby" value="coding" checked>敲代码
    <input type="checkbox" name="hobby" value="game"> 打游戏
    <input type="checkbox" name="hobby" value="ball">打球<br>
    生日<input type="date" name="birthday"><br>
    籍贯<select name="jiguan">
            <option value="henan" selected>河南</option>
            <option value="hebei">河北</option>
            <option value="shanxi">山西</option>
        </select><br>
    <input type="submit" value="提交">
</form>

</body>
</html>

1.2 编写Servlet

package com.qf.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class MyReqRespServlet extends HttpServlet {

    /**
     *
     * HttpServletRequest req 来接收请求数据
     * HttpServletResponse resp 来处理响应
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // === 请求行 === [熟悉]
        String method = req.getMethod( );
        /**
         * URL: 资源定位符  http://localhost:8080/day39/req
         * URI: 资源标识符  /day39/req
         */
        StringBuffer url = req.getRequestURL( );
        String uri = req.getRequestURI( );
        String protocol = req.getProtocol( );

        System.out.println("method:"+method);
        System.out.println("url:"+url );
        System.out.println("uri:"+uri);
        System.out.println("protocol:"+protocol );

        // ==== 请求头 ====
        // 获得所有的请求头[了解]
        Enumeration<String> names = req.getHeaderNames( );
        while (names.hasMoreElements()) {
            String heard = names.nextElement( );
            String value = req.getHeader(heard);
            System.out.println(heard+"-->"+value );
        }

        /**
         * [重点] 获得请求正文
         * 无论是明文,暗文,邮箱,日期,单选,下拉框获取数据的方法都是
         * req.getParameter(name),参数是前端标签内name属性的值
         */
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
        String sex = req.getParameter("sex");
        // int i = Integer.parseInt(sex);

        String birthday = req.getParameter("birthday");
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //Date date = sdf.parse(birthday);


        String jiguan = req.getParameter("jiguan");

        System.out.println("username = " +  username);
        System.out.println("password = " + password );
        System.out.println("email = " +  email);
        System.out.println("sex = " +  sex);
        System.out.println("birthday = " +  birthday);
        System.out.println("jiguan = " +  jiguan);

        String[] hobbies = req.getParameterValues("hobby");
        System.out.println(Arrays.toString(hobbies ) );

    }
}

1.3 配置web.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">

    <servlet>
        <servlet-name>req</servlet-name>
        <servlet-class>com.qf.servlet.MyReqRespServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>req</servlet-name>
        <!--此处不需要写项目名,只需要写请求路径-->
        <url-pattern>/req</url-pattern>
    </servlet-mapping>
</web-app>

1.4 部署项目

1.5 启动测试

二、做出响应


        // 响应状态码
        // 200 是成功, 302 重定向 404 资源未找到 500 服务器错误
        // 一般不用设置,为自动响应
        // resp.setStatus(200);

        // 设置响应头
        // resp.setHeader("key","value");
        // 指定浏览器如何解析响应的内容,解决响应乱码
        resp.setContentType("text/html;charset=utf-8");


        // 向浏览器响应内容(响应正文)
        PrintWriter out = resp.getWriter( );
        out.write("<html>");
        out.write("     <head>");
        out.write("         <title>这是响应</title>");
        out.write("     </head>");
        out.write("     <body>");
        out.write("         <div style='background-color:red;width:500px;height:500px;font-size:50px'>");
        out.write("         这是响应,欢迎"+username);
        out.write("         </div>");
        out.write("     </body>");
        out.write("</html>");

三、乱码解决

四、 综合案例(Servlet + JDBC)

登录页面
	html/jsp
后台服务器代码
	web.xml
	servlet,接收数据
	jdbc+orm
	servlet,做出响应
mysql
	库,表

4.1 数据库

CREATE TABLE admin(
	username VARCHAR(20) PRIMARY KEY,
	PASSWORD VARCHAR(20) NOT NULL,
    phone varchar(11) NOT NULL,
    Address varchar(20) NOT NULL
)CHARSET=utf8;
INSERT INTO admin(username,PASSWORD,phone,address)
VALUES('gavin','123456','12345678901','北京市昌平区');
INSERT INTO admin(username,PASSWORD,phone,address)
VALUES('aaron','123456','12345678901','北京市昌平区');

实体类

public class Admin {

    private String username;
    private String password;
    private String phone;
    private String address;
    
    //  set get 构造 toString ...
}

4.2 pom依赖

   <!-- 引入servlet依赖 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <!-- 引入jsp依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
    </dependency> 
    <!-- mysql驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>
    <!-- 阿里巴巴数据库连接池 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.10</version>
    </dependency>

4.3 DBUtils

package com.qf.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class DBUtil {

    // 读取输入流中的数据放入properties对象
    private static Properties properties = new Properties( );

    // 声明Druid连接池
    private static DruidDataSource dataSource;


    /**
     * 静态代码块
     * 目的: 为了加载DBUtil类时就执行静态代码块内的代码
     *      就会加载驱动,且只保留一份
     */
    static {
        try {
            // 将db.properties文件变为输入流
            InputStream inputStream = DBUtil.class.getResourceAsStream("/db.properties");
            properties.load(inputStream);
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace( );
            System.out.println("加载驱动出错");
        }
    }


    /**
     * 返回数据库连接
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            conn = dataSource.getConnection( );
        } catch (Exception e) {
            e.printStackTrace( );
            System.out.println("获得连接出错");
        }
        return conn;
    }

    /**
     * 关闭所有连接
     */
    public static void closeAll(Connection conn, Statement s) {
        try {
            conn.close( );
            s.close( );
        } catch (SQLException e) {
            e.printStackTrace( );
        }
    }

    public static void closeAll(Connection conn, Statement s, ResultSet rs) {
        try {
            conn.close( );
            s.close( );
            rs.close( );
        } catch (SQLException e) {
            e.printStackTrace( );
        }
    }

    /**
     * 设计方法,自动完成查询结果的封装
     */
    public static <T> T selectOne(Class<T> target, String sql, Object... args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        T t = null; // 最终返回的目标类型
        try {
            conn = getConnection( );
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1,args[i]);
            }
            rs = ps.executeQuery( );
            // 根据目标类,获得所有属性
            Field[] fields = target.getDeclaredFields( );
            while(rs.next()) {
                t = target.newInstance( );
                // 遍历得到所有的属性,即就是数据库的字段
                for (Field field : fields) {
                    String name = field.getName( );
                    Object value = rs.getObject(name);
                    field.setAccessible(true);
                    if (value != null) {
                        field.set(t,value);
                    }
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll(conn,ps,rs);
        }
        return t;
    }

    public static <T> List<T> selectAll(Class<T> target, String sql, Object... args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        T t = null; // 最终返回的目标类型
        ArrayList<T> list = new ArrayList<>( );
        try {
            conn = getConnection( );
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1,args[i]);
            }
            rs = ps.executeQuery( );
            // 根据目标类,获得所有属性
            Field[] fields = target.getDeclaredFields( );
            while(rs.next()) {
                t = target.newInstance( );
                // 遍历得到所有的属性,即就是数据库的字段
                for (Field field : fields) {
                    String name = field.getName( );
                    Object value = rs.getObject(name);
                    field.setAccessible(true);
                    if (value != null) {
                        field.set(t,value);
                    }
                }
                list.add(t);
            }
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll(conn,ps,rs);
        }
        return list;
    }

    /**
     * 封装增删改的方法
     */
    public static int update(String sql,Object... args){
        Connection conn = null;
        PreparedStatement ps = null;
        int num = 0;
        try {
            conn = getConnection( );
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1,args[i]);
            }
            num = ps.executeUpdate( );
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll(conn,ps);
        }
        return num;
    }

}

加入数据库连接池

db.properties

# properties文件是一种特殊的文件格式,形如map
# 文件内容的写法: key=value
# 数据库驱动
driverClass=com.mysql.jdbc.Driver
# 连接url
url=jdbc:mysql://localhost:3306/java2307?useSSL=false
# 用户名
username=root
# 密码
password=123456
# ----- 加入druid的一些连接配置
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒 -->
maxWait=5000

4.4 登录页面

<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>登录</h2>
    <form action="/day39/login">
        用户名<input type="text" name="username"><br>
        密码 <input type="password" name="password"><br>
        <input type="submit" value="登录"><br>
    </form>
</body>
</html>

4.5 web.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">

    <!-- 设置项目启动访问的首页,默认是index.jsp -->
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
    
    <servlet>
        <servlet-name>req</servlet-name>
        <servlet-class>com.qf.servlet.MyReqRespServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>req</servlet-name>
        <url-pattern>/req</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.qf.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
</web-app>

4.6 业务层service

AdminService

public interface AdminService {

    /**
     * 根据用户名密码查询用户
     * @param username
     * @param password
     * @return 查到返回的是用户对象
     *         查不到返回的null
     */
   Admin login(String username , String password);

    /**
     * 查询全部用户
     */
    List<Admin> findAll();

}

AdminServiceImpl

public class AdminServiceImpl implements AdminService{

    private AdminDao adminDao = new AdminDaoImpl();

    @Override
    public Admin login(String username, String password) {
        /**
         * 业务逻辑代码...
         */
        Admin admin = adminDao.login(username, password);
        return admin;
    }

    @Override
    public List<Admin> findAll() {
        List<Admin> list = adminDao.findAll( );
        return list;
    }
}

4.7 数据访问层dao

AdminDao

public interface AdminDao {

    /**
     * 登录
     */
    Admin login(String username,String password);

    /**
     * 查询全部
     */
    List<Admin> findAll();

}

AdminDaoImpl

public class AdminDaoImpl implements AdminDao{

    @Override
    public Admin login(String username, String password) {
        Connection conn = DBUtil.getConnection( );
        PreparedStatement ps = null;
        ResultSet rs = null;
        Admin admin = null;
        try {
            ps = conn.prepareStatement("select * from admin where username = ? and password = ?");
            ps.setString(1,username);
            ps.setString(2,password);

            rs = ps.executeQuery( );
            while (rs.next()) {
                // 从数据库查出的
                String username1 = rs.getString("username");
                String password1 = rs.getString("password");
                String phone = rs.getString("phone");
                String address = rs.getString("address");

                admin = new Admin(  );// 用这个对象封装数据库的数据
                admin.setUsername(username1);
                admin.setPassword(password1);
                admin.setPhone(phone);
                admin.setAddress(address);
            }
        } catch (SQLException e) {
            e.printStackTrace( );
        } finally {
            DBUtil.closeAll(conn,ps,rs);
        }
        return admin;
    }

    @Override
    public List<Admin> findAll() {
        Connection conn = DBUtil.getConnection( );
        PreparedStatement ps = null;
        ResultSet rs = null;
        Admin admin = null;
        ArrayList<Admin> list = new ArrayList<>( );
        try {
            ps = conn.prepareStatement("select * from admin ");

            rs = ps.executeQuery( );
            while (rs.next()) {
                // 从数据库查出的
                String username1 = rs.getString("username");
                String password1 = rs.getString("password");
                String phone = rs.getString("phone");
                String address = rs.getString("address");

                admin = new Admin(  );// 用这个对象封装数据库的数据
                admin.setUsername(username1);
                admin.setPassword(password1);
                admin.setPhone(phone);
                admin.setAddress(address);

                // 存入集合
                list.add(admin);
            }
        } catch (SQLException e) {
            e.printStackTrace( );
        } finally {
            DBUtil.closeAll(conn,ps,rs);
        }
        return list;
    }
}

4.8 LoginServlet

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置编码
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        // 接收请求
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("username = " + username );
        System.out.println("password = " + password );

        /**
         * 中间处理业务逻辑的代码
         * 需要单独创建业务层类(service),数据访问层类(dao)
         * 不要把所有事情都交给servlet,要做到单一职责
         */
        AdminService service = new AdminServiceImpl();
        Admin admin = service.login(username, password);


        PrintWriter out = resp.getWriter( );
        // 做出响应
        if (admin != null) {
            // 登录成功,展现全部
            List<Admin> list = service.findAll( );
            out.write("<html>");
            out.write("<h2 style='color:green'>欢迎"+username+"登录管理员系统</h2>");

            out.write("<hr>");
            out.write("<table border='2'>");
            out.write("<tr>");
            out.write(" <td>用户名</td>");
            out.write(" <td>密码</td>");
            out.write(" <td>手机号</td>");
            out.write(" <td>地址</td>");
            out.write("</tr>");
            for (int i = 0; i < list.size(); i++) {
                Admin obj = list.get(i);
                out.write("<tr>");
                out.write(" <td>"+obj.getUsername()+"</td>");
                out.write(" <td>"+obj.getPassword()+"</td>");
                out.write(" <td>"+obj.getPhone()+"</td>");
                out.write(" <td>"+obj.getAddress()+"</td>");
                out.write("</tr>");
            }
            out.write("</table>");
            out.write("</html>");

        } else {
            // 登录失败
            out.write("<html>");
            out.write("<h1 style='color:red'>用户名或密码错误</h1>");
            out.write("</html>");
        }
    }
}

4.9 测试

image-20230523162257066

image-20230523162307245

举报

相关推荐

0 条评论