1

简单项目【springboot】

 2 years ago
source link: https://blog.csdn.net/qq_51625007/article/details/123085957
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

借鉴狂神springboot项目

第一步 设计数据表

  • department
create table department(
    id int,
    departmentName varchar(10)
)
  • employee
create table employee
(
    id            int auto_increment
        primary key,
    last_name     varchar(20) not null,
    email         varchar(20) not null,
    gender        int         not null,
    department_id int         references department(id),
    birth         datetime    not null
);
insert into department(id, departmentName) values
 (101,'教学部'),
(102,'市场部'),
(103,'教研部'),
 (104,'运营部'),
 (105,'后勤部')
insert into employee(last_name, email, gender, department_id, birth) values
('AA','[email protected]',0,101,'2019-1-1 00:00:00'),
 ('BB','[email protected]',1,102,'2019-1-1 00:00:00'),
 ('CC','[email protected]',0,103,'2019-1-1 00:00:00'),
 ('DD','[email protected]',1,104,'2019-1-1 00:00:00'),
 ('EE','[email protected]',0,105,'2019-1-1 00:00:00')

在这里插入图片描述

在这里插入图片描述

第二步 建Springboot项目

在这里插入图片描述

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kuang</groupId>
    <artifactId>springboot-05-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-05-project</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <!--  druid      -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>

        <!--   log4j      -->
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--  mybatis    -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

        <!--   mysql     -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

newCodeMoreWhite.png

application.properties

# 关闭模板引擎的缓存
spring.thymeleaf.cache=false

# 我们的配置文件放在的真实位置
spring.messages.basename=i18n.login

#json格式化全局配置
spring.jackson.time-zone=GMT+8
spring.jackson.date-format=yyyy-MM-dd
spring.jackson.default-property-inclusion=NON_NULL
# 日期格式化
spring.mvc.date-format=yyyy-MM-dd

# 整合mybatis
# 驼峰
mybatis.configuration.mapUnderscoreToCamelCase=true 
#mybatis.type-aliases-package=com.kuang.pojo
#mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

newCodeMoreWhite.png

application.yml

spring:
  datasource:
    username: root
    password: root
    # serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/kuang_boot?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
newCodeMoreWhite.png
    @Autowired
    DataSource dataSource;
    @Test
    void contextLoads() throws SQLException {
        //查看默认数据源
        System.out.println(dataSource.getClass());

        //获得数据库连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);


        //关闭
        connection.close();
    }
  • Department类
package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Department {
    private Integer id;
    private String departmentName;

}

  • Employee类
package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@NoArgsConstructor

@Data
public class Employee {
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;//0 女 1男
    private Integer departmentId;
    private Date birth;


    public Employee(String lastName, String email, Integer gender, Integer departmentId,Date birth) {
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.departmentId=departmentId;
        this.birth=birth;
    }
}

newCodeMoreWhite.png

mapper

  • DepartmentMapper
package com.kuang.mapper;

import com.kuang.pojo.Department;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.Collection;

@Mapper
@Repository
public interface DepartmentMapper {


    //获得所有部门信息
    @Select("select * from department")
    Collection<Department> getDepartments();

    //通过id得到部门
    @Select("select * from department where id=#{id}")
    Department getDepartmentById(Integer id);

}

newCodeMoreWhite.png
  • EmployeeMapper
package com.kuang.mapper;

import com.kuang.pojo.Employee;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.util.List;
@Mapper
@Repository
public interface EmployeeMapper {

    //增加一个员工
    @Insert("insert into employee(last_name, email, gender, department_id,birth) value (#{lastName},#{email},#{gender},#{departmentId},#{birth})")
    void save(Employee employee);

    //查询全部员工信息
    @Select("select * from employee")
    List<Employee> getAll();

    //通过id得到员工
    @Select(" select * from employee where id = #{id}")
    Employee getEmployeeById(Integer id);

    @Update("update employee set last_name=#{lastName},email=#{email},gender=#{gender},department_id=#{departmentId},birth=#{birth} where id=#{id}")
    int updateEmp(Employee employee);

    //删除员工id
    @Delete("delete  from employee where id=#{id}")
    void delete(Integer id);


}

newCodeMoreWhite.png
    @Test
    void testMapper(){

        //getDepartments
//        Collection<Department> departments = departmentMapper.getDepartments();
//        for (Department d:departments) {
//            System.out.println(d);
//        }

        //departmentById
        Department departmentById = departmentMapper.getDepartmentById(101);
//        System.out.println(departmentById);

        //save
//        Employee employee=new Employee("FF","[email protected]",0,101,new Date());
//        employeeMapper.save(employee);

        //updateEmp
//        Employee employee=new Employee("FF","[email protected]",1,101,new Date());
//        employee.setId(6);
//        employeeMapper.updateEmp(employee);

        //delete
//        employeeMapper.delete(6);

        //getAll
        List<Employee> all = employeeMapper.getAll();
        for (Employee e:all) {
            System.out.println(e);
        }



    }
newCodeMoreWhite.png

controller

  • EmployeeController
package com.kuang.controller;

