【SpringBoot】基于MybatisPlus的博客管理系統(1)

1.準備工作

1.1數據庫

-- 建表SQL
create database if not exists java_blog_spring charset utf8mb4;use java_blog_spring;
-- 用戶表
DROP TABLE IF EXISTS java_blog_spring.user_info;
CREATE TABLE java_blog_spring.user_info(`id` INT NOT NULL AUTO_INCREMENT,`user_name` VARCHAR ( 128 ) NOT NULL,`password` VARCHAR ( 128 ) NOT NULL,`github_url` VARCHAR ( 128 ) NULL,`delete_flag` TINYINT ( 4 ) NULL DEFAULT 0,`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now(),PRIMARY KEY ( id ),UNIQUE INDEX user_name_UNIQUE ( user_name ASC )) ENGINE = INNODB DEFAULT CHARACTER
SET = utf8mb4 COMMENT = '用戶表';-- 博客表
drop table if exists java_blog_spring.blog_info;
CREATE TABLE java_blog_spring.blog_info (`id` INT NOT NULL AUTO_INCREMENT,`title` VARCHAR(200) NULL,`content` TEXT NULL,`user_id` INT(11) NULL,`delete_flag` TINYINT(4) NULL DEFAULT 0,`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now(),PRIMARY KEY (id))ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '博客表';-- 新增用戶信息
insert into java_blog_spring.user_info (user_name, password,github_url)values("zhangsan","123456","https://gitee.com/bubble-fish666/class-java45");
insert into java_blog_spring.user_info (user_name, password,github_url)values("lisi","123456","https://gitee.com/bubble-fish666/class-java45");insert into java_blog_spring.blog_info (title,content,user_id) values("第一篇博客","111我是博客正文我是博客正文我是博客正文",1);
insert into java_blog_spring.blog_info (title,content,user_id) values("第二篇博客","222我是博客正文我是博客正文我是博客正文",2);

1.2pom文件配置(MybatisPlus依賴)

MybatisPlus依賴:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version>
</dependency>

1.3yml文件配置(數據庫配置)

記得更改password

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/java_blog_spring?characterEncoding=utf8&useSSL=falseusername: rootpassword: '123456'driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:configuration:map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:file:name: spring-blog.log

1.4項目架構初始化

前期的架構:

?

開發中, 以下命名統稱為實體類:

POJO
Model
Entity


在實際開發中, 實體類的劃分要細的多:

VO(value object):? ?表現層對象
DO(Data Object)/PO(Persistant Object): 持久層/數據層對象
DTO(Data Transfer Object): 數據傳輸對象
BO(Business Object): 業務對象
細分實體類, 可以實現業務代碼的解耦.

詳情見:實體類

2.業務實現

2.1獲取博客列表

1.第一步:實現實體類? 對接數據庫數據

//do層數據庫資源對象
@Data
@AllArgsConstructor
public class BlogInfo {@TableId(type = IdType.AUTO)private Integer id;private String title;private String content;private Integer userId;private Integer deleteFlag;private LocalDateTime createTime;private LocalDateTime updateTime;
}
@Data
public class UserInfo {@TableId(type = IdType.AUTO)private Integer id;private String userName;private String password;private String githubUrl;private Integer deleteFlag;private LocalDateTime createTime;private LocalDateTime updateTime;
}

2.實現返回對象類? 對接前端

@Data
public class BlogInfoResponse {@TableId(type = IdType.AUTO)private Integer id;private String title;private String content;//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//重寫構造方法public String getCreateTime() {return DateUtils.format(createTime);}//通過重寫0content構造方法完成業務想要的返回結果  如:對字符串進行拼接等等}

BlogInfoResponse 是返回前端展示博客列表所需的數據

注意:

我們需要掌握更改日期格式的方法:

常見的日期類型有:Date??LocalDateTime

在這里我們用的是LocalDateTime

那我們就先講它的轉化方法

