Springboot笔记

Springboot结构理解

Controller层:

本层定义接口并调用service层接口方法完成业务逻辑。

功能:

接受前端请求,调用service,接受service返回的数据,之后响应给客户端。

Service层:

service层为业务服务,调用mapper层并提供给controller层使用,间接和数据库打交道。

项目结构包括两部分,接口文件和接口实现类文件,接口文件中定义在controller层中调用的service层方法;接口实现类文件中完成service层接口中定义的方法的实现。

注意:这里接口实现类中方法的实现是指业务逻辑的实现,可能有些方法并不能在实现类里完成真正意义上的实现,还需要在mapper层文件完成其真正意义上的实现(主要是和数据库交互)。

Mapper层:

mapper层为操作数据库的一层。

mapper层分为两部分,mapper接口层和mapper.xml层。

mapper接口层:

定义在service接口中没有完成真正实现,需要通过书写SQL语句才能完成其功能的方法。

mapper.xml层:
(1)配置通用查询映射结果:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nayun.cultourism.mapper.CultureTourismSituationMapper">
<!-- 通用查询映射结果-->
<resultMap id="cultureTourismResultMap" type="com.nayun.cultourism.entity.CultureTourismSituation">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="annual_flow" property="annualFlow"/>
<result column="position" property="position"/>
<result column="illustration" property="illustration"/>
<result column="pic_url" property="picUrl"/>
<result column="creat_user" property="createUser"/>
<result column="creat_dept" property="creatDept"/>
<result column="creat_time" property="creatTime"/>
<result column="update_user" property="updateUser"/>
<result column="update_time" property="updateTime"/>
<result column="status" property="status"/>
<result column="is_deleted" property="isDeleted"/>
<result column="address" property="address"/>
</resultMap>

注意:

  • namespace 和 resultMap 的 type 要指向正确的地址,namespace指向mapper文件,type指向实体类。

  • column为数据库中的表字段,property为实体类中属性名(一一对应)。

关于column以及property命名:

  • column为数据库表字段名,小写,各单词之间用下划线分割。
  • property为实体类中属性名,命名一般符合驼峰形。

(2)完成mapper接口中方法的SQL语句实现:

在这个模块中就是书写具体的SQL语句了,将查询结果映射在方法中的resultMap中,id为在mapper接口中定义的方法名。

<!--查询所有景点数据-->
<select id="findAll" resultMap="cultureTourismResultMap">
select * from cockpit_tourist_spots where is_deleted = 0
</select>
<select id="getList" resultMap="cultureTourismResultMap">
select * from cockpit_tourist_spots where is_deleted = 0
<if test="cultureTourismSituation.name != null and cultureTourismSituation.name != ''">
and name LIKE CONCAT('%',#{cultureTourismSituation.name},'%')
</if>
</select>

Entity层:

也就是所谓的model,也称为pojo层,是数据库在项目中的类,该文件包含实体类的属性和对应属性的set、get方法。

实体类中属性同数据库表字段一一对应,对于相应的set、get方法一般不需要书写,实体类上引入@Data注解,会自动为实体类注入get、set以及toString方法,减少代码量。

VO层:

视图对象,用于展示层,把某个指定页面的所有数据封装起来,方便前端获取数据,后端将前端需要 的数据做整合,打包成一个类。

使用场景:

如果在前端页面需要展示经过某些数据库操作才能展示的特定数据,一般在vo层中把操作过程中涉及的数据进行封装,方便前端获取。并在controller层定义对应接口时把返回类型规定为vo类。

DTO层:

数据对象传输层,负责屏蔽后端实体层,将UI要的数据进行重新定义和封装。因为后端在实际业务场景中需要存储大量数据,而用户需要的数据只是一部分,为了快速获取用户需要的数据,应该把用户经常用到的数据在dto层中进行封装,在调用服务层时,只需要调用一次便可完成所有的逻辑操作。

运行流程:

  1. 控制层接收前端请求,调用对应的业务层接口方法
  2. 业务层实现类去实现业务层接口
  3. 业务层实现类的方法内调用数据层的接口
  4. 数据层实现文件(mapper.xml)实现数据层接口
  5. 然后处理结果层层返回

组合注解@Spring BootApplication 代替@EnableAutoConfiguration和@ComponentScan

@EnableAutoConfiguration
@ComponentScan
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@Spring BootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}

