Spring入门详解


Core Technologies :: Spring Framework

Spring Framework

Spring IoC

  • Inversion of Control
    • 控制反转,一种面向对象的编程思想,将类与类之间的依赖关系交给容器进行处理
    • 减少Bean之间的耦合度
    • 被Spring管理的bean默认是单例的
  • Dependency Injection
    • 依赖注入,IoC思想的实现方式
    • 在需要使用某一对象时,无需创建该对象,依赖于外部容器,由外部容器创建后传递进来
  • IoC Container
    • IoC容器,实现依赖注入的关键
    • 本质上是一个工厂,用来管理所有的对象以及依赖关系
    • org.springframework.beans 和 org.springframework.context都是IoC Container
      • 开发时主要使用org.springframework.context.ApplicationContext接口,负责实例化、配置和组装beans.

image.png

Spring IoC注解

注解解释
@Autowired用于注入Bean,该注解能写在成员变量、Set方法、构造器中> ⚠️:在Spring Framework4.3以后,@Autowired 如果目标bean一开始只定义一个构造函数,则不再需要对此类构造函数进行注解,但是如果有多个构造函数可用,并且没有默认构造函数,则必须至少对其中一个构造函数进行注解,以便于指示容器使用哪一个构造函数。
@Qualifier用于声明Bean的名称,可以引用Bean的自定义名称,也可以引用默认名称(类名首字母改小写)
@Bean用于装配第三方的Bean(Jar包中的Bean等等),也能装配自定义的Bean
@Configuration用于声明配置类,该注解是基于@Component实现的
@Primary优先分配
@Scope默认单例 @Scope(“singleton”)
多个实例 @Scope(“prototype”)

Example

定义数据访问组件AlphaDao、业务组件AlphaService、控制器AlphaController,并通过注解的方式将它们委托给Spring容器,将AlphaDao注入给AlphaService,将AlphaService注入给AlphaController,并在AlphaController中调用AlphaService,以实现查询数据的请求

public interface AlphaDao{
    String select();
}
@Repository("alphaDaoMyBatis")
// 优先装配
@Primary
public class AlphaDaoMybatisImpl implements AlphaDao{
    @Override
    public String select() {
        return "MyBatis";
    }
}
@Service
public AlphaService{
    @Autowired
    private AlphaDao alphaDao;
    public String find(){
        return alphaDao.select();
    }
}
@Controller
@RequestMapping("/alpha")
public AlphaController{
    @Autowired
    private AlphaService alphaService;

    @RequestMapping("data")
    @ResponseBody
    public String getData(){
        return alphaService.find();
    }
}
@Test
public void testApplicationContext(){
    System.out.println(applicationContext);

    AlphaDao alphaDao = applicationContext.getBean(AlphaDao.class);
    System.out.println(alphaDao.select());

    // alphaDao = (AlphaDao) applicationContext.getBean("alphaHibernate");
    alphaDao = applicationContext.getBean("alphaMyBatis", AlphaDao.class);
    System.out.println(alphaDao.select());
}

Spring MVC

  • 三层架构
    • 表现层、业务层、数据访问层
  • MVC(主要解决表现层问题)
    • Model:模型层
    • View:视图层
    • Controller:控制层
    • image.png
  • 核心组件
    • 前段控制器:DispatcherServlet
    • image.png
    • 具体流程:
      image.png

Controller处理请求与响应

处理GET及POST类型的请求
// GET请求
// students?current=1&limit=20
@RequestMapping(path = "/students", method = RequestMethod.GET)
@ResponseBody
// 参数名保持一致即可匹配,没有参数需要加注解
public String getStudents(
        // 参数注入
        @RequestParam(name = "current", required = false, defaultValue = "1") int current,
        @RequestParam(name = "limit", required = false, defaultValue = "10") int limit){
    System.out.println(current);
    System.out.println(limit);
    return "some students";
}
// /student/123
@RequestMapping(path = "/student/{id}", method = RequestMethod.GET)
@ResponseBody
public String getStudent(@PathVariable("id") int id){
    System.out.println(id);
    return "a student";
}