		LocalDateTime localDateTime = LocalDateTime.now();DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");String format1 = dateTimeFormatter.format(localDateTime);System.out.println(format1);

使用?DateTimeFormatter 類進行格式定義

類型格式的定義是什么呢?

查詢java.text.SimpleDateFormat 官??檔可知

  • LetterDate or Time ComponentPresentationExamples
    GEra designatorTextAD
    yYearYear1996; 96
    YWeek yearYear2009; 09
    MMonth in year (context sensitive)MonthJuly; Jul; 07
    LMonth in year (standalone form)MonthJuly; Jul; 07
    wWeek in yearNumber27
    WWeek in monthNumber2
    DDay in yearNumber189
    dDay in monthNumber10
    FDay of week in monthNumber2
    EDay name in weekTextTuesday; Tue
    uDay number of week (1 = Monday, ..., 7 = Sunday)Number1
    aAm/pm markerTextPM
    HHour in day (0-23)Number0
    kHour in day (1-24)Number24
    KHour in am/pm (0-11)Number0
    hHour in am/pm (1-12)Number12
    mMinute in hourNumber30
    sSecond in minuteNumber55
    SMillisecondNumber978
    zTime zoneGeneral time zonePacific Standard Time; PST; GMT-08:00
    ZTime zoneRFC 822 time zone-0800
    XTime zoneISO 8601 time zone-08; -0800; -08:00

Date的轉化方法:

		Date date = new Date();//SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");String format = simpleDateFormat.format(date);System.out.println(format);

?所以我們通過重寫構造方法完成日期格式修改

最后我們通過AOP思想完成日期統一修改:

public class DateUtils {public static String format(LocalDateTime localDateTime) {DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(Constant.PATTERN);return dateTimeFormatter.format(localDateTime);}public static String format(LocalDateTime localDateTime, String pattern) {DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);return dateTimeFormatter.format(localDateTime);}
}
/*** 統一返回結果* @param <T>*/
@Data
public class Result<T> {private int code;private String errMsg;private T data;public static <T> Result success(T data) {Result<T> re = new Result<>();re.setCode(ResultCodeEnum.SUCCESS.getCode());re.setData(data);return re;}public static <T> Result fail(String errMsg) {Result<T> re = new Result<>();re.setCode(ResultCodeEnum.FAIL.getCode());re.setErrMsg(errMsg);return re;}public static <T> Result fail(String errMsg, T data) {Result<T> re = new Result<>();re.setCode(ResultCodeEnum.FAIL.getCode());re.setErrMsg(errMsg);re.setData(data);return re;}
}

Result:統一返回結果?

注意:在靜態方法中使用T泛型時要在static后加<T>

在這一步我們在使用code時可以選擇:

1.在Constant中定義靜態常亮

2.定義枚舉

我選擇使用枚舉:

@AllArgsConstructor
public enum ResultCodeEnum {SUCCESS(200),FAIL(-1);@Getterprivate int code;}

?3.Controller? Service? Mapper? 三件套

Controller:在注入BlogService 時推薦使用@Resource? 因為可能使用實現了多個對象的接口

同時注入的類型為接口類型,方便修改注入(只用修改@Resource name屬性)

@Slf4j
@RestController
@RequestMapping("/blog")
public class BlogInfoController {@Resource(name = "blogService")private BlogService blogService;@RequestMapping("/getList")public List<BlogInfoResponse> getList() {log.info("獲取博客列表...");return blogService.getList();}
}

?

Service :先定義接口,然后在impl包中實現具體類并處理邏輯

?

