zoukankan      html  css  js  c++  java
  • 构建web应用之——SpringMVC实现CRUD

    配置好SpringMVC最基本的配置后,开始实现处理数据的CRUD(CREATE, READ, UPDATE, DELETE)

    为实现模块上的松耦合,我们将与数据库的交互任务交给DAO(Data Access Object,即数据访问对象)层,

    SpringMVC中使用@Repository注解为DAO自动生成bean,下面是实现数据增删改查所用的数据库:

    1.数据库:mysql

    2.数据源连接池:DBCP(最先使用了Spring中内置的基于JDBC的数据源DriverManagerDataSource,但它没有

    池的概念,在每次请求连接时都要创建新连接,降低了性能)

    实现过程:

    一、添加依赖

    基于之前的项目,我们还需要配置一些其他的依赖,来支持我们项目的构建,具体依赖如下:

    <!-- mysql -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>5.1.3.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.13</version>
          <scope>runtime</scope>
        </dependency>
    
        <!-- 数据源连接池 -->
        <dependency>
          <groupId>commons-dbcp</groupId>
          <artifactId>commons-dbcp</artifactId>
          <version>1.4</version>
        </dependency>
        <dependency>
          <groupId>commons-pool</groupId>
          <artifactId>commons-pool</artifactId>
          <version>1.6</version>
        </dependency>

    除了上述依赖意外,我们还需要加入spring bean的依赖。虽然我们使用注解自动装配以及XML配置的形式来声明和使用bean,

    但是,我们需要spring bean来配置我们的配置文件路径。

    <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-beans</artifactId>
          <version>5.1.3.RELEASE</version>
        </dependency>

    二、编码(Service层和Controller层的实现)

    我们通过DAO层来与数据库实现交互,因此,我们的Service层以及Controller层无需关注数据交互,只需要处理自己本职的工作即可。

    下面是文件结构:

    我们通过StudentController类来响应请求,通过StudentService接口来定义CRUD四种服务,通过StudentDao接口来定义

    与数据库交互的方法(增、删、改、查),StudentServiceImpl类以及StudentDaoImpl类分别实现了接口中定义的方法。

    StudentDao定义与数据库交互的方法(具体实现过程抛给其实现类):

    package example.dao;
    
    import example.entity.Student;
    
    public interface StudentDao {
    
        public void create(Student student);
        public Student readById(String studentId);
        public void updateName(String studentId, String newUsername);
        public void deleteById(String studentId);
    }

    有了StudentDao中定义的方法后,我们就可以编写Controller层和Service层代码逻辑了(数据如何增删改查我们暂时不用关心)

    StudentService定义了我们的web项目所要拥有的功能:

    1.添加一个学生

    2.查找指定学号的学生信息

    3.更新学生信息

    4.删除指定学生

    package example.service;
    
    import example.entity.Student;
    
    public interface StudentService {
    
        public void create(Student student);
        public Student readById(String studentId);
        public void updateUsername(String studentId, String newName);
        public void deleteById(String studentId);
    
    }

    StudentServiceImpl实现了StudentService接口中的方法

    package example.service;
    
    import example.dao.StudentDao;
    import example.entity.Student;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.stereotype.Service;
    
    @Service
    public class StudentServiceImpl implements StudentService {
    
        // 注入StudentDao
        @Autowired
        private StudentDao studentDao;
    
        @Override
        public void create(Student student) {
            studentDao.create(student);
        }
    
        @Override
        public Student readById(String studentId) {
            return studentDao.readById(studentId);
        }
    
        @Override
        public void updateUsername(String studentId, String newName) {
            studentDao.updateName(studentId, newName);
        }
    
        @Override
        public void deleteById(String studentId) {
            studentDao.deleteById(studentId);
        }
    }

    使用@Service注解使得Spring自动为StudentService生成bean,同时我们注入了StudentDao的bean

    Controller层负责处理请求:

    package example.controller;
    
    import example.entity.Student;
    import example.service.StudentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    
    @Controller
    @RequestMapping("/student")
    public class StudentController {
    
        // 注入StudentService Bean
        @Autowired
        private StudentService studentService;
    
        // 处理创建学生请求
        @RequestMapping(value = "/create", method = RequestMethod.POST)
        public String createStudent(Student student) {
            studentService.create(student);
            // 重定向到学生信息界面
            return "redirect:/student/read/" + student.getStudentId();
        }
    
        // 处理查询学生信息请求
        @RequestMapping(value = "/read/{studentId}", method = RequestMethod.GET)
        public String readStudent(
                @PathVariable("studentId") String studentId,
                Model model) {
            model.addAttribute(studentService.readById(studentId));
            return "student";
        }
    
        // 处理JSP视图查询处理
        @RequestMapping(value = "/read", method = RequestMethod.GET)
        public String readStudentByView(
                @RequestParam("studentId") String studentId,
                Model model) {
            model.addAttribute(studentService.readById(studentId));
            return "student";
        }
    
        // 处理修改学生信息请求
        @RequestMapping(value = "/update", method = RequestMethod.POST)
        public String updateStudent(String studentId, String newUsername) {
            studentService.updateUsername(studentId, newUsername);
            return "redirect:/student/read/" + studentId;
        }
    
        // 处理删除学生请求
        @RequestMapping(value = "/delete", method = RequestMethod.POST)
        public String deleteStudent(String studentId) {
            studentService.deleteById(studentId);
            return "deleteSuccessfully";
        }
    }

    @Controller注解使Spring自动为其生成bean,@RequestMapping注解用来声明请求映射(类比之前的helloMVC实现)

    最后,我们需要在DispatcherServlet以及Spring内部配置文件中进行配置,使其能够在编译时扫描到带有注解的类并为其生成bean

    dispatcher-servlet.xml中

    <!-- DispatcherServlet上下文只管理@Controller类型的bean -->
        <context:component-scan base-package="example">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
    <!-- 自动扫描装配 -->
        <context:component-scan base-package="example.controller"/>

    applicationContext.xml

    <!-- 忽略对@Controller的扫描 -->
        <context:component-scan base-package="example">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>

    三、实现Dao层

    到目前为止,我们还无法获取数据(当然可以在StudentDaoImpl中使用静态数据),接下来我们要实现StudentDao接口中

    的方法,使得我们能真正意义上在视图中看到想要的数据

    在编写方法逻辑之前,我们需要完成数据库相关配置:

    1.数据库配置参数(jdbc.properties)松耦合的一种方式

    ############ DBCP数据源连接池配置
    ############ mysql
    jdbc.driverClassName=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
    jdbc.username=root
    jdbc.password=
    ############ BasicDataSource的池配置属性
    jdbc.initialSize=5
    jdbc.maxActive=10

    2.完成数据库、数据源以及bean的装配

    <!-- Spring内置JDBC数据源 -->
        <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/student?useUnicode=true&amp;characterEncoding=utf8
                &amp;serverTimezone=GMT"/>
            <property name="username" value="root"/>
            <property name="password" value=""/>
        </bean> -->
    
        <!-- 配置jdbc.properties路径 -->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="classpath:jdbc.properties"/>
        </bean>
        <!-- 使用DBCP数据源连接池 -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="${jdbc.driverClassName}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
            <property name="initialSize" value="${jdbc.initialSize}"/>
            <property name="maxActive" value="${jdbc.maxActive}"/>
        </bean>
    
        <!-- 使用JDBC模板操作数据 -->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <constructor-arg ref="dataSource"/>
        </bean>

    注意:配置连接数据库的参数变量时,不能只写url,username等,应为xml中使用${username}获得的是计算机账号的名称,要加以区分

    3.实现StudentDao方法

    这一部分说白了就是编写增删改查的SQL语句,代码如下:

    package example.dao;
    
    import example.entity.Student;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowMapper;
    import org.springframework.stereotype.Repository;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    @Repository
    public class StudentDaoImpl implements StudentDao {
    
        private JdbcTemplate jdbcTemplate;
    
        @Autowired
        public StudentDaoImpl(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
    
        private static final String INSERT_STUDENT =
                "insert into student (student_id, student_name, password)" +
                        "values (?, ?, ?)";
    
        private static final String QUERY_STUDENT =
                "select student_id, student_name, password from student where student_id = ?";
    
        private static final String UPDATE_STUDENT =
                "update student set student_name = ? where student_id = ?";
    
        private static final String DELETE_STUDENT =
                "delete from student where student_id = ?";
    
        @Override
        public void create(Student student) {
            jdbcTemplate.update(INSERT_STUDENT,
                    student.getStudentId(),
                    student.getUsername(),
                    student.getPassword());
        }
    
        @Override
        public Student readById(String studentId) {
            return jdbcTemplate.queryForObject(
                    QUERY_STUDENT,
                    new StudentRowMapper(),
                    studentId
            );
        }
    
        @Override
        public void updateName(String studentId, String newUsername) {
            jdbcTemplate.update(UPDATE_STUDENT,
                    newUsername,
                    studentId);
        }
    
        @Override
        public void deleteById(String studentId) {
            jdbcTemplate.update(DELETE_STUDENT, studentId);
        }
    
        private static final class StudentRowMapper
                implements RowMapper<Student> {
            @Override
            public Student mapRow(ResultSet resultSet, int i) throws SQLException {
                return new Student(
                        resultSet.getString("student_id"),
                        resultSet.getString("student_name"),
                        resultSet.getString("password")
                );
            }
        }
    }

    使用@Repository注解使得Spring能够自动生成StudentDao的bean,同时注入JDBCTemplatebean用于数据库sql的操作,

    需要注意的是,调用JdbcTemplate.queryForObject()方法时,需要一个RowMapper对象用于存放查找的Student对象,因此,

    在代码最后我们定义了一个内部类实现了RowMapper接口,并实现了mapRow()方法用于返回一个Student的实例

    以上,我们的代码实现就完成了。要运行web项目,我们还需要在Mysql数据库中创建student表以及创建相关视图

    home.jsp

    <%--
      Created by IntelliJ IDEA.
      User: asus1
      Date: 2019/1/6
      Time: 12:06
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        Hello world! Hello SpringMVC!
        <div>
            create:
            <form action="http://localhost:8080/trymaven/student/create" method="post">
                studentId: <input type="text" name="studentId" placeholder="studentId"/>
                username: <input type="text" name="username" placeholder="username"/>
                password: <input type="password" name="password" placeholder="password"/>
                <input type="submit" value="submit"/>
            </form>
        </div>
        <div>
            read:
            <form action="http://localhost:8080/trymaven/student/read" method="get">
                studentId: <input type="text" name="studentId" placeholder="studentId"/>
                <input type="submit" value="submit">
            </form>
        </div>
        <div>
            update:
            <form action="http://localhost:8080/trymaven/student/update" method="post">
                studentId: <input type="text" name="studentId" placeholder="studentId"/>
                new username: <input type="text" name="newUsername" placeholder="new username"/>
                <input type="submit" value="submit"/>
            </form>
        </div>
        <div>
            delete:
            <form action="http://localhost:8080/trymaven/student/delete" method="post">
                studentId: <input type="text" name="studentId" placeholder="studentId"/>
                <input type="submit" value="submit"/>
            </form>
        </div>
    </body>
    </html>

    student.jsp

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%--
      Created by IntelliJ IDEA.
      User: asus1
      Date: 2019/1/6
      Time: 19:39
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>student</title>
    </head>
    <body>
        <div class="studentView">
            <span class="studentId"><c:out value="${student.studentId}"/></span>
            <span class="studentName"><c:out value="${student.username}"/></span>
        </div>
    </body>
    </html>

    deleteSuccessfully.jsp

    <%--
      Created by IntelliJ IDEA.
      User: asus1
      Date: 2019/1/6
      Time: 19:45
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>deleteState</title>
    </head>
    <body>
    The information is deleted successfully.
    </body>
    </html>

    四、运行web项目

    通过Tomcat启动项目:

  • 相关阅读:
    SqlSugar ORM 入门篇2 【查询】 让我们实现零SQL
    .NET ORM框架 SqlSugar4.0 功能快速预览【开源】
    Django 2 by example
    持续为您导航
    Django框架
    Python快速入门
    第一章 创建博客应用
    Python术语对照表
    49、你并不了解的format、decimal
    48、python内存泄露
  • 原文地址:https://www.cnblogs.com/znnby1997/p/10235620.html
Copyright © 2011-2022 走看看