import com.kuang.mapper.DepartmentMapper;
import com.kuang.mapper.EmployeeMapper;
import com.kuang.pojo.Department;
import com.kuang.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.Collection;

@Controller
public class EmployeeController {
    //
    @Autowired
    EmployeeMapper employeeDao;

    @Autowired
    DepartmentMapper departmentDao;

    @GetMapping("/emps")
    public String list(Model model){

        model.addAttribute("departmentDao",departmentDao);

        Collection<Employee> employees = employeeDao.getAll();
        model.addAttribute("emps",employees);
        return "emp/list";
    }

    @GetMapping("/emp")
    public String toAddpage(Model model) {
        //查出所有部门信息
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("departments",departments);
        return "emp/add";
    }


    @PostMapping("/emp")
    public String addpage(Employee employee) {

        employeeDao.save(employee);//调用底层 保存
        //添加的操作
        return "redirect:/emps";
    }


    @GetMapping("/emp/{id}")
    public String toUpdatePage(@PathVariable("id") Integer id, Model model) {
        //查出原来的数据
        Employee employee = employeeDao.getEmployeeById(id);
        model.addAttribute("employee", employee);
        //查出所有部门信息
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("departments",departments);
        return "emp/update";
    }

    @PostMapping("/updateEmp")
    public String updateEmp(Employee employee) {
        employeeDao.updateEmp(employee);
        return "redirect:/emps";
    }


    @GetMapping("/delEmp/{id}")
    public String delEmp(@PathVariable("id") Integer id) {
        employeeDao.delete(id);
        return "redirect:/emps";
    }
}

newCodeMoreWhite.png
  • IndexController
package com.kuang.controller;

import com.kuang.mapper.DepartmentMapper;
import com.kuang.mapper.EmployeeMapper;
import com.kuang.pojo.Department;
import com.kuang.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.Collection;

@Controller
public class EmployeeController {
    //
    @Autowired
    EmployeeMapper employeeDao;

    @Autowired
    DepartmentMapper departmentDao;

    @GetMapping("/emps")
    public String list(Model model){

        model.addAttribute("departmentDao",departmentDao);

        Collection<Employee> employees = employeeDao.getAll();
        model.addAttribute("emps",employees);
        return "emp/list";
    }

    @GetMapping("/emp")
    public String toAddpage(Model model) {
        //查出所有部门信息
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("departments",departments);
        return "emp/add";
    }


    @PostMapping("/emp")
    public String addpage(Employee employee) {

        employeeDao.save(employee);//调用底层 保存
        //添加的操作
        return "redirect:/emps";
    }


    @GetMapping("/emp/{id}")
    public String toUpdatePage(@PathVariable("id") Integer id, Model model) {
        //查出原来的数据
        Employee employee = employeeDao.getEmployeeById(id);
        model.addAttribute("employee", employee);
        //查出所有部门信息
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("departments",departments);
        return "emp/update";
    }

    @PostMapping("/updateEmp")
    public String updateEmp(Employee employee) {
        employeeDao.updateEmp(employee);
        return "redirect:/emps";
    }


    @GetMapping("/delEmp/{id}")
    public String delEmp(@PathVariable("id") Integer id) {
        employeeDao.delete(id);
        return "redirect:/emps";
    }
}

newCodeMoreWhite.png
  • LoginController
package com.kuang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpSession;


@Controller
public class LoginController {
    @GetMapping("user/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password,
                        Model model, HttpSession session){
        //具体的业务
        if(StringUtils.hasLength(username)&&"123456".equals(password)){
            session.setAttribute("loginUser",username);
            return "redirect:/main.html";
        }else {
            //告诉用户,你登录失败了
            model.addAttribute("msg","用户名或密码错误");
            return "index";
        }

    }

    @RequestMapping("/user/logout")
    public String logout(HttpSession session){
       session.invalidate();
       return "redirect:/index.html";
    }

}

newCodeMoreWhite.png

config

  • LoginHandlerInterceptor
package com.kuang.config;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser == null) {
            request.setAttribute("msg","没有权限,请先登录");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        }
        return true;
    }
}

newCodeMoreWhite.png
  • MyLocaleResolver
package com.kuang.config;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;


public class MyLocaleResolver implements LocaleResolver {

    //解析请求
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        //获取请求中的语言参数
        String l = request.getParameter("l");

        //如果没有就使用默认的
        Locale locale = Locale.getDefault();

        //如果请求的链接携带了国际化的参数
        if (!StringUtils.isEmpty(l)) {
            String[] split = l.split("_");
            //语言 国家
            locale = new Locale(split[0], split[1]);
        }


        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

    }
}

newCodeMoreWhite.png
  • MyMvcConfig
package com.kuang.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//如果 你想自定义一些定制化的功能,只要写这个组件,然后将它交给springboot,springboot就会帮我们自动装配
//扩展springmvc

//如果我们要扩展springmvc,官方建议我们这样做
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    //视图跳转
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 浏览器发送/test , 就会跳转到test页面;
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");
    }

    //自定义的国际化生效
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }

//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(new LoginHandlerInterceptor())
//                .addPathPatterns("/**")
//                .excludePathPatterns("/","/index.html", "/user/login","/css/*","/js/*","/img/*","/dashboard.html");
//    }
}