@Service
public interface BlogService {List<BlogInfoResponse> getList();
}
@Service("blogService")
public class BlogServiceImpl implements BlogService {@Resourceprivate BlogInfoMapper blogInfoMapper;@Overridepublic List<BlogInfoResponse> getList() {//1.SQL拼接QueryWrapper<BlogInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().eq(BlogInfo::getDeleteFlag, Constant.IS_DELETE);List<BlogInfo> blogInfos = blogInfoMapper.selectList(queryWrapper);//2.將獲取的數據轉化為BlogInfoResponse用于返回List<BlogInfoResponse> list = blogInfos.stream().map(blogInfo -> {BlogInfoResponse blogInfoResponse = new BlogInfoResponse();//根據屬性名稱進行復制  原數據  轉化數據BeanUtils.copyProperties(blogInfo, blogInfoResponse);return blogInfoResponse;}).collect(Collectors.toList());//轉化listreturn list;}}

注意點:

1.在?@Service中進行名稱綁定

2.參數轉換:

使用blogInfos.stream().map()與lambda表達式實現遍歷? (或者使用for循環)

代碼中的鏈式調用解釋如下:

blogInfos.stream(): 將 List 轉換為一個 stream

blogInfos.stream().map(x -> {轉換規則, return y}): 對 List 中的每一個元素根據指定規則進行轉換(x: 原來的元素; y: 轉換后的元素)

.collect(Collectors.toList()): 將轉換后的 Stream 轉換為一個新的 List

3.根據屬性名稱進行復制? ? 原數據? ? ? 轉化數據

BeanUtils.copyProperties(blogInfo, blogInfoResponse);

Mapper:因為使用了MybatisPlus,不用寫SQL語句(舒服)

只用實現BaseMapper<T>接口? T為對接數據庫的類,會根據該類生成SQL語句

@Mapper
public interface BlogInfoMapper extends BaseMapper<BlogInfo> {
}

使用postman校驗一下:

2.2獲取博客詳情?

前置工作已經做完了,直接寫Controller? Service代碼就行

Controller :

