1. SpringBoot引入knife4j

1.1 xml依赖

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
            <version>4.0.0</version>
        </dependency>

1.2 yml配置

knife4j:
  enable: true

1.3 注解的写法

1.3.1 Controller注解的写法

结合《1.4.1 Controller注解映射》测试页面理解注解

@RestController
@RequestMapping("/api/book")
@Api(tags = "图书的api接口")
public class BookController {

    @Autowired
    private BookServiceImpl bookService;

    @GetMapping("/selectAllByPage")
    @ApiOperation("selectAllByPage方法测试")
    @ApiImplicitParam(name = "selectAllByPage", value = "分页查询", required = true)
    public HttpResp selectAllByPage(Integer currentPage) {
        return HttpResp.getResults(ResultCode.BOOK_SUCCESS, new Date(), bookService.selectAllByPage(currentPage, 5));
    }

    @GetMapping("/selectPriceBelowFifty")
    @ApiImplicitParam(name = "selectPriceBelowFifty", value = "价格低于50的书")
    @ApiOperation("selectPriceBelowFifty方法测试")
    public HttpResp selectPriceBelowFifty() {
        return HttpResp.getResults(ResultCode.BOOK_SUCCESS, new Date(), bookService.selectPriceBelowFifty());
    }

    @GetMapping("/selectPriceBetweenThirtyAndSixty")
    @ApiOperation("selectPriceBetweenThirtyAndSixty方法测试")
    @ApiImplicitParam(name = "selectPriceBetweenThirtyAndSixty", value = "价格在30-60元之间的书")
    public HttpResp selectPriceBetweenThirtyAndSixty() {
        return HttpResp.getResults(ResultCode.BOOK_SUCCESS, new Date(), bookService.selectPriceBetweenThirtyAndSixty());
    }

    @GetMapping("/selectByAuthor")
    @ApiOperation("selectByAuthor方法测试")
    @ApiImplicitParam(name = "selectByAuthor",value = "查询某个作者的所有书籍",required = true)
    public HttpResp selectByAuthor(String author){
        return HttpResp.getResults(ResultCode.BOOK_SUCCESS,new Date(),bookService.selectByAuthor(author));
    }

    @GetMapping("/selectTenOrderByPubDateAsc")
    @ApiOperation("selectTenOrderByPubDateAsc方法测试")
    @ApiImplicitParam(name = "selectTenOrderByPubDateAsc",value = "查询出版时间最早的前10本书")
    public HttpResp selectTenOrderByPubDateAsc(){
        return HttpResp.getResults(ResultCode.BOOK_SUCCESS,new Date(),bookService.selectTenOrderByPubDateAsc());
    }

    @GetMapping("/selectIntroductionLikeZhong")
    @ApiOperation("selectIntroductionLikeZhong方法测试")
    @ApiImplicitParam(name = "selectIntroductionLikeZhong",value = "分页显示简介中带有'中'字的书名",required = true)
    public HttpResp selectIntroductionLikeZhong(Integer currentPage){
        List<Book> books = bookService.PaginationIntroductionLikeZhong(currentPage);
        List<String> bookTitles = new ArrayList<>();
        for (Book book : books) {
            bookTitles.add(book.getTitle());
        }
        return HttpResp.getResults(ResultCode.BOOK_SUCCESS,new Date(),bookTitles);
    }

    @GetMapping("/selectAllBooksBySinglePub")
    @ApiOperation("selectAllBooksBySinglePub方法测试")
    @ApiImplicitParam(name = "selectAllBooksBySinglePub",value = "按出版社名查询该出版社下的所有图书",required = true)
    public HttpResp selectAllBooksBySinglePub(String pubName){
        return HttpResp.getResults(ResultCode.BOOK_SUCCESS,new Date(),bookService.selectAllBooksBySinglePub(pubName));
    }
}

1.3.2 DTO类注解的写法

结合《1.4.2 DTO注解映射》测试页面理解注解

@Getter
@Setter
@ToString
@ApiModel("DTO返回数据")
public class HttpResp<T>  implements Serializable {
    private ResultCode resultCode;
    @ApiModelProperty("time")
    private Date time;
    @ApiModelProperty("结果集")
    private T data;

    private HttpResp(){}

    public static <T> HttpResp<T> getResults(ResultCode resultCode,Date time,T data){
        HttpResp httpResp = new HttpResp();
        httpResp.setResultCode(resultCode);
        httpResp.setData(time);
        httpResp.setData(data);
        return httpResp;
    }
}

1.4 knife4j页面详解