newCodeMoreWhite.png

前端页面模板

在这里插入图片描述

  • login.properties
login.tip=请登录
login.btn=登录
login.password=密码
login.remeber=记住我
login.username=用户名
  • login_en_US.properties
login.tip=Please sign in
login.btn=Sign in
login.password=Password
login.remember=Remeber me
login.username=Username
  • login_zh_CN.properties
login.tip=请登录
login.btn=登录
login.password=密码
login.remember=记住我
login.username=用户名

templates 页面 main

index.html

<body class="text-center">
		<form class="form-signin" th:action="@{/user/login}">
			<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">
			<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>

			<!--如果msg为空,则不显示消息-->
			<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>


			<label class="sr-only">Username</label>
			<input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
			<label class="sr-only">Password</label>
			<input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required="">
			<div class="checkbox mb-3">
				<label>
          <input type="checkbox" value="remember-me"> [[#{login.remember}]]
        </label>
			</div>
			<button class="btn btn-lg btn-primary btn-block" type="submit"> [[#{login.btn}]] </button>
			<p class="mt-5 mb-3 text-muted">© 2020-2030  </p>
			<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
			<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
		</form>

	</body>
newCodeMoreWhite.png
  • add.html
        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <form th:action="@{/emp}" method="post">
                <div class="form-group">
                    <label>LastName</label>
                    <input type="text" name="lastName" class="form-control" placeholder="海绵宝宝">
                </div>
                <div class="form-group">
                    <label>Email</label>
                    <input type="email" name="email" class="form-control" placeholder="[email protected]">
                </div>
                <div class="form-group">
                    <label>Gender</label><br>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="gender" value="1">
                        <label class="form-check-label">男</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="gender" value="0">
                        <label class="form-check-label">女</label>
                    </div>
                </div>
                <div class="form-group">
                    <label>department</label>
                    <select class="form-control" name="departmentId">
                        <option th:each="department:${departments}" th:text="${department.getDepartmentName()}" th:value="${department.getId()}"></option>
                    </select>
                </div>
                <div class="form-group">
                    <label>Birth</label>
                    <input type="text" class="form-control" placeholder="2019-1-1" name="birth">
                </div>
                <button type="submit" class="btn btn-primary">添加</button>
            </form>
        </main>

newCodeMoreWhite.png
  • list.html
				<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
					<h2><a class="btn btn-sm btn-success" th:href="@{/emp}">添加员工</a> </h2>
					<div class="table-responsive">
						<table class="table table-striped table-sm">
							<thead>
								<tr>
									<th>id</th>
									<th>lastName</th>
									<th>email</th>
									<th>gender</th>
									<th>department</th>
									<th>birth</th>
									<th>操作</th>
								</tr>
							</thead>
							<tbody>
								<tr th:each="emp:${emps}">
									<td th:text="${emp.getId()}"></td>
									<td th:text="${emp.getLastName()}"></td>
									<td th:text="${emp.getEmail()}"></td>
									<td th:text="${emp.getGender()==0?'女':'男'}"></td>
									<td th:text="${departmentDao.getDepartmentById(emp.getDepartmentId()).getDepartmentName()}">
									</td>
									<td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}"></td>
									<td>
										<a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.getId()}">编辑</a>
										<a class="btn btn-sm btn-danger" th:href="@{/delEmp/}+${emp.getId()}">删除</a>
									</td>
								</tr>
							</tbody>

						</table>
					</div>
				</main>

newCodeMoreWhite.png
  • update.html
        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <form th:action="@{/updateEmp}" method="post">
                <input type="hidden" name="id" th:value="${employee.getId()}">

                <div class="form-group">
                    <label>lastName</label>
                    <input th:value="${employee.getLastName()}" type="text" name="lastName" class="form-control" placeholder="海绵宝宝">
                </div>
                <div class="form-group">
                    <label>Email</label>
                    <input th:value="${employee.getEmail()}" type="email" name="email" class="form-control" placeholder="[email protected]">
                </div>
                <div class="form-group">
                    <label>Gender</label><br>
                    <div class="form-check form-check-inline">
                        <input th:checked="${employee.getGender() == 1}" class="form-check-input" type="radio" name="gender" value="1">
                        <label class="form-check-label">男</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input th:checked="${employee.getGender() == 0}" class="form-check-input" type="radio" name="gender" value="0">
                        <label class="form-check-label">女</label>
                    </div>
                </div>
                <div class="form-group">
                    <label>department</label>
                    <select class="form-control" name="departmentId">
                        <option th:each="department:${departments}" th:selected="${department.getId() == employee.getDepartmentId()}"  th:text="${department.getDepartmentName()}" th:value="${department.getId()}"></option>
                    </select>
                </div>
                <div class="form-group">
                    <label>Birth</label>
                    <input th:value="${#dates.format(employee.getBirth(),'yyyy-MM-dd')}" type="text" class="form-control" placeholder="2019-1-1" name="birth">
                </div>
                <button type="submit" class="btn btn-primary">保存</button>
            </form>
        </main>

newCodeMoreWhite.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK