当前位置: 首页 > news >正文

SpringBoot+Spring+MyBatis相关知识点

目录

 

一、相关概念

1.spring框架

2.springcloud

3.SpringBoot项目

4.注解

5.SpringBoot的文件结构

6.启动类原理

二、相关操作

1.Jar方式打包

2.自定义返回的业务状态码

 3.Jackson

4.加载配置文件

5.异常处理

三、优化配置

 1.简化sql语句

2.查询操作

复杂查询

 一对一联表查询

一对多联表查询

小结


 

一、相关概念

1.spring框架

也可称为DI,IoC,AOP框架,相当于是一个容器,每一个对象就是一个bean

对于项目构建过程:Controller -> Service -> Dao

未用框架时,需要实例化service实现类来调用方法

private UserService userService = new UserService();

使用Spring框架后,可通过注解来实现自动装配对象

@Autowire

private UserService userService

2.springcloud

是基于springboot, 只不过是在之前基础上多了几个插件包

3.SpringBoot项目

SpringBoot是一个通过注解简化配置的web开发框架。

有两种创建方式:

本地创建-先创建一个普通maven项目,再参考官方文档:Getting Started | Building an Application with Spring Boot

添加相关maven依赖;

在线创建 -https://start.spring.io/

开发JSON接口,可通过@RestController注解实现,可将要显示的数据序列化成JSON对象.

4.注解

本质是继承Annotation接口,起到说明、配置的作用

常见注解:

@Controller用于标记类是一个控制器,返回页面的时使用,但如果要返回JSON,需要再添加@ResponseBody

@RestController 用于标记类是一个控制器,并返回JSON数据,实现接口返回数据会被序列化为JSON,相当于@Controller+@ResponseBody

@RequestMapping 设置路由映射,为某个方法设置子路径

@GetMapping用于设置get请求查询接口的路径,相当于@RequestMapping(method = RequestMethod.GET)

同理有

@PostMapping = @RequestMapping(method = RequestMethod.POST) @PutMapping = @RequestMapping(method = RequestMethod.PUT)

@DeleteMapping = @RequestMapping(method = RequestMethod.DELETE)

@SpringBootApplication 用于标记是SringBoot应用,里面包含多个子注解,相当于@Configuration(spring扫描注入)+@EnableAutoConfiguration(自动载入所需Bean)+@ComponentScan(spring扫描包的范围)

@Component标记这个是一个组件,相当于在启动类中添加@Bean,new一个对象

@Scheduled注解是一个定时任务注解,可以在方法上添加,表示这个方法是一个定时任务方法

5.SpringBoot的文件结构

  • src/main/java:存放代码
  • src/main/resources:存放静态资源
  • static: 存放静态文件,比如 css、js、image, (访问方式 http://localhost:8080/js/main.js)
  • templates:存放静态页面jsp,html,tpl
  • config:存放配置文件,application.properties

静态文件加载顺序

META/resources ----->resources -------->static ------->public

6.启动类原理

启动类和controller分开存放,启动类要放在根目录下,在启动类上只需要注解@SpringBootApplication

二、相关操作

1.Jar方式打包

只需在pom.xml文件中添加插件

<build>

     <plugins>

        <plugin>

          <groupId>org.springframework.boot</groupId>

          <artifactId>spring-boot-maven-plugin</artifactId>

       </plugin>

   </plugins>

</build> 
如果没有加,则执行jar包 ,报错如下
java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar
no main manifest attribute, in spring-boot-demo-0.0.1-SNAPSHOT.jar

打包与启动命令

  • 构建:mvn install

target目录下的jar包就是打包后项目

  • 进到对应的target
  • 目录启动 java -jar xxxxx.jar
  • 保持后台运行,守护进程 nohup java -jar xxx.jar &(但windows下没有,只能在linux或mac下运行实现)

2.自定义返回的业务状态码

在utils包下添加JSONData工具类实现

package net.xdclass.demoproject.utils;

/**
 * 接口返回工具类
 */
public class JsonData {


    private int code;

    private Object data;

    private String msg;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public JsonData(){}

    public JsonData(int code, Object data){
        this.code = code;
        this.data = data;

    }


    public JsonData(int code, Object data, String msg){
        this.code = code;
        this.data =data;
        this.msg = msg;

    }


    public static JsonData buildSuccess(Object data){
        return new JsonData(0,data);
    }

    public static JsonData buildError(String msg){
        return new JsonData(-1,"",msg);
    }


    public static JsonData buildError(String msg,int code){
        return new JsonData(code,"",msg);
    }


    @Override
    public String toString() {
        return "JsonData{" +
                "code=" + code +
                ", data=" + data +
                ", msg='" + msg + '\'' +
                '}';
    }
}

在controller层中直接调用即可

//将返回的list对象用工具类封装成json格式的字符串返回给前端
return JsonData.buildSuccess(video);

 3.Jackson

jackson注解,处理相关自动

@JsonIgnore(指定字段不返回)、@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss",locale="zh",timezone="GMT+8")(指定日期格式)、@JsonInclude(Include.NON_NULL)(空字段不返回)、@JsonProperty(指定别名)

序列化和反序列化操作

      //序列化操作
       ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(list);
        System.out.println(jsonStr);
	  //反序列化操作
        List<Video> temp = objectMapper.readValue(jsonStr,List.class);

4.加载配置文件

方式一

  • Controller中通过注解指定资源路径(@PropertySource({"classpath:resource.properties"}))
  • 增加属性@Value("${test.name}") private String name;

方式二:

创建一个实体类配置文件WXConfig

package net.xdclass.demoproject.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.Serializable;

@Configuration//表示这是一个配置类,用于加载配置文件中的属性值,会被Spring容器扫描
@PropertySource(value="classpath:pay.properties")
public class WXConfig implements Serializable {

    @Value("${wxpay.appid}")//从配置文件中获取属性值,并赋值给payAppid
    //或者@Value("${wxpay.appid}")
    private String payAppid;

    @Value("${wxpay.secret}")
    private String paySecret;

    @Value("${wxpay.mechid}")
    private String payMechId;

    public String getPayAppid() {
        return payAppid;
    }

    public void setPayAppid(String payAppid) {
        this.payAppid = payAppid;
    }

    public String getPaySecret() {
        return paySecret;
    }

    public void setPaySecret(String paySecret) {
        this.paySecret = paySecret;
    }

    public String getPayMechId() {
        return payMechId;
    }

    public void setPayMechId(String payMechId) {
        this.payMechId = payMechId;
    }
}

在TestController中引入

package net.xdclass.demoproject.controller;

import net.xdclass.demoproject.config.WXConfig;
import net.xdclass.demoproject.task.AsyncTask;
import net.xdclass.demoproject.utils.JsonData;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
@RequestMapping("api/v1/test")
@PropertySource({"classpath:pay.properties"})//在classpath目录下查找配置文件的路径
public class TestController {


    @Value("${wxpay.appid}")//从配置文件中获取属性值,并赋值给payAppid
//    @Value("${wxpay.appid}")//方式2
    private String payAppid;

    @Value("${wxpay.secret}")
    private String paySecret;



    @Autowired//会自动将WXConfig对象注入到TestController对象中
    private WXConfig wxConfig;

    @GetMapping("get_config")
    public JsonData testConfig(){


       Map<String,String> map = new HashMap<>();
//        map.put("appid",payAppid);
//        map.put("secret",paySecret);
//
//        return JsonData.buildSuccess(map);


        //通过配置类获取属性值,并封装成map对象返回给前端
        map.put("appid",wxConfig.getPayAppid());
        map.put("secret",wxConfig.getPaySecret());
        map.put("mechid",wxConfig.getPayMechId());

        return JsonData.buildSuccess(map);//将返回的map对象用工具类封装成json格式的字符串返回给前端

    }


}

在postman中可通过接口来访问得到数据,来模拟客户端

 

5.异常处理

全局异常处理实现

创建一个全局异常处理类

  • 类添加注解

@ControllerAdvice,如果需要返回json数据,则方法需要加@ResponseBody

@RestControllerAdvice, 默认返回json数据,方法不需要加@ResponseBody

  • 方法添加处理器

@ExceptionHandler(value=Exception.class)

package net.xdclass.demoproject.handler;


import net.xdclass.demoproject.utils.JsonData;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * 标记这个是一个异常处理类
 */
@RestControllerAdvice//标记这个是一个异常处理类,可以处理全局异常
public class CustomExtHandler {
    
    //处理特定异常:Exception.class
    @ExceptionHandler(value = Exception.class)//标记这个方法是一个异常处理方法,处理Exception.class异常
    JsonData handlerException(Exception e, HttpServletRequest request){

        //打印异常信息
        return JsonData.buildError("服务端出问题了", -2);
    }
}

 自定义全局异常

引入thymeleaf依赖

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

创建异常显示视图

resource目录下新建templates,并新建error.html

创建异常处理类

package net.xdclass.demoproject.handler;


import net.xdclass.demoproject.utils.JsonData;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * 标记这个是一个异常处理类
 */
@ControllerAdvice//标记这个是一个异常处理类
public class CustomExtHandler {

    @ExceptionHandler(value = Exception.class)
    Object handlerException(Exception e, HttpServletRequest request){

        //打印异常信息:ModelAndView:视图和模型的结合,可以将数据传递给视图,并渲染视图
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error.html");//设置视图名称:error.html,会自动去templates目录下查找error.html文件,并渲染
        System.out.println(e.getMessage());//打印异常信息
        //将异常信息传递给视图
        modelAndView.addObject("msg",e.getMessage());
        return modelAndView;


    }
}

三、优化配置

 1.简化sql语句

sql片段的使用:select * 去查询数据库不适用高并发项目

简化前

<select id="selectById" parameterType="java.lang.Integer" resultType="Video">

        select id,title,summary,cover_img  from video where id = #       {video_id,jdbcType=INTEGER}

    </select>

简化后

<sql id="base_video_field">
        id,title,summary,cover_img
    </sql>
    
     <select id="selectById" parameterType="java.lang.Integer" resultType="Video">

        select <include refid="base_video_field"/>  from video where id = #       {video_id,jdbcType=INTEGER}

    </select>

2.查询操作

复杂查询

sql的两种返回类型:resultType(适用于简单查询)、resultMap(适用于复杂查询) 

用resultMap来实现:在xml文件中配置

<!--1.配置映射结果集 2.编写查询语句实现查询-->
<resultMap id="VideoResultMap" type="Video">

        <!--
        id 指定查询列的唯一标示
        column 数据库字段的名称
        property pojo类的名称
        -->
        <id column="id" property="id" jdbcType="INTEGER" />

        <result column="video_tile" property="title"  jdbcType="VARCHAR" />
        <result column="summary" property="summary"  jdbcType="VARCHAR" />
        <result column="cover_img"  property="coverImg"  jdbcType="VARCHAR" />

    </resultMap>
<!--通过配置resultMap将as后面的数据库类型映射成as前面的java类型 -->
    <select id="selectBaseFieldByIdWithResultMap" resultMap="VideoResultMap">
        select id , title as video_title, summary, cover_img from video where id = #{video_id}
    </select>

 在Mapper接口中编写方法

   //复杂查询
    Video selectBaseFieldByIdWithResultMap(@Param("video_id")int id);

启动类中输出

            //resultMap映射出来得到的结果
            System.out.println(videoMapper.selectBaseFieldByIdWithResultMap(30));

 一对一联表查询

当需要同时查询两个表的信息时,通过association来配置一对一的关联表属性。

xml文件中

<resultMap id="VideoOrderResultMap" type="VideoOrder">
     <!--配置id为唯一标识-->
        <id column="id" property="id"/>

<!--配置结果集映射-->
        <result column="user_id" property="userId"/>
        <result column="out_trade_no" property="outTradeNo"/>
        <result column="create_time" property="createTime"/>
        <result column="state" property="state"/>
        <result column="total_fee" property="totalFee"/>
        <result column="video_id" property="videoId"/>
        <result column="video_title" property="videoTitle"/>
        <result column="video_img" property="videoImg"/>


        <!--配置关联表的映射属性:
         association 配置属性一对一
         property 对应videoOrder里面的user属性名
         javaType 这个属性的类型
         -->
        <association property="user" javaType="User">
            <id property="id"  column="user_id"/>
            <result property="name" column="name"/>
            <result property="headImg" column="head_img"/>
            <result property="createTime" column="create_time"/>
            <result property="phone" column="phone"/>
        </association>

    </resultMap>

    <!--一对一管理查询订单, 订单内部包含用户属性-->
    <select id="queryVideoOrderList" resultMap="VideoOrderResultMap">

        select

         o.id id,
         o.user_id ,
         o.out_trade_no,
         o.create_time,
         o.state,
         o.total_fee,
         o.video_id,
         o.video_title,
         o.video_img,
         u.name,
         u.head_img,
         u.create_time,
         u.phone
         from video_order o left join user u on o.user_id = u.id

    </select>

mapper接口

package net.xdclass.online_class.dao;

import net.xdclass.online_class.domain.User;
import net.xdclass.online_class.domain.VideoOrder;

import java.util.List;

public interface VideoOrderMapper {

    /**
     * 查询全部订单,关联用户信息
     * @return
     */
    List<VideoOrder> queryVideoOrderList();



}

启动类中

           // resultmap association关联查询
            VideoOrderMapper videoOrderMapper = sqlSession.getMapper(VideoOrderMapper.class);//获取mapper对象
            List<VideoOrder> videoOrderList = videoOrderMapper.queryVideoOrderList();//调用mapper接口中的方法
            System.out.println(videoOrderList.toString());//输出结果

一对多联表查询

 查询关联表信息中的返回多条数据,用collection来实现接收多条数据

<resultMap id="UserOrderResultMap" type="User">

        <id property="id"  column="id"/>
        <result property="name" column="name"/>
        <result property="headImg" column="head_img"/>
        <result property="createTime" column="create_time"/>
        <result property="phone" column="phone"/>

        <!--
        property 填写pojo类中集合类属性的名称
        ofType 集合里面的pojo对象
        -->
        <collection property="videoOrderList" ofType="VideoOrder">

            <!--配置主键,管理order的唯一标识-->
            <id column="order_id" property="id"/>
            <result column="user_id" property="userId"/>
            <result column="out_trade_no" property="outTradeNo"/>
            <result column="create_time" property="createTime"/>
            <result column="state" property="state"/>
            <result column="total_fee" property="totalFee"/>
            <result column="video_id" property="videoId"/>
            <result column="video_title" property="videoTitle"/>
            <result column="video_img" property="videoImg"/>
        </collection>
    </resultMap>

    <select id="queryUserOrder" resultMap="UserOrderResultMap">
        select
        u.id,
        u.name,
        u.head_img,
        u.create_time,
        u.phone,
        o.id order_id,
        o.out_trade_no,
        o.user_id,
        o.create_time,
        o.state,
        o.total_fee,
        o.video_id,
        o.video_title,
        o.video_img
        from user u left join video_order o on u.id = o.user_id

    </select>

小结

 

 

http://www.dtcms.com/a/111200.html

相关文章:

  • MQL5教程 05 指标开发实战:双色线、双线变色MACD、跨时间周期均线
  • TSMaster在新能源汽车研发测试中的硬核应用指南
  • 【rockchip】使用RKMPP+RGA解码H264并转换数据格式输出
  • 一文理解什么是中值模糊
  • C++多线程函数介绍
  • 【Kafka基础】ZooKeeper在Kafka中的核心作用:分布式系统中枢神经系统
  • 【LeetCode Solutions】LeetCode 141 ~ 145 题解
  • RocketMQ 中的 ProducerManager 组件剖析
  • 【Java Stream详解】
  • 提高:图论:强连通分量 图的遍历
  • Nginx功能及应用全解:从负载均衡到反向代理的全面剖析
  • OpenAI:人工智能领域的探索者与变革者
  • 黑马点评redis改 part 1
  • T-SQL语言的链表查找
  • eventEmitter实现
  • 网络建设与运维神州数码DCN MAC地址表操作
  • TypedDict和dataclass的优缺点对比
  • 前馈控制与反馈控制融合算法详解及python案例分析
  • JavaWeb学习--MyBatis-Plus整合SpringBoot的ServiceImpl方法(增加,修改与删除部分)
  • 深入解析:使用Python爬取Bilibili视频
  • 如何用DeepSeek进行SWOT分析?以CSDN的“C知道”为例
  • k8s的StorageClass存储类和pv、pvc、provisioner、物理存储的链路
  • 做一个Andriod系统应用的方法
  • 软件设计师之设计模式
  • 第七章 Python基础进阶-异常、模块与包(其五)
  • 手撕AVL树
  • 模运算核心性质与算法应用:从数学原理到编程实践
  • Julia语言的测试覆盖率
  • 卷积神经网络CNN 经典模型 — GoogleLeNet、ResNet、DenseNet算法原理与模型构造
  • Visual Basic语言的网络协议栈