基于SpringBoot、Freemarker 实现用户增删改查的完整案例

2023年 8月 22日 58.6k 0

环境准备

  • JDK 1.8 及以上
  • SpringBoot 2.5.5 及以上
  • MySQL 5.7 及以上
  • Maven
  • IntelliJ IDEA (可选)

创建项目

我们使用 IntelliJ IDEA 创建一个 Spring Boot Web 项目。

  • 打开 IntelliJ IDEA,点击菜单栏的 "File",选择 "New",然后选择 "Project"。

  • 在向导中选择 "Spring Initializr",然后点击 Next。

  • 在 Spring Initializr 页面中,填写项目信息。

    • Group:自己定义
    • Artifact:自己定义
    • Dependencies:选择 "Spring Web"、"Spring Data JPA" 和 "MySQL Driver",然后点击 Next。
    • Metadata:自己定义

    然后点击 Finish,等待项目创建完成。

  • 数据库配置

    application.properties 文件中添加以下配置:

    spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
    spring.jpa.hibernate.ddl-auto=create
    

    实现用户表

    创建用户实体

    我们先创建一个用户实体类 User,并使用 JPA 注解标记对应数据库的表名和字段名。

    @Entity
    @Table(name = "user")
    public class User implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String name;
    
        private Integer age;
    
        @Column(name = "create_time")
        private LocalDateTime createTime;
    
        @Column(name = "update_time")
        private LocalDateTime updateTime;
    
        // Getter 和 Setter 略
    }
    

    创建用户 Repository

    创建一个接口 UserRepository,并继承 JpaRepository 接口。

    public interface UserRepository extends JpaRepository {
    }
    

    创建用户 Service

    创建一个 Service 接口 UserService,定义对用户操作的方法。

    public interface UserService {
        User save(User user);
    
        void deleteById(Long id);
    
        User findById(Long id);
    
        List findAll();
    }
    

    创建一个 Service 实现类 UserServiceImpl,实现 Service 接口,对用户的增删改查操作进行具体实现。

    @Service
    public class UserServiceImpl implements UserService {
    
        private final UserRepository userRepository;
    
        @Autowired
        public UserServiceImpl(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        @Override
        public User save(User user) {
            LocalDateTime now = LocalDateTime.now();
            user.setCreateTime(now);
            user.setUpdateTime(now);
            return userRepository.save(user);
        }
    
        @Override
        public void deleteById(Long id) {
            userRepository.deleteById(id);
        }
    
        @Override
        public User findById(Long id) {
            return userRepository.findById(id).orElse(null);
        }
    
        @Override
        public List findAll() {
            return userRepository.findAll();
        }
    }
    

    实现 Controller

    添加页面

    我们需要先添加前端页面,这里使用 Freemarker 模板进行实现。

    resources/templates/ 目录下创建名为 user.ftl 的文件,并填写以下代码:

    
    
    
        
        用户管理
    
    
        用户管理
    
        
            
            
            用户名:
            
            年龄:
            
    
            保存
        
    
        
            
                id
                name
                age
                create_time
                update_time
                操作
            
            
            
                ${user.id}
                ${user.name}
                ${user.age}
                ${user.createTime}
                ${user.updateTime}
                
                    编辑
                    删除
                
            
            
        
    
        
        
            $(function() {
                function clearForm() {
                    $('input[type="text"],input[type="number"]').val('');
                    $('input[type="hidden"]').val(0);
                }
    
                function listUser() {
                    $.get('/user', function (data) {
                        $('.user-table').replaceWith(data);
                    });
                }
    
                $('form #save').click(function () {
                    var id = $('form #id').val();
                    var formData = $('form').serializeArray();
                    var user = {};
                    $.each(formData, function (_, kv) {
                        user[kv.name] = kv.value;
                    });
                    user.id = id;
                    $.ajax('/user', {
                        data: JSON.stringify(user),
                        contentType: 'application/json',
                        type: (id === '0') ? 'POST' : 'PUT',
                        success: function () {
                            clearForm();
                            listUser();
                        }
                    });
                });
    
                $(document).on('click', '.edit', function () {
                    var id = $(this).data('id');
                    $.get('/user/' + id, function (data) {
                        $.each(data, function (key, value) {
                            $('form #' + key).val(value);
                        });
                    });
                });
    
                $(document).on('click', '.delete', function () {
                    var id = $(this).data('id');
                    $.ajax('/user/' + id, {
                        type: 'DELETE',
                        success: function () {
                            listUser();
                        }
                    });
                });
    
                listUser();
            });
        
    
    
    

    创建 Controller

    创建一个 Controller 类 UserController,并添加对用户增删改查的对应操作。同时,使用 @Controller@ResponseBody 注解实现对前端页面请求的响应,并使用 @Autowired 注解自动注入 UserService。

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        private final UserService userService;
    
        @Autowired
        public UserController(UserService userService) {
            this.userService = userService;
        }
    
        @GetMapping
        public String index(Model model) {
            List userList = userService.findAll();
            model.addAttribute("userList", userList);
            return "user";
        }
    
        @PostMapping
        @ResponseBody
        public User add(@RequestBody User user) {
            return userService.save(user);
        }
    
        @PutMapping("/{id}")
        @ResponseBody
        public User update(@PathVariable("id") Long id, @RequestBody User user) {
            User oldUser = userService.findById(id);
            if (oldUser == null) {
                return null;
            }
            oldUser.setName(user.getName());
            oldUser.setAge(user.getAge());
            oldUser.setUpdateTime(LocalDateTime.now());
            return userService.save(oldUser);
        }
    
        @DeleteMapping("/{id}")
        @ResponseBody
        public void delete(@PathVariable("id") Long id) {
            userService.deleteById(id);
        }
    
        @GetMapping("/{id}")
        @ResponseBody
        public User find(@PathVariable("id") Long id) {
            return userService.findById(id);
        }
    }
    

    测试

    启动应用程序,在浏览器中访问 http://localhost:8080/user,即可看到用户的增删改查界面。在该界面中,您可以添加、修改、删除和查询用户信息。同时,您也可以查看完整的工程目录结构。

    工程目录结构

    spring-boot-demo/
        ├─src/
        │  ├─main/
        │  │  ├─java/
        │  │  │  └─com/
        │  │  │      └─example/
        │  │  │          ├─controller/
        │  │  │          │  └─UserController.java
        │  │  │          ├─domain/
        │  │  │          │  └─User.java
        │  │  │          ├─repository/
        │  │  │          │  └─UserRepository.java
        │  │  │          ├─service/
        │  │  │          │  ├─impl/
        │  │  │          │  │  └─UserServiceImpl.java
        │  │  │          │  └─UserService.java
        │  │  │          └─SpringBootDemoApplication.java
        │  │  └─resources/
        │  │      ├─static/
        │  │      └─templates/
        │  │          └─user.ftl
        │  └─test/
        └─pom.xml
    

    完整代码

    为方便您的参考,这里提供一个完整的项目代码。其中,可以直接使用自己的数据库信息进行测试。

  • User.java
  • package com.example.domain;
    
    import javax.persistence.*;
    import java.io.Serializable;
    import java.time.LocalDateTime;
    
    @Entity
    @Table(name = "user")
    public class User implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String name;
    
        private Integer age;
    
        @Column(name = "create_time")
        private LocalDateTime createTime;
    
        @Column(name = "update_time")
        private LocalDateTime updateTime;
    
        // Getter 和 Setter 略
    }
    
  • UserRepository.java
  • package com.example.repository;
    
    import com.example.domain.User;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    public interface UserRepository extends JpaRepository {
    }
    
  • UserService.java
  • package com.example.service;
    
    import com.example.domain.User;
    
    import java.util.List;
    
    public interface UserService {
        User save(User user);
    
        void deleteById(Long id);
    
        User findById(Long id);
    
        List findAll();
    }
    
  • UserServiceImpl.java
  • package com.example.service.impl;
    
    import com.example.domain.User;
    import com.example.repository.UserRepository;
    import com.example.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.time.LocalDateTime;
    import java.util.List;
    
    @Service
    public class UserServiceImpl implements UserService {
    
        private final UserRepository userRepository;
    
        @Autowired
        public UserServiceImpl(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        @Override
        public User save(User user) {
            LocalDateTime now = LocalDateTime.now();
            user.setCreateTime(now);
            user.setUpdateTime(now);
            return userRepository.save(user);
        }
    
        @Override
        public void deleteById(Long id) {
            userRepository.deleteById(id);
        }
    
        @Override
        public User findById(Long id) {
            return userRepository.findById(id).orElse(null);
        }
    
        @Override
        public List findAll() {
            return userRepository.findAll();
        }
    }
    
  • UserController.java
  • package com.example.controller;
    
    import com.example.domain.User;
    import com.example.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;
    
    import java.time.LocalDateTime;
    import java.util.List;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        private final UserService userService;
    
        @Autowired
        public UserController(UserService userService) {
            this.userService = userService;
        }
    
        @GetMapping
        public String index(Model model) {
            List userList = userService.findAll();
            model.addAttribute("userList", userList);
            return "user";
        }
    
        @PostMapping
        @ResponseBody
        public User add(@RequestBody User user) {
            return userService.save(user);
        }
    
        @PutMapping("/{id}")
        @ResponseBody
        public User update(@PathVariable("id") Long id, @RequestBody User user) {
            User oldUser = userService.findById(id);
            if (oldUser == null) {
                return null;
            }
            oldUser.setName(user.getName());
            oldUser.setAge(user.getAge());
            oldUser.setUpdateTime(LocalDateTime.now());
            return userService.save(oldUser);
        }
    
        @DeleteMapping("/{id}")
        @ResponseBody
        public void delete(@PathVariable("id") Long id) {
            userService.deleteById(id);
        }
    
        @GetMapping("/{id}")
        @ResponseBody
        public User find(@PathVariable("id") Long id) {
            return userService.findById(id);
        }
    }
    
  • pom.xml
  • 
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
    
        
        
            org.springframework.boot
            spring-boot-starter-freemarker
        
    
        
        
            mysql
            mysql-connector-java
        
    
        
        
            org.springframework.boot
            spring-boot-starter-web
        
    
    
  • SpringBootDemoApplication.java
  • package com.example;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class SpringBootDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBootDemoApplication.class, args);
        }
    }
    
  • application.properties
  • spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
    spring.datasource.username=root
    spring.datasource.password=root
    
    # 让 Hibernate 自动创建数据库表结构
    spring.jpa.hibernate.ddl-auto=create
    # 设置 Hibernate 方言
    spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
    
  • user.ftl
  • 
    
    
        
        用户管理系统
        
            body {
                background-color: #F0F0F0;
            }
    
            .container {
                width: 1200px;
                margin: 20px auto;
                padding: 20px;
                border-radius: 5px;
                background-color: #FFFFFF;
                box-shadow: 0 0 5px #999999;
            }
    
            h1 {
                text-align: center;
                margin-bottom: 30px;
            }
    
            .add {
                margin-bottom: 20px;
            }
    
            .add input[type='text'], .add input[type='number'] {
                width: 150px;
                padding: 5px;
                border-radius: 5px;
                border: 1px solid #CCCCCC;
                margin-right: 10px;
            }
    
            .add button {
                padding: 5px 10px;
                border-radius: 5px;
                border: 1px solid #CCCCCC;
                background-color: #FFFFFF;
                cursor: pointer;
            }
    
            table {
                width: 100%;
                border-collapse: collapse;
                text-align: center;
                margin-bottom: 30px;
            }
    
            th {
                background-color: #F5F5F5;
                padding: 10px;
                border-bottom: 1px solid #CCCCCC;
            }
    
            td {
                padding: 10px;
                border-bottom: 1px solid #CCCCCC;
            }
    
            .btn-group {
                margin-bottom: 20px;
            }
    
            .btn-group button {
                padding: 5px 10px;
                border-radius: 5px;
                border: 1px solid #CCCCCC;
                background-color: #FFFFFF;
                cursor: pointer;
                margin-right: 10px;
            }
        
    
    
    
        用户管理系统
    
        
            
            
            添加用户
        
    
        
            
            
                ID
                姓名
                年龄
                创建时间
                更新时间
                操作
            
            
            
            
            
                ${user.id}
                ${user.name}
                ${user.age}
                ${user.createTime?string("yyyy-MM-dd HH:mm:ss")}
                ${user.updateTime?string("yyyy-MM-dd HH:mm:ss")}
                
                    
                        编辑
                        删除
                    
                
            
            
            
        
    
    
    
        function addUser() {
            let name = document.getElementById("name").value;
            let age = document.getElementById("age").value;
            let xhr = new XMLHttpRequest();
            xhr.open("POST", "/user");
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.onreadystatechange = function () {
                if (xhr.readyState === XMLHttpRequest.DONE) {
                    if (xhr.status === 200 || xhr.status === 201) {
                        location.reload();
                    } else {
                        alert("添加用户失败!");
                    }
                }
            }
            xhr.send(JSON.stringify({name, age}));
        }
    
        function editUser(id) {
            let name = prompt("请输入姓名:");
            let age = prompt("请输入年龄:");
            let xhr = new XMLHttpRequest();
            xhr.open("PUT", `/user/${id}`);
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.onreadystatechange = function () {
                if (xhr.readyState === XMLHttpRequest.DONE) {
                    if (xhr.status === 200 || xhr.status === 201) {
                        location.reload();
                    } else {
                        alert("编辑用户失败!");
                    }
                }
            }
            xhr.send(JSON.stringify({name, age}));
        }
    
        function deleteUser(id) {
            if (confirm("确定删除该用户吗?")) {
                let xhr = new XMLHttpRequest();
                xhr.open("DELETE", `/user/${id}`);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === XMLHttpRequest.DONE) {
                        if (xhr.status === 200 || xhr.status === 201) {
                            location.reload();
                        } else {
                            alert("删除用户失败!");
                        }
                    }
                }
                xhr.send();
            }
        }
    
    
    
    

    总结

    虽然现在前后端分离的场景比较普遍,前端有很多流行的框架,如Vue、Angular、React等,但是上面介绍的基于SpringBoot和Freemarker的用户管理系统对于初学者学习来说仍然是一份非常好的示例。

    通过这个例子,我们可以学习到如何使用Spring Boot快速搭建一个Web应用,如何使用JPA进行数据持久化,以及如何使用Freemarker模板引擎来渲染页面。同时,这个例子也展示了一个最基本的CRUD应用,其中包括增加、删除、修改和查询用户。

    无论是在学习过程中还是实际开发中,了解这些基本的概念和用法都是非常重要的。因此,我认为这个例子对于初学者来说是非常有用的。

    相关文章源码放在:gitee仓库、github仓库上。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论