目录
[1、 B/S开发架构](#1、 B/S开发架构)
[二、 mybatis框架](#二、 mybatis框架)
[三、 CRUD接口的实现](#三、 CRUD接口的实现)
前言
Java后端最主流标配(企业 90% 业务项目)
核心框架:SpringBoot + MyBatis / MyBatis-Plus
- SpringBoot:负责整体项目框架、Web 接口、依赖、配置、事务
- MyBatis:负责数据库操作、SQL 映射
- MyBatis-Plus(MP):MyBatis 增强版,简化增删改查,现在用得更多
搭配常用组件:Redis、MySQL、Nginx、MQ、SpringCloud(微服务)。
一、 springboot 框架
1 、 B/S 开发架构

(1)浏览器发送请求
(2)服务器(tomcat)接收请求
(3)服务器处理请求
(4)服务器发送响应
(5)浏览器接收响应
(6)浏览器渲染页面
通信协议是
url= 协议://主机:端口号/资源在服务器上路径
2 、什么是 springboot 框架
(1)介绍
spring框架:它是一个java企业级开发的核心框架,主要目的是降低开发难度,提升开发效率。
spring框架的核心功能: ioc和aop
springboot框架:它是spring框架的简化框架。
springboot框架的优点:约定大于配置,开箱即用。
(2)springboot项目搭建
推荐使用idea官网搭建,可以手动修改版本(刷新pom)
java
<!--web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
包含:核心启动器, json数据处理, tomcat服务器, web开发工具, mvc分层开发
最后运行启动类即可。
- 为什么运行springboot启动类的main方法后就可以把web应用启动了?
- 关键就是刚刚引入的那个依赖,因为springboot项目里引入了spring-boot-starter-web的起步依赖:里面包含了web应用开发所需要的常见依赖,同时它里面还包含了tomcat服务器的启动依赖。因此在启动项目时就会把tomcat服务器启动,而它监听的端口号是8080(可以在控制台中找到),所以我们可以通过localhost:8080访问(因此springboot项目内嵌了一个tomcat服务器)
(3) IOC
控制反转:将对象的创建交给spring容器,并由容器管理。@Component注解
(4) DI
依赖注入:和ioc表达的是同一事物。两对象之间有依赖关系, a对象中需要使用b对象, a依赖b。 @Autowired注解
(5)配置文件
<application.properties>和application.yml修改服务器端口号8080
二、 mybatis 框架
(1)数据库准备表
先在MySQL里创建数据库和相应的表
(2)搭建mybatis框架
在pom.xml中导入依赖
mysql驱动
java
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
mybatis驱动
java
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
配置application.properties文件,连接数据库
java
#配置数据库连接信息
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
(4)定义实体类
引入lombok的依赖------帮助创建实体类(在pojo包下创建实体类)
创建springboot项目时,在developer tools那里勾选Lombok
实体类中的基本数据类型建议使用包装类,否则会有默认值。如:Integer id
在实体类上加@Data、@NoArgsConstructor、@AllArgsConstructor注解就不用再写get和set方法了
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User{
private Integer id;
private String username;
private String password;
private String name;
private Integer age;
private LocalDateTime updateTime;
}
(5)CRUD操作
java
package com.example.yanglaoheda.mapper;
import com.example.yanglaoheda.domain.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper {
//添加新用户
@Insert("insert into user values(null,#{username},#{password},#{name},# {tel})")
int addUser(User user);
//查询用户
@Select("select * from user where id=#{id}")
User selectUserById(int id);
//查询所有用户
@Select("select * from user")
List<User> selectAllUser();
//修改用户信息
@Update("update user set username=#{username} , password=#{password},name=# {name},tel=#{tel} where id=#{id}")
int updateUser(User user);
//删除用户
@Delete("delete from user where id=#{id}")
int deleteUserById(int id);
}
三、 CRUD 接口的实现
1、分层解耦---三层架构
在软件设计时:要尽量让每个接口、每个类、每个方法职责单一,只做一件事
springmvc将代码分层,分为三层,分别是:
controller是控制层,接收请求,调用service层进行请求的处理;
service是业务层,处理请求(可能需要调用mapper操作数据库);
mapper是持久层,对数据库进行操作;

思考:三层架构为什么是面向接口型?
因为可能会有多种实现,需要接口来定义统一的规范。比如:Dao数据访问,可能直接访问当前目录,可能访问数据库,也可能读取网络上的数据。不同方式的获取对应不同的Dao
java
main
|---java
| |
| |---包名
| |----controller包
| |---controller类
| |----service包
| |---service接口
| |---Impl包
| |----service实现类
| |----dao包
| |---dao接口
| |---Impl包
| |----dao实现类
| |----pojo包
| |---实体类
| |----项目启动类
耦合:衡量软件中各个层/各个模块的依赖关联程度
内聚:软件中各个功能模块内部的功能联系
软件设计原则:高内聚,低耦合
2、如何实现分层解耦
**·**控制反转:Inversion Of Controller,简称IOC。是Spring框架的第一大核心。是指:对象的创建控制权由程序自身转移到外部容器,由容器来创建对象,而不需要在程序中手动创建
**·**依赖注入:Dependency Injection,简称DI。是指:容器为应用程序提供运行时所依赖的资源。
**·**Bean对象:IOC容器中创建、管理的对象
3、如何实现IOC和DI
(1)将Dao和Service层的实现类交给IOC容器管理:直接在实现类上面加@Component注解
(2)为Controller以及Service注入运行时所依赖的对象:在注入对象时就不能直接new了,而是在声明的成员变量上面加@Autowired(应用程序运行时,会自动去IOC容器里查询该类型的bean对象,并赋值给该成员变量)
拓展IOC和DI
1、要把某个类的对象交给IOC容器管理,就需要在该类上加以下注解:
| @Component | 声明bean的基础注解 | 不属于以下三类时用此注解 |
|---|---|---|
| @Controller | 衍生注解 | 控制层上加 |
| @Service | 衍生注解 | 业务层的实现类上加 |
| @Repository | 衍生注解 | 数据访问层的实现类上加 |
因为@RestController=@Controller+@ResponseBody,已经包含了@Controller
要想声明bean的四大注解生效,还需要被组件扫描注解@ComponentScan扫描。而在启动类上声明的@SpringBootApplication注解中,底层包含了@ComponentScan注解,且默认扫描的范围是启动类所在包及其子包
2、@Autowired注解:默认是按照类型进行注入的,如果IOC容器中存在多个相同类型的bean对象就会报错(即一个接口多个实现类),如何解决?
法一:在想要获取的实现类上加@Primary注解
法二:在注入的成员变量上面加注解@Autowired+@Qualifier("指定实现类名称")
法三:在注入的成员变量上面加注解@Resource(name="指定实现类名称")

@Resource和@Autowired的区别
- @Resource是JavaEE提供的注解,@Autowired是Spring框架提供的注解
- @Autowired默认按照类型注入,@Resource默认按照名称注入
3、注意:是面向接口编程,这意味着注入的bean对象都是接口,而不是其实现类。如果想要用哪个实现类就在上面加@Service注解,把该实现类加入到IOC容器统一管理
4、具体实现
(1)Service层
业务处理:调用mapper完成crud
java
package com.example.yanglaoheda.service;
import com.example.yanglaoheda.domain.User;
import com.example.yanglaoheda.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
//添加用户业务
public int saveUser(User user){
return userMapper.addUser(user);
}
//查询单个用户的业务
public User queryUser(int id){
return userMapper.selectUserById(id);
}
//查询所有用户的业务
public List<User> queryAllUser(){
return userMapper.selectAllUser();
}
//修改用户的业务
public int updateUser(User user){
return userMapper.updateUser(user);
}
//删除用户的业务
public int deleteUserById(int id){
return userMapper.deleteUserById(id);
}
}
(2)Controller层
java
package com.example.yanglaoheda;
import com.example.yanglaoheda.domain.User;
import com.example.yanglaoheda.service.UserService;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
//添加用户的接口
@PostMapping
public String saveUser(User user){
int i = userService.saveUser(user);
if(i>0){
return "添加用户成功";
}else{
return "添加用户失败";
}
}
//查询某个用户接口
@GetMapping("/one")
public User queryUser(int id){
User user = userService.queryUser(id);
return user;
}
//查询所有用户接口
@GetMapping("/list")
public List<User> queryAll(){
List<User> users = userService.queryAllUser();
return users;
}
//修改用户接口
@PutMapping
public String updateUser(User user){
int i = userService.updateUser(user);
if(i>0){
return "修改成功";
}else {
return "修改失败";
}
}
//删除用户接口
@DeleteMapping
public String deleteUser(int id){
int i = userService.deleteUserById(id);
if(i>0){
return "删除用户成功";
}else {
return "删除用户失败";
}
}
}
注意:服务器为什么会自动将集合数据转为json格式数据给前端?
因为Controller类上面加了@RestController注解,这个注解底层封装了@ResponseBody→作用:它会把Controller的返回值直接作为响应体的数据响应,如果返回值是对象/集合,会先转为json格式再响应
@RestController=@Controller+@ResponseBody
(3)apifox测试接口实现