采用@RestController组合注解代替@Controller和@ResponseBody

@Controller
public class BookController {
@GetMapping("/book")
@ResponseBody
public Book book() {
}
}
@RestController
public class BookController {
@GetMapping("/book")
public Book book() {
}
}

基础配置

  • Didiproperties.java
package com.didispace.chapter14;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
//@ConfigurationProperties(prefix= "con")
public class DidiProperties {
/**
* 这是一个测试配置
*/
@Value("${con.from}")//
private String from;
}
  • application.yaml
con:
from: demo
  • HelloController.java
package com.didispace.chapter14;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Data
@RestController
public class HelloController {
@Autowired
DidiProperties didiProperties;
@RequestMapping("/hello")
public String index() {
return didiProperties.getFrom();
}
}

maven中的parent、dependencyManager、dependency的用法和区别

一、parent一般使用场景:

比如有3个项目A、B和C,都要使用到某个相同的jar包,如果都单独引用,后期需要修改,不好维护,此时可以创建一个parent项目P,里面打包方式为pom,不需要编写任何代码,只需要管理jar包,在P项目中,引入公共的jar包,然后在A、B、C项目中,使用parent标签,引入P作为依赖,就可以使用P项目中所有引入的jar包了

二、dependencyManager使用场景:

比如有3个项目A、B和C,A项目使用a.jar,B项目使用b.jar,C 项目使用c.jar,此时用parent标签,会在ABC3个项目中,把3个jar包全部引入
该场景需要用dependencyManager标签,在P项目中,用dependencyManager来维护a,b,c3个jar包,并引入jar包的版本,ABC使用dependency来引入需要的jar包即可

form-data和x-www-form-urlencode区别

  • form-data

就是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来表名文件类型;content-disposition,用来说明字段的一些信息;

由于有boundary隔离,所以multipart/form-data既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件。

  • x-www-form-urlencoded

就是application/x-www-from-urlencoded,会将表单内的数据转换为键值对,比如,name=java&age = 23

  • multipart/form-data与x-www-form-urlencoded区别

multipart/form-data:既可以上传文件等二进制数据,也可以上传表单键值对,只是最后会转化为一条信息; x-www-form-urlencoded:只能上传键值对,并且键值对都是间隔分开的。

spring-servlet.multipart.max-file-size=10MB和spring-servlet.multipart.max-request-size=10MB区别

spring-servlet.multipart.max-file-size:代表单个文件最大大小
spring-servlet.multipart.max-request-size:代表单个请求所有文件最大大小

上传文件

@PostMapping("/uploadtest")
private String uploadtest(MultipartFile file, HttpServletRequest request){
String name=file.getOriginalFilename();
//获取当前服务器运行路径,getRealpath为自定义路径,返回String类自定义路径
String path= request.getServletContext().getRealPath("/upload_resource/");
//创建file类实例用于测试对应路径文件是否存在
File dir=new File(path);
if(!dir.exists())
dir.mkdir();
创建file类实例
File final_file=new File(path+name);
try {
file.transferTo(final_file);
} catch (IOException e) {
throw new RuntimeException(e);
}
return path;

上传文件至项目文件地址:

@PostMapping("/uploadtest")
private String uploadtest(MultipartFile file, HttpServletRequest request){
String name=file.getOriginalFilename();
//path="./xxx/"代表存放在当前目录下,path="/xxx/"代表存放在磁盘根目录下
String path="./upload_resourse/";
File dir=new File(path);
if(!dir.exists())
dir.mkdir();
File final_file=new File(path+name);
try {
//参数为相对路径会自动匹配父路径,改为绝对路径方可
file.transferTo(final_file.getAbsoluteFile());
} catch (IOException e) {
throw new RuntimeException(e);
}
}

Mybatis

  1. 配置

application.properties

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://sh-cynosdbmysql-grp-ggs4362k.sql.tencentcdb.com:20105/Spring
spring.datasource.username=root
spring.datasource.password=aaa235112@
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
  1. Mapper注册

  • Mapper注册
@Mapper //注解Mapper,springboot使用动态实现类自动实现接口中方法
public interface UserMapper {
@Select("select * from user")
public List<User> select();
}
  • MapperScan注册
@SpringBootApplication
@MapperScan("org.springdemo.mapper")//注册 进行扫描指定包路径
public class SpringdemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringdemoApplication.class, args);
}
}
  • 实现
@RestController
public class Usercontroller {
//usermapper注入
@Autowired
private UserMapper userMapper;
@GetMapping("/user")
private List<User> user(){
List<User> list=userMapper.select();
return list;
}
}

关于mybatis和mybatis-plus

  • mybatis可以使用XML或者注解来配置和映射原生信息
  • mybatis-plus在mybtis基础上做了增强,简化开发。实际以后期维护成本为代价换取前期貌似简便整洁的开发
  • 建议:个人小型项目可用MP快速上手开发,大型项目及多表查询尽量使用MB

mybatis 多页查询

  • User.java 实体类
package org.springdemo.entity;
import java.util.List;
@Data
public class User {
private int id;
private String name;
private int age;
private String number;
private List<Order> orders;
}
  • UserMapper.java 映射
package org.springdemo.mapper;
import com.sun.org.glassfish.gmbal.IncludeSubclass;
import org.apache.ibatis.annotations.*;
import org.springdemo.entity.Order;
import org.springdemo.entity.User;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
@Mapper
public interface UserMapper {
//查询用户及对应的订单
@Select("select * from user")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(column = "age",property = "age"),
@Result(column = "number",property = "number"),
@Result(column = "id",property ="orders",javaType = List.class,many = @Many(select = "org.springdemo.mapper.OrderMapper.selectByid"))
})
public List<User> selectAllusersAndorders();
//提供查询订单及对应的用户接口
@Select("select * from user where id = #{id}")
public User selectByid(@PathVariable int id);
}
  • Order.java 实体类
package org.springdemo.entity;
@Data
public class Order {
private int id;
private String name;
private String price;
private String remain;
private User user;
}
  • OrderMapper.java 映射
package org.springdemo.mapper;
import org.apache.ibatis.annotations.*;
import org.springdemo.entity.Order;
import org.springdemo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
@Mapper
public interface OrderMapper {
//查询订单及对应的用户
@Select("select * from `order`")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(column = "price",property = "price"),
@Result(column = "remain",property = "remain"),
@Result(column = "id",property = "user",javaType = User.class,one = @One(select = "org.springdemo.mapper.UserMapper.selectByid"))
})
public List<Order> selectAllorderAnduser();
//提供查询用户及对应的订单接口
@Select("select * from `order` where id = #{id}")
public List<Order> selectByid(@PathVariable int id);
}
  • Controller.java 控制器
package org.springdemo.controller;
import org.springdemo.entity.Order;
import org.springdemo.entity.User;
import org.springdemo.mapper.OrderMapper;
import org.springdemo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class Usercontroller {
//注入
@Autowired
private UserMapper userMapper;
@Autowired
private OrderMapper orderMapper;
@GetMapping("/findOrder")
private List<Order> findOrder(){
return orderMapper.selectAllorderAnduser();
}
@GetMapping("/findUser")
private List<User> findUser(){
return userMapper.selectAllusersAndorders();
}
}
posted @   chuimber  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示