Spring Boot 学习笔记(一)

自动配置原理

思维导图
  SpringBoot所有的自动配置都是在启动的时候扫描并加载spring.factories中的所有xxxxxAutoConfiguration自动配置类,而自动配置类是否生效则看是否满足条件。我们可以通过引入对应的start依赖使自动配置类生效。
  application.yaml(application.properties)文件中进行手动配置,不进行配置则会使用默认的配置属性。在SpringBoot启动时自动加载了大量的xxxxxAutoConfiguration自动配置类,而这些类中存在对应的xxxProperties配置类,里面的属性与我们将要配置的application.yaml文件中的属性对应。

SpringApplication.run()

  • 判断是web项目还是普通的项目
  • 推断并找到当前的主类
  • 找到所有的监听器设置到listener属性中

application.yaml

SpringBoot推荐使用的配置文件。

  • 可为类的属性注入值,类上使用@ConfigurationProperties(prefix="xxx")注解与配置文件绑定,导入依赖开启提示功能
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<optional>true</optional>
</dependency>
  • 可配置多个环境
server:
  port: 8080
spring:
  profiles:
    active: dev  # 使用的环境
---
server:
  port: 8081
spring:
  profiles: dev
---
server:
  port: 8082
spring:
  profiles: test

静态资源

  • 存放位置"classpath:/META-INF/resources/""classpath:/resources/""classpath:/static/""classpath:/public/"
  • 默认首页使用index.html命名,创建在静态资源包下

扩展配置

以WebMvc配置为例,转自2.3.1版本官方文档
(如果使用自定义的类进行配置加上@Bean交给SpringBoot)

  If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.

  If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.

  If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.

CRUD实验

Thymeleaf

  • 导入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  • template包下的静态资源文件,只能由controller层的请求进行访问,同时要记得导入模板引擎
  • thymeleaf使用文档
  • 抽取html中的公共部分使用th:fragmentth:replace()中可以传递参数

定制首页

  • 首页位置
    在这里插入图片描述
  • 首页转发
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 配置首页视图
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/login.html").setViewName("login");
    }
}

国际化

  • 创建i18n文件
    i18n文件
  • 配置文件
spring:
  # 国际化配置
  messages:
    basename: i18n.login
  • 页面通过thymeleaf获取值
  • 在请求中加入国际化所需的参数
<a th:href="@{/index.html(l='zh_CN')}">中文</a>
<a th:href="@{/index.html(l='en_US')}">English</a>
  • 自定义LocaleResolver
public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        // 获取请求参数
        String language = httpServletRequest.getParameter("l");
        // 若果没有请求参数采用默认值
        Locale locale = Locale.getDefault();
        // 请求参数不为空
        if (!StringUtils.isEmpty(language)){
            // 分割语言和地区
            String[] s = language.split("_");
            locale = new Locale(s[0], s[1]);
        }
        return locale;
    }
    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
    }
}
  • 记得在自定义的WebMvcConfigurer配置类中注册组件
@Bean
public LocaleResolver localeResolver() {
    return new MyLocaleResolver();
}

拦截器

  • 自定义拦截器
public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object user = request.getSession().getAttribute("user");
        if (user == null) {
            request.setAttribute("msg", "还没有登录,请先登录");
            request.getRequestDispatcher("/login.html").forward(request, response);
            return false;
        } else {
            return true;
        }
    }
}
  • 同样记得加入到定义的WebMvcConfigurer配置类中
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginHandlerInterceptor()).
            addPathPatterns("/**").
            excludePathPatterns("/index.html", "/", "/user/login", "/css/**", "/js/**", "/img/**");
}

实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;  //0:女  1:男
    private Department department;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
    private Integer id;
    private String departmentName;
}

查询所有

  • 操作数据库查询,由于Employee实体类中的department属性是对象,所以采用一对一的查询方式,通过d_id查询department表,将查询的结果赋值给department属性