    @RequestMapping("/getBlogDetail")public BlogDetailResponse getBlogDetail(@NotNull(message = "blogId 不能為空") Integer blogId) {
//        if(blogId == null) {
//            throw new BlogException("用戶id不能為空");
//        }log.info("獲取博客詳情,id:{}",blogId);return blogService.getBlogDetail(blogId);}

@NotNull(message = "blogId 不能為空"):

jakarta.validation完成的參數校驗(javax.validation 是Java Bean Validation API的包名)

?如果參數為空了還要爆出異常,這時候啟用我們定義的異常與統一異常處理

@Slf4j
@ResponseBody
@ControllerAdvice
public class ExceptionAdvice {@ExceptionHandlerpublic Result exceptionAdvice(Exception e) {log.error("出現異常e:", e);return Result.fail(e.getMessage());}@ExceptionHandlerpublic Result exceptionAdvice(BlogException e) {log.error("出現異常e:", e);return Result.fail(e.getErrMsg());}@ExceptionHandlerpublic Result exceptionAdvice(HandlerMethodValidationException e) {log.error("出現異常e:", e);//獲取異常信息
//        List<String> errors = new ArrayList<>();
//        e.getAllErrors().forEach(error -> errors.add(e.getMessage()));return Result.fail("參數校驗失敗");}
}

在統一異常處理(@ResponseBody@ControllerAdvice@ExceptionHandler)中可以處理自定義異常與常規異常? 同時打印日志?

Service:

    @Overridepublic BlogDetailResponse getBlogDetail(Integer blogId) {QueryWrapper<BlogInfo> queryWrapper = new QueryWrapper<>();//根據id與DeleteFlag查詢queryWrapper.lambda().eq(BlogInfo::getId, blogId).eq(BlogInfo::getDeleteFlag, Constant.IS_DELETE);BlogInfo blogInfo = blogInfoMapper.selectOne(queryWrapper);BlogDetailResponse blogDetailResponse = new BlogDetailResponse();BeanUtils.copyProperties(blogInfo, blogDetailResponse);return blogDetailResponse;}

老套路查詢后轉化類型

postman檢驗一下:

沒傳參,返回我們定義的返回信息

正常傳參:

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77700.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77700.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77700.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

貴族運動項目有哪些·棒球1號位

10個具有代表性的貴族運動&#xff1a; 高爾夫 馬術 網球 帆船 擊劍 斯諾克 冰球 私人飛機駕駛 深海潛水 馬球 貴族運動通常指具有較高參與成本、歷史底蘊或社交屬性的運動&#xff0c;而棒球作為一項大眾化團隊運動&#xff0c;與典型貴族運動的結合較為罕見。從以下幾個角度探…

【Tauri2】035——sql和sqlx

前言 這篇就來看看插件sql SQL | Taurihttps://tauri.app/plugin/sql/ 正文 準備 添加依賴 tauri-plugin-sql {version "2.2.0",features ["sqlite"]} features可以是mysql、sqlite、postsql 進去features看看 sqlite ["sqlx/sqlite&quo…

全鏈路自動化AIGC內容工廠:構建企業級智能內容生產系統

一、工業化AIGC系統架構 1.1 生產流程設計 [需求輸入] → [創意生成] → [多模態生產] → [質量審核] → [多平臺分發] ↑ ↓ ↑ [用戶反饋] ← [效果分析] ← [數據埋點] ← [內容投放] 1.2 技術指標要求 指標 標準值 實現方案 單日產能 1,000,000 分布式推理集群 內容合規率…

是否想要一個桌面哆啦A夢的寵物

是否想擁有一個在指定時間喊你的桌面寵物呢&#xff08;手動狗頭&#xff09; 如果你有更好的想法&#xff0c;歡迎提出你的想法。 是否考慮過跟開發者一對一&#xff0c;提出你的建議&#xff08;狗頭&#xff09;。 https://wwxc.lanzouo.com/idKnJ2uvq11c 密碼:bbkm

Unity AI-使用Ollama本地大語言模型運行框架運行本地Deepseek等模型實現聊天對話(二)

一、使用介紹 官方網頁&#xff1a;Ollama官方網址 中文文檔參考&#xff1a;Ollama中文文檔 相關教程&#xff1a;Ollama教程 使用版本&#xff1a;Unity 2022.3.53f1c1、Ollama 0.6.2 示例模型&#xff1a;llama3.2 二、運行示例 三、使用步驟 1、創建Canvas面板 具體…

從 BERT 到 GPT:Encoder 的 “全局視野” 如何喂飽 Decoder 的 “逐詞糾結”

當 Encoder 學會 “左顧右盼”&#xff1a;Decoder 如何憑 “單向記憶” 生成絲滑文本&#xff1f; 目錄 當 Encoder 學會 “左顧右盼”&#xff1a;Decoder 如何憑 “單向記憶” 生成絲滑文本&#xff1f;引言一、Encoder vs Decoder&#xff1a;核心功能與基礎架構對比1.1 本…

數據結構入門:詳解順序表的實現與操作

目錄 1.線性表 2.順序表 2.1概念與結構 2.2分類 2.2.1靜態順序表 2.2.2動態順序表 3.動態順序表的實現 3.1.SeqList.h 3.2.SeqList.c 3.2.1初始化 3.2.2銷毀 3.2.3打印 3.2.4順序表擴容 3.2.5尾部插入及尾部刪除 3.2.6頭部插入及頭部刪除 3.2.7特定位置插入…

LeetCode熱題100--53.最大子數組和--中等

1. 題目 給你一個整數數組 nums &#xff0c;請你找出一個具有最大和的連續子數組&#xff08;子數組最少包含一個元素&#xff09;&#xff0c;返回其最大和。 子數組是數組中的一個連續部分。 示例 1&#xff1a; 輸入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 輸出&…

python:練習:2

1.題目&#xff1a;統計一篇英文文章中每個單詞出現的次數&#xff0c;并按照出現次數排序輸出。 示例輸入&#xff1a; text "Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991…

AI Agent 孵化器?開源框架CAMEL

簡介 CAMEL&#xff08;Communicative Agents for Mind Exploration of Large Scale Language Model Society&#xff09;是一個開源框架&#xff0c;大語言模型多智能體框架的先驅者。旨在通過角色扮演和自主協作&#xff0c;探索大語言模型&#xff08;LLM&#xff09;在多智…

關于插值和擬合(數學建模實驗課)

文章目錄 1.總體評價2.具體的課堂題目 1.總體評價 學校可以開設這個數學建模實驗課程&#xff0c;我本來是非常的激動地&#xff0c;但是這個最后的上課方式卻讓我高興不起哦來&#xff0c;因為老師講的這個內容非常的簡單&#xff0c;而且一個上午的數學實驗&#xff0c;基本…

LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding

TL;DR 2024 年 Meta FAIR 提出了 LayerSkip&#xff0c;這是一種端到端的解決方案&#xff0c;用于加速大語言模型&#xff08;LLMs&#xff09;的推理過程 Paper name LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding Paper Reading Note Paper…

解決ktransformers v0.3 docker鏡像中 operator torchvision::nms does not exist 問題

問題背景 更新ktransformers docker鏡像到v0.3版本后&#xff08;之前為v0.2.4post1&#xff09;&#xff0c;使用更新前啟動命令無法正確啟動服務&#xff0c;提示以下錯誤&#xff1a; Traceback (most recent call last):File "/workspace/ktransformers/ktransforme…

如何系統學習音視頻

學習音視頻技術涉及多個領域&#xff0c;包括音頻處理、視頻處理、編碼解碼、流媒體傳輸等。 第一階段&#xff1a;基礎知識準備 目標&#xff1a;掌握音視頻學習所需的計算機科學和數學基礎。 計算機基礎 學習計算機網絡基礎&#xff08;TCP/IP、UDP、HTTP、RTSP等協議&#…

TiDB 可觀測性最佳實踐

TiDB 介紹 TiDB&#xff0c;由 PingCAP 公司自主研發的開源分布式關系型數據庫&#xff0c;是一款創新的 HTAP 數據庫產品&#xff0c;它融合了在線事務處理&#xff08;OLTP&#xff09;和在線分析處理&#xff08;OLAP&#xff09;的能力&#xff0c;支持水平擴容和縮容&…

使用FreeRTOS解決單片機串口異步打印

單片機串口異步打印 文章目錄 單片機串口異步打印前言設計思路準備隊列創建完整代碼 總結 前言 &#x1f30a;在單片機開發中串口的異步打印異步打印允許單片機在執行其他任務的同時進行打印操作&#xff0c;無需等待打印完成后再繼續執行后續代碼&#xff0c;避免了在多處調用…

代碼顏色模式python

1. CMYK&#xff08;印刷場景&#xff09; 例子&#xff1a;某出版社設計書籍封面時&#xff0c;使用 Adobe Illustrator 繪制圖案。 紅色封面的 CMYK 值可能為&#xff1a;C0, M100, Y100, K0&#xff08;通過洋紅和黃色油墨混合呈現紅色&#xff09;。印刷前需將設計文件轉…

HarmonyOS NEXT 詩詞元服務項目開發上架全流程實戰(二、元服務與應用APP簽名打包步驟詳解)

在HarmonyOS應用開發過程中&#xff0c;發布應用到應用市場是一個重要的環節。沒經歷過的童鞋&#xff0c;首次對HarmonyOS的應用簽名打包上架可能感覺繁瑣。需要各種秘鑰證書生成和申請&#xff0c;混在一起分不清。其實搞清楚后也就那會事&#xff0c;各個文件都有它存在的作…

【BotSharp框架示例 ——實現聊天機器人,并通過 DeepSeek V3實現 function calling】

BotSharp框架示例 ——實現聊天機器人&#xff0c;并通過 DeepSeek V3實現 function calling 一、一點點感悟二、創建項目1、創建項目2、添加引用3、MyWeatherPlugin項目代碼編寫4、WeatherApiDefaultService項目代碼編寫5、WebAPI MyWeatherAPI 的項目代碼編寫6、data文件夾中…

百度CarLife實現手機車機無縫互聯

百度CarLife是百度推出的智能車聯網解決方案&#xff0c;通過手機與車機互聯技術&#xff0c;為用戶提供安全便捷的車載互聯網服務體驗。 CarLife 實現手機與車機屏幕的無縫互聯&#xff0c;讓應用內容同步至車載系統&#xff0c;減少駕駛過程中操作手機的頻率&#xff0c;提升…