// POST请求
@RequestMapping(path = "/student", method = RequestMethod.POST)
@ResponseBody
// 参数名与html中表单input属性名对应
// http://localhost:8080/community/html/student.html
public String saveStudent(String name, int age){
    System.out.println(name);
    System.out.println(age);
    return "success";
}
向浏览器响应HTML格式的数据
// 响应HTML数据,由前端控制器调度,需返回model和view
@RequestMapping(path = "/teacher", method = RequestMethod.GET)
public ModelAndView getTeacher(){
    ModelAndView mav = new ModelAndView();
    mav.addObject("name", "张三");
    mav.addObject("age",30);
    // 设置templates下的模版,不用写.html
    mav.setViewName("/demo/view");
    return mav;
}
// 前端控制器实例化model,返回view视图
@RequestMapping(path = "school", method = RequestMethod.GET)
public String getSchool(Model model){
model.addAttribute("name", "nku");
    model.addAttribute("age", 110);
    // 返回view.html 动态模版
    return "/demo/view";
}
向浏览器响应JSON格式的数据
// 响应JSON(异步请求)
// Java对象 -> JSON字符串 -> JS对象
@RequestMapping(path = "/emp", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getEmp(){
    Map<String, Object> emp = new HashMap<>();
    emp.put("name", "zhangsan");
    emp.put("age", 21);
    return emp;
}

@RequestMapping(path = "/emps", method = RequestMethod.GET)
@ResponseBody
public List<Map<String, Object>> getEmps(){
    List<Map<String, Object>> list = new ArrayList<>();
    Map<String, Object> emp = new HashMap<>();
    emp.put("name", "zhangsan");
    emp.put("age", 21);
    list.add(emp);

    emp = new HashMap<>();
    emp.put("name", "lisi");
    emp.put("age", 11);
    list.add(emp);
    return list;
}

Spring MVC注解

注解使用解释
@ResponseBody@ResponseBody可以用于同步请求和异步请求中。
当你在控制器(Controller)方法上使用@ResponseBody注解时,Spring MVC会将方法的返回值作为响应体(Response Body)直接写入HTTP响应中,而不会通过视图解析器(View Resolver)解析成视图(View)。这在处理AJAX请求(异步请求)时非常有用,但也可以用于同步请求中。
@RequestMapping@RequestMapping(path = “/student/{id}”, method = RequestMethod.GET)可以声明类或方法的访问路径,还可以声明请求的方式
@PathVariable@RequestMapping(path = “/student/{id}”, method = RequestMethod.GET)
public String getStudent(@PathVariable(“id”) int id){}
可以将请求路径中的参数,绑定到控制器中方法的参数
@RequestParampublic String getStudents(
@RequestParam(name = “current”, required = false, defaultValue = “1”) int current, @RequestParam(name = “limit”, required = false, defaultValue = “10”) int limit
){}
可以将请求对象中的参数,绑定到控制器中方法的参数
@Value// 从application.properties中获取domain
@Value(“${community.path.domain}”)
private String domain;
用于注入外部化属性
@PostConstruct
@PostDestroy
@PostConstruct
public void init(){
System.out.println(“init AlphaService”);
}
@PreDestroy
public void destroy(){
System.out.println(“销毁 AlphaService”);
}
设置构造之后调用和销毁前调用的方法

Thymeleaf

  • 模版引擎:根据模版文件和Model生成动态的HTML
  • ${name}表达式是在服务器返回的Modle中提取返回值,所以是在Response中提取,而Request是从浏览器向服务端发送的请求,而我们在服务端接收到Request请求后通过requestMapping映射到controller中的方法中的参数列表来获取到请求参数

Thymeleaf加载动态模版

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<p th:text="${name}"></p>
<p th:text="${age}"></p>
// 响应HTML数据,由前端控制器调度,需返回model和view
@RequestMapping(path = "/teacher", method = RequestMethod.GET)
public ModelAndView getTeacher(){
    ModelAndView mav = new ModelAndView();
    // 属性名与html模版中的表单对应
    mav.addObject("name", "张三");
    mav.addObject("age",30);
    // 设置templates下的模版,不用写.html
    mav.setViewName("/demo/view");
    return mav;
}
// 前端控制器自动实例化model,返回view视图
@RequestMapping(path = "school", method = RequestMethod.GET)
public String getSchool(Model model){
    model.addAttribute("name", "nku");
    model.addAttribute("age", 110);
    // 返回view.html 动态模版
    return "/demo/view";
}

细节

  • 遍历集合: th:each=“obj:${list}”

Ref

Tutorial: Using Thymeleaf

Mybatis

核心组件

  • SqlSessionFactory:用于创建SqlSession的工厂类
  • SqlSession:Mybatis的核心组件,用于向数据库执行SQL
  • 主配置文件:XML配置文件,可以对MyBatis的底层行为做出详细的配置
Mapper接口

DAO接口,只需要写接口就行,由Mapper映射器实现
Mapper接口用于定义数据库访问行为,但它不一定需要使用@Mapper注解进行标记。除了使用 @Mapper注解,还可以通过在配置文件(如mybatis-config.xml)中添加对应的Mapper接口类来注册
注入UserMapper即可使用

package com.nowcoder.community.dao;

import com.nowcoder.community.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper {
    User selectById(int id);

    User selectByName(String username);

    User selectByEmail(String email);

    int insertUser(User user);

    int updateStatus(int id, int status);

    int updateHeader(int id, String headerUrl);

    int updatePassword(int id, String password);
}
Mapper映射器

用于编写SQL,并将SQL和实体类映射的组件,采用XML、注解均可实现

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace属性,用于声明该配置文件所对应的接口 -->
<mapper namespace="com.nowcoder.community.dao.UserMapper">
  <!-- 用于定义可以复用的SQL片段 -->
  <sql id="insertFields">
    username, password, salt, email, type, status, activation_code, header_url, create_time
  </sql>
  <sql id="selectFields">
    id, username, password, salt, email, type, status, activation_code, header_url, create_time
  </sql>
  <!-- 与方法名对应-->
  <!-- 可以利用resultType属性声明返回值类型 -->
  <select id="selectById" resultType="User">
    select <include refid="selectFields"></include>
    from user
    where id = #{id}
  </select>

  <select id="selectByName" resultType="User">
    select <include refid="selectFields"></include>
    from user
    where username = #{username}
  </select>

  <select id="selectByEmail" resultType="User">
    select <include refid="selectFields"></include>
    from user
    where email = #{email}
  </select>
	<!-- 利用parameterType声明传入参数类型,
  keyProperty用于指定主键在POJO中对应的属性名,需要配合数据库的自增主键来使用。-->
  <!-- #{username}用于从传入参数中获取username字段的值 -->
  <insert id="insertUser" parameterType="User" keyProperty="id">
    insert into user (<include refid="insertFields"></include>)
    values(#{username}, #{password}, #{salt}, #{email}, #{type}, #{status}, #{activationCode}, #{headerUrl}, #{createTime})
  </insert>

  <update id="updateStatus">
    update user set status = #{status} where id = #{id}
  </update>

  <update id="updateHeader">
    update user set header_url = #{headerUrl} where id = #{id}
  </update>

  <update id="updatePassword">
    update user set password = #{password} where id = #{id}
  </update>

</mapper>
注解
  • 在编写MyBatis的Mapper接口时,可以用@Param注解为参数取别名,当方法只有一个参数时,并且该参数应用在上时,就必须用@Param注解为该参数取别名
Ref

mybatis – MyBatis 3 | 入门

SpringBoot

Spring Boot整合Mybatis配置文件

  • 在Spring Boot中,已经内置了对多种连接池的支持,如HikariCP、Tomcat JDBC Connection Pool等。所以在Spring Boot环境中,可以通过DataSourceProperties对连接池进行配置。
# ServerProperties
server.port=8080
server.servlet.context-path=/community

# ThymeleafProperties
# close cache in development
spring.thymeleaf.cache=false

# DataSourceProperties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/community?characterEncoding=utf-8&useSSL=false&serverTime=Hongkong
spring.datasource.username=root
spring.datasource.password=***
# connect pool
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.maximum-pool-size=15
# Minimum idle connection
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000

# MybatisProperties
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.nowcoder.community.entity
mybatis.configuration.use-generated-keys=true
# header_url <==> headerUrl 🌟
# 带下划线的字段是数据库的字段,驼峰命名则是JavaEntity
mybatis.configuration.map-underscore-to-camel-case=true
  
# logger 日志级别,debug
# logging.level.com.nowcoder.community=debug

mybatis-spring –

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yyy_jin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值