1.4.1 Controller注解映射

1.4.2 DTO注解映射

 

2. mybatisplus联表查询、LambdaQueryWrapper查询、mybatisplus分页

2.1 mybatisplus联表查询

采用mybatis的mapper.xml注入方式

2.1.1 yml配置

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-aliases-package: com.wn.bc0606.entity
  mapper-locations: classpath:/mapper/*.mapper.xml

2.1.2 mapper.xml做resultMap映射

<?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.wn.bc0606.dao.BookDao">

    <resultMap id="BookPub" type="book">
        <id column="book_id" property="id"/>
        <result property="title" column="book_title"/>
        <result property="author" column="book_author"/>
        <result property="price" column="book_price"/>
        <result property="version" column="book_version"/>
        <result property="pubDate" column="book_pubDate"/>
        <result property="store" column="book_store"/>
        <result property="imgUrl" column="book_imgUrl"/>
        <result property="weight" column="book_weight"/>
        <result property="introduction" column="book_introduction"/>
        <result property="sold" column="book_sold"/>
        <result property="pages" column="book_pages"/>
        <result property="createTime" column="book_createTime"/>
        <result property="updateTime" column="book_updateTime"/>
        <result property="type" column="book_type"/>
        <result property="publisher" column="book_publisher"/>
        <association property="publisher" javaType="publisher"/>
    </resultMap>
    <select id="selectAllBooksBySinglePub" parameterType="String" resultMap="BookPub">
        select b.*
        from book_tab b
                 left join publisher_tab p on b.book_publisher = p.pub_id
        where p.pub_name = #{pubName}
    </select>

</mapper>

2.1.3 Dao接口的写法

@Mapper
public interface BookDao extends BaseMapper<Book> {

    List<Book> selectAllBooksBySinglePub(@Param("pubName") String pubName);

}

2.1.4 ServiceImpl注入Dao并调用方法

@Override
    public List<Book> selectAllBooksBySinglePub(String pubName) {
        return bookDao.selectAllBooksBySinglePub(pubName);
    }

2.2  LambdaQueryWrapper查询

@Override
    public List<Book> selectTenOrderByPubDateAsc() {
        LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(Book::getPubDate).last("limit 10");
        return bookDao.selectList(wrapper);
    }

2.3 mybatisplus分页

分页的本质是sql语句 limit(m,n)

2.3.1 配置分页拦截器

@Configuration
public class InterceptorConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        paginationInnerInterceptor.setOverflow(true);
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
        return mybatisPlusInterceptor;
    }
}

 2.3.2 完成分页的Service代码

@Override
    public List<Book> PaginationIntroductionLikeZhong(Integer currentPage) {
        LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Book::getIntroduction,"中");
        IPage<Book> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(5);
        return bookDao.selectPage(page,wrapper).getRecords();
    }

3. SpringBoot设计模式浅析(单例实验)

3.1 单例懒加载模式

若不加synchronized锁则线程不安全

/**
 * 单例模式懒加载
 */
public class Singleton {
    private static Singleton test;
    private Singleton(){
    }

    //synchronized 同步锁 效率下降
    public static synchronized Singleton getSingleton(){
        if(null==test){
            test = new Singleton();
        }
        return test;
    }
}

3.2  单例即时加载模式

/**
 * 单例模式即时加载
 */
public class SingletonHunger {
    private static SingletonHunger instance = new SingletonHunger();

    private SingletonHunger(){}

    public static SingletonHunger getSingletonHunger(){
        return instance;
    }
}

3.3 枚举实现单例

/**
 * 枚举实现单例
 */
public enum SingleEnum {
    INSTANCE
}

3.4 多线程测试类

public class ThreadTest {
    public static void main(String[] args) {

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {

                try {
//                    Singleton singleton = Singleton.getSingleton();
//                    SingleEnum singleEnum = SingleEnum.INSTANCE;
                    SingletonHunger singletonHunger = SingletonHunger.getSingletonHunger();
                    System.out.println(singletonHunger.hashCode());
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {

                try {
//                    Singleton singleton = Singleton.getSingleton();
//                    SingleEnum singleEnum = SingleEnum.INSTANCE;
                    SingletonHunger singletonHunger = SingletonHunger.getSingletonHunger();
                    System.out.println(singletonHunger.hashCode());
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread1.start();
        thread2.start();

    }
}

3.5 其他模式解析

详见大佬文章

面试官:“谈谈Spring中都用到了那些设计模式?”。_spring用到的设计模式_JavaGuide的博客-CSDN博客

更多推荐