public interface EmployeeMapper {
    @Select("select * from employee")
    @Results({
            // property:为employee类中对应的字段
            // column:为数据库中对应的字段并作为参数传给后面的方法
            // one:一对一查询
            @Result(property = "department", column = "d_id", one = @One(select = "com.diana.mapper.DepartmentMapper.getDeptById"))
    })
    List<Employee> getEmps();
}
public interface DepartmentMapper {
    @Select("select * from department where id=#{id}")
    Department getDeptById(Integer id);
}
  • 编写controller代码
@Controller
public class EmployeeController {

    @Autowired
    EmployeeMapper employeeMapper;

    @GetMapping("/emps")
    public String getEmps(Model model){
        List<Employee> emps = employeeMapper.getEmps();
        model.addAttribute("emps", emps);
        return "emp/list";
    }
}
  • 前端页面获取数据
<tr th:each="emp:${emps}">
	<td th:text="${emp.id}"></td>
	<td th:text="${emp.lastName}"></td>
	<td th:text="${emp.email}"></td>
	<td th:text="${emp.gender==0?'':''}"></td>
	<td th:text="${emp.department.departmentName}"></td>
</tr>

增加

  • 通过GET请求访问添加页面,部门使用下拉框,所以将数据库中的所有部门查询后,传递过去
// 前往添加员工页面
@GetMapping("/emp")
public String toAddEmpPage(Model model){
   List<Department> depts = departmentMapper.getDepts();
   model.addAttribute("depts", depts);
   return "emp/add";
}
// 获取所有部门
@Select("select * from department")
List<Department> getDepts();
  • 通过POST请求从页面获取信息,注意页面中的name属性值要与实体类属性值保持一致
// 添加员工
@PostMapping("/emp")
public String addEmp(Employee employee){
    employeeMapper.addEmp(employee);
    return "redirect:/emps";
}
// 添加员工
@Insert("insert into employee(lastName,email,gender,d_id) values(#{lastName},#{email},#{gender},#{department.id})")
int addEmp(Employee employee);

更新

  • 通过路径参数获取更新的员工id
<a class="btn btn-sm btn-primary" th:href="@{/update/}+${emp.id}">编辑</a>
  • 编写前往更新页面的方法,考虑数据回显
// 前往更新员工页面
@GetMapping("/update/{id}")
public String toUpdateEmpPage(@PathVariable("id") Integer id, Model model){
    // 数据回显
    Employee emp = employeeMapper.getEmpById(id);
    model.addAttribute("emp", emp);

    List<Department> depts = departmentMapper.getDepts();
    model.addAttribute("depts", depts);

    return "emp/update";
}
// 通过id查找员工
@Select("select * from employee where id=#{id}")
@Results({
        @Result(property = "department", column = "d_id", one = @One(select = "com.diana.mapper.DepartmentMapper.getDeptById"))
})
Employee getEmpById(Integer id);
  • 更新员工信息
// 更新员工信息
@PostMapping("/update")
public String updateEmp(Employee employee){
    employeeMapper.updateEmp(employee);
    return "redirect:/emps";
}
// 更新员工信息
@Update("update employee set lastName=#{lastName},email=#{email},gender=#{gender},d_id=#{department.id} where id=#{id}")
int updateEmp(Employee employee);

删除

// 删除员工
@GetMapping("/delete/{id}")
public String delEmp(@PathVariable("id") Integer id){
    employeeMapper.delEmp(id);
    return "redirect:/emps";
}
// 删除员工
@Delete("delete from employee where id=#{id}")
int delEmp(Integer id);

一对多查询 一个部门所有的员工

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

    private List<Employee> employees;
}
// 一对多查询Dept
// 通过dept的id查找emps
    @Select("select * from employee where d_id=#{deptId}")
    List<Employee> getEmpByDeptId(Integer deptId);
//一对多查询以dept的id为参数调用"com.diana.mapper.EmployeeMapper.getEmpByDeptId"方法查询emp
    @Select("select * from department where id=#{id}")
    @Results({
    		// 查询id
            @Result(property = "id", column = "id"),
            // 以部门id为参数查询员工
            @Result(property = "employees", column = "id", many = @Many(select = "com.diana.mapper.EmployeeMapper.getEmpByDeptId"))
    })
    Department getDeptAndEmp(Integer id);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值