主頁 > 軟體設計 > JAVA框架專案實戰:系統公告設計及實作

JAVA框架專案實戰:系統公告設計及實作

2021-01-28 14:36:41 軟體設計

專案實戰:系統公告設計及實作

本期涉及內容:JDBC、點擊即可跳轉復習JDBC

1.需求及業務設計

專案(公告系統)

1.需求(為行政人員發布公告,通知提供遍歷)
2.原型設計(系統做完以后是什么樣子的,先做一個設計稿)
3.表的設計(公告內容中包含哪些欄位)
4.技術分層架構(分而治之-將復雜問題簡單化)
5.技術堆疊的設計(資料庫端技術,服務端技術,客服端技術)

目的:以專案為驅動,講解技術的應用,

1.1業務描述

系統公告是方便公司行政管理人員向公司全員或部分指定人員發送通知公告的模塊,如開會通知、放假通知及其它資訊,使用戶可以很方便的了解公司動向,

1.2系統原型設計

公告串列頁面,如圖所示:
在這里插入圖片描述
公告編輯頁面,如圖所示:
在這里插入圖片描述

1.3資料庫及表設計

基于系統公告業務,現對公告表進行設計,sql 腳本如下:

drop database if exists db_notice;
create database if not exists db_notice default character set utf8; use db_notice
drop table if exists sys_ notice;
create table sys_ notice (
id             int(4) auto_ increment     comment'ID',
title          varchar(50) not null       comment'標題 ',
type           char(1) not null           comment'型別(1通知 2公告),
content        varchar(500) default null  comment'公告內容',
status         char(1) default '0'        comment'狀態(0 正常 1關閉)',
createdUser    varchar(64) default''      comment'創建者' ,
createTime      datetime                  comment'創建時間',
modifiedUser    varchar(64) default''     comment'更新者',
modifiedTime    datetime                  comment'更新時間',
remark          varchar( 255)             comment'備注',
primary key (id)
) engine=innodb auto_increment=1 comment = '通知公告表';

 

1.4技術架構分層設計

系統分層設計是一種設計思想(分而治之),是讓每層物件都有一個獨立職責,再讓多層物件協同(耦合)完成一個完整的功能,這樣做可以更好提高系統可擴展性,但同時也會增加系統整體運維的難度,
在這里插入圖片描述
其中,在上圖中的箭頭表示一種直接依賴關系,開放介面層可以依賴于 Web 層,也可以直接依賴于 Service 層,其它依此類推(具體每層要實作的邏輯可自行查閱阿里巴巴開發手冊),

1.5技術堆疊中技術選型設計

2.SpringBoot 技術

2.1 簡介

JAVAEE 應用體系中繁重的配置、低下的開發效率、高難度的三方集成,復雜的部署流程等等一直被開發人員所詬病,
Spring 這樣的輕量級的資源整合框架,在實作其相對比較多的資源整合時,依舊需要大量的手動依賴管理,復雜的 XML 配置(還經常沒有提示),
現在的軟體生態應用也已經形成一定的規模,系統架構正在從單體架構,分布式架構, 跨越到微服務架構,隨著整個架構體系的變化,企業對技術的要求也在變化,現在的企業更注重技術的開箱即用,更注重技術在生態圈中的深度融合,更注重輕量級的運維,由此由此spring boot 誕生,
Spring Boot 是 Java 軟體開發框架(很多人現在把它理解為一個腳手架),其設計目的是用來簡化 Spring 專案的初始搭建以及開發程序,該框架使用了特定的注解方式來進行配置,從而使開發人員不再需要大量的 xml 配置,不再需要大量的手動依賴管理,Spring Boot 基于快速構建理念,通過約定大于配置,開箱即用的方式,希望能夠在蓬勃發展的快速應用開發領域成為其領導者,

2.2 關鍵特性

SpringBoot 其核心特性包含如下幾個方面:
起步依賴(Starter Dependency),
自動配置(Auto Configuration),
健康檢查(Actator)-監控,
嵌入式服務(Tomcat,Jetty)等,

2.3 工程創建及啟動

SpringBoot 工程中由 SpringBootApplication 注解描述的類為啟動入口類,例如:
在這里插入圖片描述

package com.cy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; 
@SpringBootApplication
public class Application {//Application.class
   public static void main(String[] args) {//Main Thread
      SpringApplication.run(Application.class,args);
   }
}

運行啟動類檢測輸出結果,了解其啟動程序,如圖所示:
在這里插入圖片描述
其中,專案在啟動時要做哪些基礎操作.

  1. 基于執行緒呼叫i/o 從磁盤讀取類,將其加載到記憶體,此時會基于類創建位元組碼物件(其型別為 Class 型別)
  2. 基于 Class 物件( 位元組碼物件) 讀取類的配置資訊( 例如類上有什么注解- 例如@Component,屬性上有什么注解,. )
  3. 基于類的配置進行相應的配置存盤 ( 交給 spring 管理的類的配置 )- Map<String,BeanDefinition>
  4. 基 于 類 的 配 置 借 助 BeanFactory 創 建 類 的 實 例 ( 物件 ), 多 個 對 象 存 儲 到Map<String,Object>

3HikariCP 連接池應用

池化思想是我們專案開發程序中的一種非常重要的思想,如整數池,字串池,物件池、連接池、執行緒池等都是池化思想一種應用,都是通過復用物件,以減少因創建和釋放物件所帶來的資源消耗,進而來提升系統性能,
例如 Integer 物件的內部池應用,代碼如下:

package com.cy.java.pool;
public class TestInteger01 {
   public static void main(String[] args) {
        //演示整數池(-128 ~ 127)
        Integer n1=100;//Integer.valueOf(100) 編譯時優化
        Integer n2=100; 
        //對整數而言為什么不將所有整數都放到池中,而只是存盤了一部分資料呢?
        //池設計的目的是? 以空間換時間,這塊空間中應該存盤一些常用的整數資料
        Integer n3=200;
        Integer n4=200;// 池 中 沒 有 則 new Integer(200) 
        System.out.println(n1==n2);//true,池存盤著-128~+127 
        System.out.println(n3==n4);//false
        //所有的池設計都會用到一種設計
     }
}

專案開發程序中應用程式與資料庫互動時,“獲得連接”或“釋放連接”是非常消耗系統資源的兩個程序,頻繁地進行資料庫連接的建立和關倍訓極大影響系統的性能,若多執行緒并發量很大,這樣耗時的資料庫連接就可能讓系統變得卡頓,因為 TCP 連接的創建開支十分昂貴,并且資料庫所能承載的 TCP 并發連接數也有限制,針對這種場景,資料庫連接池應運而生,如圖-1 所示:
在這里插入圖片描述
Java 官方,為了在應用程式中更好的應用連接池技術,定義了一套資料源規范,例如javax.sql.DataSource 介面,基于這個介面,很多團隊或個人創建了不同的連接池物件,然后我們的應用程式中通過耦合與 DataSource 介面,便可以方便的切換不同廠商的連接池,Java 專案中通過連接池獲取連接的一個基本程序,如圖-2 所示:
在這里插入圖片描述

在圖-2 中,用戶通過 DataSource 物件的 getConnection()方法,獲取一個連接,假如池中有連接,則直接將連接回傳給用戶,假如池中沒有連接,則會呼叫 Dirver(驅動, 由資料庫廠商進行實作)物件的 connect 方法從資料庫獲取,拿到連接以后,可以將連接在池中放一份,然后將連接回傳給呼叫方,連接需求方再次需要連接時,可以從池中獲取, 用完以后再還給池物件,

資料庫連接池的江湖,

資料庫連接池在 Java 資料庫相關中間件產品群中,應該算是底層最基礎的一類產品, 作為企業應用開發必不可少的組件,無數天才們為我們貢獻了一個又一個的優秀產品,它們有的隨時代發展,功成身退,有的則還在不斷迭代,老而彌堅,更有新生代產品,或性能無敵,或功能全面,目前市場上常見的連接池有 DBCP、C3P0,DRUID,HikariCP 等,
資料庫連接池的原理分析,
在系統初始化的時候,在記憶體中開辟一片空間,將一定數量的資料庫連接作為物件存盤在物件池里,并對外提供資料庫連接的獲取和歸還方法,用戶訪問資料庫時,并不是建立一個新的連接,而是從資料庫連接池中取出一個已有的空閑連接物件;使用完畢歸還后的連接也不會馬上關閉,而是由資料庫連接池統一管理回收,為下一次借用做好準備,如果由于高并發請求導致資料庫連接池中的連接被借用完畢,其他執行緒就會等待,直到有連接被歸還,整個程序中,連接并不會關閉,而是源源不斷地回圈使用,有借有還,資料庫連接池還可以通過設定其引數來控制連接池中的初始連接數、連接的上下限數,以及每個連接的最大使用次數、最大空閑時間等,也可以通過其自身的管理機制來監視資料庫連接的數量、使用情況等,

資料庫連接池的構成分析,

資料庫連接池以連接池的管理為核心,主要支持連接池的建立和釋放這兩大核心功能,“麻雀雖小,五臟俱全”,資料庫連接池還可以支持其他非常實用的功能,一款商用的資料庫連接池、一款能夠被開發者廣泛使用的資料庫連接池、一款能夠在開源社區持續活躍發展的資料庫連接池還必須再支持一些實用的功能,如并發(鎖性能優化乃至無鎖)、連接數控制(不同的系統對連接數有不同的需求)、監控(一些自身管理機制來監視連接的數量及使用情況等)、外部配置(各種主流資料庫連接池官方檔案最核心的部分)、資源重用(資料庫連接池的核心思想)、檢測及容災(面對一些網路、時間等問題的自愈)、多庫多服務(如不同的資料庫、不同的用戶名和密碼、分庫分表等情況)、事務處理(對資料庫的運算子合 ALL- ALL-NOTHING 原則)、定時任務(如空閑檢查、最小連接數控制)、快取(如 PSCache 等避免對 SQL 重復決議)、例外處理(對 JDBC 訪問的例外統一處理)、組件維護(如連接狀態、JDBC 封裝的維護)等,

3.2資料初始化

打開 mysql 控制臺,然后按如下步驟執行 notice.sql 檔案,
鏈接:https://pan.baidu.com/s/1J8ZOFDoiP1ic4aXWGaW8XQ
提取碼:k7xg

第一步:登錄 mysql,

mysql –uroot –proot

第二步:設定控制臺編碼方式,

set names utf8;

第三步:執行 notice.sql 檔案(切記不要打開檔案復制到 mysql 客戶端運行),

source d:/notice.sql

在這里插入圖片描述

3.3快速入門實踐

連接池產品 HikariCP 擁有強勁的性能和穩定性,再加上它自身小巧的身形,在當前的“云時代、微服務”的背景下,HakariCP 得到了越來越多的人青睞,HiKariCP 號稱是目

前世界上最快的連接池,有江湖一哥的稱號,

3.3.1添加依賴

添加依賴,其 pom 檔案關鍵元素如下:

<!--鏈接 mysql 時使用的 mysql 驅動-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<!--當添加 data-jdbc 依賴時會自動下載 HikariCp 依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

打開Settings -> Plugins ->下載插件
在這里插入圖片描述在這里插入圖片描述啟動快捷鍵 Alt+insert
在這里插入圖片描述選擇ok
在這里插入圖片描述
可以選擇需要增加的依賴
在這里插入圖片描述

3.3.2基本引數配置

打開 application.properties 組態檔,添加如下內容,

# spring datasource
spring.datasource.url=jdbc:mysql:///db_notice?serverTimezone=GMT%2B8 
spring.datasource.username=root
spring.datasource.password=root

hikariCP 其它額外配置,可通過搜索引擎進行查閱,

3.3.3撰寫及運行單元測驗,

在專案中添加單元測驗類及測驗方法,代碼如下:
在這里插入圖片描述

package com.cy.pj.sys.dao;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.*;

/**
 * 為springboot中的單元測驗類
 * 說明:
 * 1.springboot中的單元測驗類必須放在啟動類所在包或子包中
 * 2.springboot中的單元測驗類必須使用@SpringBootTest注解描述
 */
@SpringBootTest
public class DataSourceTests {
    /**
     * 在專案中添加了資料庫相關依賴以后,
     * springboot底層會自動幫我們配置一個資料源(DataSource)物件,
     * 此物件是連接池的規劃,
     * @Autowired 注解描述屬性時,是告訴spring框架,要基于反射機制為屬性賦值(依賴注入)
     * 賦值時,首先會基于屬性型別從spring容器查找相匹配的物件,假如只有一個則直接注入
     * 有多個相同型別的物件時,還會比較屬性名(檢查屬性名是否與bean名字相同),有相同的
     * 則直接注入(沒有相同的則直接拋出例外)
     *
     */

    @Autowired
    //private javax.sql.DataSource dataSource; //引入包名千萬不要引入錯了
    private DataSource dataSource; //簡寫
    @Test //org.junit.jupiter.api.Test
    void testGetConnection() throws SQLException {
        //獲取鏈接時,
        Connection conn = dataSource.getConnection();
        System.out.println("conn="+conn);
        //conn=HikariProxyConnection@1269826537 wrapping com.mysql.cj.jdbc.ConnectionImpl@12aa4996
    }
}

第四步:API 運行原理分析
在這里插入圖片描述

小結:


SpringBoot技術
1.是什么?
基于spring技術實作的一個腳手架,

2.基于此腳手架需要做什么?
快速構建專案開發環境,

3.為什么要使用springboot搭建環境?
提供了開箱即用的特性(依賴),自動裝箱…

4.springboot工程的創建,目錄結構,啟動分析
1)創建(基于http://start.spring.io官方提供的構建結構進行實作)

2)目錄結構?
2.1)src/main/java (java業務代碼)
2.2)src/main/resoutces (專案組態檔,靜態資源)
2.3)src/test/java (單元測驗代碼)
2.4)pom.xml(服務端依賴,maven插件配置)

3)專案的啟動
3.1)啟動類(@SpringBootTest)
3.2)啟動程序(了解啟動程序)

FAQ?

1)我們寫的類所在包與啟動類所在包要建立什么關系? .
2)啟動類在啟動時我如何知道加載了哪些類? (-XX: +TraceClassLoading)


HikariCP連接池

1.池化思想 (空間換時間,實作物件復用,進行減少物件創建銷毀帶來的系統開銷)
1)整數池(Integer[])
2)字串(char[])
3)執行緒池(ThreadPoolExecutor)
4)物件池(Spr ing中的bean池)
5)…


2.Java中連接池規范(DataSource)
1)為什么要創建連接池?(連接的創建和銷毀非常耗時-TCP/IP-3次握手,4次揮手)
2) java中連接池的規范? (javax. sql. DataSource)
3) java中連接池的江湖? (c3p0, dbcp , Druid , hikariCP ,…)
4)連接池設計思考?(資料存盤結構,演算法,執行緒安全,引數設計,… )

3.Java中的連接池規范實作-HikariCP
1)特點:日本人->設計小而精,性能高,穩定…
2)SpringBoot默認優先加載? (添加了spring - jdbc依賴會自動配置hikaricp)
3)連接池的測驗應用?
3.1)添加依賴? (mysq 1驅動, spring- jdbc依賴)
3.2)連接資料庫的配置(url,username,password)
3.3)構建單元測驗類及方法對連接池進行單元測驗?(獲取連接)
3.4)連接獲取原理分析?(@Test->DataSource->HikariDataSource->HikariPool->.)



3.4JDBC 操作練習

基于 JDBC 技術查詢資料庫表中的通告資訊,并進行單元測驗,

連接資料庫,并插入一條陳述句,

在這里插入圖片描述

# spring datasource
spring.datasource.url=jdbc:mysql:///db_notice?serverTimezone=GMT%2B8&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

配置完成后,執行測驗兩種連接方式:

getConnection() 方法,連接MySQL資料庫,

statement(sql傳送器->負責與將sql發送到資料庫端)

setTimestamp 方法,使用 Date 型設定指定列的值(在mysql中 date資料型別 只能存放年月日,所以只能用datetime型別,那在jdbc中,就要呼叫setTimestamp()方法,取出資料的時候,用結果集呼叫getTimstamp()方法,)

currentTimeMillis()計算方式與時間的單位轉換

package com.cy.pj.sys.dao;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.*;

/**
 * 為springboot中的單元測驗類
 * 說明:
 * 1.springboot中的單元測驗類必須放在啟動類所在包或子包中
 * 2.springboot中的單元測驗類必須使用@SpringBootTest注解描述
 */
@SpringBootTest
public class DataSourceTests {
    /**
     * 在專案中添加了資料庫相關依賴以后,
     * springboot底層會自動幫我們配置一個資料源(DataSource)物件,
     * 此物件是連接池的規劃,
     * @Autowired 注解描述屬性時,是告訴spring框架,要基于反射機制為屬性賦值(依賴注入)
     * 賦值時,首先會基于屬性型別從spring容器查找相匹配的物件,假如只有一個則直接注入
     * 有多個相同型別的物件時,還會比較屬性名(檢查屬性名是否與bean名字相同),有相同的
     * 則直接注入(沒有相同的則直接拋出例外)
     *
     */

    @Autowired
    //private javax.sql.DataSource dataSource; //引入包名千萬不要引入錯了
    private DataSource dataSource; //簡寫
    @Test //org.junit.jupiter.api.Test
    void testGetConnection() throws SQLException {
        //獲取鏈接時,
        Connection conn = dataSource.getConnection();
        System.out.println("conn="+conn);
        //conn=HikariProxyConnection@1269826537 wrapping com.mysql.cj.jdbc.ConnectionImpl@12aa4996
    }
    @Test
    void testSaveNotice01()throws SQLException{//homework (通過此方法基于jdbc向資料庫寫入一條資料)
        //JDBC (是java中推出的連接資料庫的一組API,是規范)
        //資料庫廠商提供JDBC驅動(jdbc規范的實作)負責實作資料庫的操作.
        //1.建立連接 (負責與資料庫進行通訊)
        Connection conn= dataSource.getConnection();
        //2.創建statement(sql傳送器->負責與將sql發送到資料庫端)
        String sql="insert into sys_notice " +
                " (title,content,type,status,createTime,createdUser,modifiedTime,modifiedUser) " +
                "  values ('加課通知','本周六加課','1','0',now(),'tony',now(),'tony') ";
        Statement stmt=conn.createStatement();
        //3.發送sql
        stmt.execute(sql);
        //4.處理結果
        //5.釋放資源(后續釋放資源要寫到finally代碼塊中)
        stmt.close();
        conn.close();//將連接回傳池中
    }
    @Test
    void testSaveNotice02()throws SQLException{//homework (通過此方法基于jdbc向資料庫寫入一條資料)
        //JDBC (是java中推出的連接資料庫的一組API,是規范)
        //資料庫廠商提供JDBC驅動(jdbc規范的實作)負責實作資料庫的操作.
        //1.建立連接 (負責與資料庫進行通訊)
        Connection conn= dataSource.getConnection();
        //2.創建statement(sql傳送器->負責與將sql發送到資料庫端)
        String sql="insert into sys_notice " +
                " (title,content,type,status,createTime,createdUser,modifiedTime,modifiedUser) " +
                "  values (?,?,?,?,?,?,?,?) ";//?表示占位符
        PreparedStatement stmt=conn.prepareStatement(sql);//預編譯方式創建Statement物件
        //3.發送sql
        stmt.setString(1,"開學通知");
        stmt.setString(2,"2021年2月18號 開學");
        stmt.setString(3,"1");
        stmt.setString(4,"0");
        stmt.setTimestamp(5,new Timestamp(System.currentTimeMillis()));
        stmt.setString(6,"jason");
        stmt.setTimestamp(7,new Timestamp(System.currentTimeMillis()));
        stmt.setString(8,"tony");
        stmt.execute();
        //4.處理結果
        //5.釋放資源(后續釋放資源要寫到finally代碼塊中)
        stmt.close();
        conn.close();//將連接回傳池中
    }
}

測驗兩種連接資料庫 運行結果:
在這里插入圖片描述

分析:

1.通過池中的連接借助JDBCAPI向資料庫表中寫入一 條通告資訊.
1.1)JDBC編碼步驟?
1.2)建立連接(Connect ion, Da taSource)
1.3)創建Statement (Statement, PreparedS tatement)
1.4)發送SQL
1.5)處理結果(查詢操作需要處理結果)
1.6)釋放資源

2.JDBC編程程序的問題分析
2. 1)步驟固定(記住了過后,有手就能寫,沒必要反復寫)
2. 2)占位符引數賦值代碼簡單,但需要重復撰寫.
2.3)行映射遠程代碼比較簡單,但是需要的代碼量比較大,需要反復撰寫
2.4)SQL陳述句不夠靈活(不支持分支結構,很難基于條件進行動態SQL的定制)

思考第三種查詢的方法

     //第三種連接方式(查詢)
    @Test
    void testSelectNotice( )throws SQLException{
        //1.建立連接
        Connection conn=dataSource.getConnection();
        //2.創建查詢陳述句,基于id查詢
        String sq1="select id,title,content,status, type,createTime "+
                " from sys_notice where id >= ?";
        PreparedStatement pstmt = conn.prepareStatement(sq1);
        //3.發送sql
        pstmt.setInt(1, 2);
        boolean flag=pstmt.execute();
        //4.處理結果
        if (flag){//true表示查詢,有結果集
            ResultSet rs=pstmt.getResultSet();
            List<Map<String,Object>> list=new ArrayList<>();

            while (rs.next()){//一行記錄應為一map物件(行映射)
                Map<String,Object> map=new HashMap();//將來也可以使用pojo物件
                // 將取出類的資料存盤到map(key為欄位名,值為欄位value)
                map.put("id",rs.getInt("id"));//取第一列的值
                map.put("title",rs.getString("title"));//取第二列的值
                map.put("content",rs.getString("content"));//取第二列的值
                map.put("status",rs.getString("status"));//取第二列的值
                map.put("type",rs.getString("type"));//取第二列的值
                map.put("createTime",rs.getTimestamp("createTime"));//取第二列的值
                //將每行記錄對應的map物件存盤到List集合
                System.out.println(map);
                list.add(map);
            }
            rs.close();
        }
        //5.釋放資源
        pstmt.close();
        conn.close();
    }
}

運行結果:
在這里插入圖片描述

在這里插入圖片描述

思考如何優化?

    //第四種連接方式(優化)
    @Test
    void testSelectNotice2( )throws SQLException{
        //1.建立連接
        Connection conn=dataSource.getConnection();
        //2.創建查詢陳述句,基于id查詢
        String sql="select id,title,content,status,type,createTime " +
                " from sys_notice where id>=?";
        PreparedStatement pstmt=conn.prepareStatement(sql);
        //3.發送sql(發送到資料庫)
        pstmt.setInt(1,2);
        boolean flag=pstmt.execute();

        //4.處理結果
        //獲取結果集中的元資料
        if (flag){//true表示查詢,有結果集
            ResultSet rs=pstmt.getResultSet();
            List<Map<String,Object>> list=new ArrayList<>();
            //獲取結果集中的元shuju (表名,欄位名)
            ResultSetMetaData rsmd=rs.getMetaData();
            while (rs.next()){//一行記錄應為一map物件(行映射)
                Map<String,Object> map=new HashMap();//將來也可以使用pojo物件(HashMap底層重寫了toString方法)
                // 將取出類的資料存盤到map(key為欄位名,值為欄位value)
                for (int i = 1; i < rsmd.getColumnCount(); i++) {
                    map.put(rsmd.getColumnLabel(i), rs.getObject(rsmd.getColumnLabel(i)));
                    //rsmd.getColumnLabel(i) 獲取第i列的名字
                }
                //下面這種寫法更加簡單,但是代碼量比較大
              /*  map.put("id",rs.getInt("id"));//取第一列的值
                map.put("title",rs.getString("title"));//取第二列的值
                map.put("content",rs.getString("content"));//取第二列的值
                map.put("status",rs.getString("status"));//取第二列的值
                map.put("type",rs.getString("type"));//取第二列的值
                map.put("createTime",rs.getTimestamp("createTime"));//取第二列的值*/
                //將每行記錄對應的map物件存盤到List集合
                System.out.println(map);
                list.add(map);
            }
            rs.close();
        }
        //5.釋放資源
        pstmt.close();
        conn.close();
    }
}

運行結果:
在這里插入圖片描述

3.5小節總結(summary)

3.5.1重難點分析

理解 DataSource 規范及規范的實作,
掌握單元測驗類、測驗方法撰寫規范,

3.5.2FAQ 分析

Java 中與資料庫建立連接需要什么?資料庫驅動
這個資料庫驅動的設計需要遵守什么規范嗎?JDBC
當我們通過 JDBC API 獲取到一個連接以后,應用結束我們會將連接回傳到池中嗎?會

連接池在應用時有什么弊端嗎?(會帶來一定的記憶體開銷,以空間換時間)
假如現在讓你去設計一個連接池,你會考慮哪些問題?(存盤,演算法,執行緒,引數)

3.5.3BUG 分析

位置錯誤,當出現如圖-情況時,先檢測單元測驗類是否寫到了src/test/java 目錄,如圖所示:
在這里插入圖片描述
類引入錯誤,DataSource 為javax.sql 包中的型別,如圖所示:
在這里插入圖片描述
連接錯誤:資料庫連接不上,如圖所示:
在這里插入圖片描述

4. MyBatis 持久化設計實作

4.1概述

Mybatis 是一個優秀的持久層框架,底層基于 JDBC 實作與資料庫的互動,并在 JDBC 操作的基礎上做了封裝和優化,它借助靈活的 SQL 定制,引數及結果集的映射方式,更好的適應了當前互聯網技術的發展,Mybatis 框架的簡單應用架構,如圖-15 所示:

在這里插入圖片描述

在當今的互聯網應用中專案,mybatis 框架通常會由 spring 框架進行資源整合,作為資料層技術實作資料互動操作,

4.2添加依賴

第一步:添加 mybatis 啟動依賴,

啟動快捷鍵 Alt+insert
在這里插入圖片描述

在這里插入圖片描述

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>

我們添加了 mybatis 依賴以后,spring 框架啟動時會對 mybatis 進行自動配置,例如 SqlSessionFactory 工廠物件的創建,
第二步:Mybatis 簡易配置實作,
假如需要對 mybatis 框架進行簡易配置,可以打開 application.properties 檔案,在此檔案中進行基本配置(可選,暫時可以不配置),例如:

mybatis.configuration.default-statement-timeout=30 
mybatis.configuration.map-underscore-to-camel-case=true 
mybatis.mapper-locations=classpath:/mapper/*/*.xml

配置 mybatis 中的 sql 日志的輸出:(com.cy 為我們寫的專案的根包)

logging.level.com.cy=DEBUG

4.3 環境測驗代碼實作

在 src/test/java 目錄中添加測驗類,對 mybatis 框架整合進行基本測驗,代碼如下:

package com.cy.pj.sys.dao;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.sql.Connection;

@SpringBootTest
public class MyBatisTests {
    /**
     * sqlsession是mybatis框架中實作與資料庫進行繪畫的入口物件
     * 加入我們可以通過此物件獲取與資料庫的來凝結,表示可以通過mybatis框架實作與資料庫會話
     */
    @Autowired
    //這里的sqlSession指向的物件是誰?
    // (sqlSessionTemplate實作了執行緒介面,并且執行緒安全)
    //不能隨意修改介面,行業規范
    private SqlSession sqlSession;

    @Test
    public void testGetConnection(){
        //連接來自哪里?(來源與連接池(底層會自動將連接池注入給mybatis框架))
        Connection conn=sqlSession.getConnection();
        System.out.println("conn="+conn);
    }
}

在 SpringBoot 腳手架工程中,Spring 框架會基于 MyBatis 框架底層配置,創建SqlSessionFactory 物件,然后再通過此工廠物件創建 SqlSession,最后基于 Springku 框架為測驗類注入 SqlSession 物件,接下來,我們可以通過 SqlSession 物件實作與資料庫的會話了,

4.4通告業務設計及實作

4.4.1業務描述

基于 SpringBoot 腳手架工程對 MyBatis 框架的整合,實作對通告資料的操作,

4.4.2Pojo 類設計

創建 SysNotice 類,借助此類物件封裝公告(通知)資料,

package com.cy.pj.sys.pojo;

/**
 * SysNotice物件用于存盤通知資料(例如)
 * Java中的物件可以簡單分為兩大型別:
 * 1) 一類是用于執行邏輯(打天下-控制邏輯,業務邏輯,資料持久邏輯)的物件
 * 2)一 類是用于存盤資料(守天下-pojo)的物件
 */
public class SysNotice {
     private static final long serialVersionUID = 1L;

     /** 公 告 ID */ 
     private Long id;

     /** 公 告 標 題 */ 
     private String title;

     /** 公告型別(1 通知 2 公告) */
     private String type;

     /** 公告內容 */
     private String content;

     /** 公告狀態(0 正常 1 關閉) */ 
     private String status;

     /** 創建時間 */
     private Date createdTime;

     /** 修改時間*/
     private Date modifiedTime;

     /** 創建用戶 */
     private String createdUser;

     /** 修改用戶*/
     private String modifiedUser;
     
     /** 備注*/
     private String setRemark;
     
     //自己添加 set/get/toString 方法
}

4.4.3 Dao 介面及方法

第一步:定義通告業務資料層介面及業務方法,

package com.cy.pj.sys.dao; 
@Mapper
public interface NoticeDao {
     List<Notice> selectNotices(Notice notice);
     int deleteById(Long… id);

     @Select("select * from sys_notice where id=#{id}")//注解方式宣告sql,復雜sql寫入xml中
     Notice selectById(Integer id); //基于id去查詢
     int insertNotice(Notice notice); //往表中寫資料
     int updateNotice(Notice notice);//修改表資料
}

在 src/test/java 目錄中添加測驗類,測驗,代碼如下:

package com.cy.pj.sys.dao;

import com.cy.pj.sys.pojo.SysNotice;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class SysNoticeDaoTests {
    @Autowired
    private SysNoticeDao sysNoticeDao;

    @Test
    void testInsertNotice(){
        //創建SysNotice物件
        SysNotice notice=new SysNotice();
        notice.setTitle("CGB2011放假了");
        notice.setContent("2021/02/08正式放假");
        notice.setCreatedUser("清風");
        notice.setModifiedUser("清風");
        //將SysNotice物件持久化到資料庫
        sysNoticeDao.insertNotice(notice);//此方法的實作內部會通過SQLSession向表中寫入資料,
    }
}

其中:@Mapper 是由 MyBatis 框架中定義的一個描述資料層介面的的注解(所有的注解只起到一個描述性的作用),用于告訴 Spring 框架此介面的實作由 mybatis 創建,并將其實作類物件存盤到 spring 容器,

第二步:創建 NoticeDao 介面對應的 SQL 映射檔案,名字為 SysNoticeMapper.xml,
存盤在 resources/mapper/sys 目錄下,同時定義 xml 檔案頭以及根元素,代碼如下:

<?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.cy.pj.sys.dao.NoticeDao">
</mapper>

第三步:在映射檔案中添加 insertNotice 方法對應的 Sql 映射,關鍵代碼如下:

<insert id="insertNotice"  parameterType="com.cy.pj.sys.pojo.SysNotice"> 
     insert into sys_notice
     (title,type,content,status,remark, 
     createdTime,modifiedTime,createdUser,modifiedUser) 
     values 
     (#{title},#{type},#{content},#{status},#{remark},
     now(),now(),#{createdUser},#{modifiedUser})
</insert>

第四步:在映射檔案中添加基于條件的 SQL 查詢映射,關鍵代碼如下:

<select id="selectNotices"
      resultType="com.cy.pj.sys.pojo.Notice"> select *
      from sys_notices
      <where>
        <if test="title!=null and title!=''">
            title like concat ("%",#{title},"%")
        </if>
        <if test="createdUser!=null and createdUser!=''">
        and createdUser like concat ("%",#{createdUser},"%")
        </if>
        <if test="type!=null and type!=''">
          and type = #{type}
       </if>
    </where>
</select>

第五步:在映射檔案中定義更新公告對應的 SQL 映射,關鍵代碼如下:

<update id="updateNotice"> 
     update sys_notice
      set title=#{title},type=#{type},content=#{content}, 
      status=#{status},remark=#{remark},modifiedTime=now(), 
      modifiedUser=#{modifiedUser}
      where id=#{id}
</update>

第六步:在映射檔案中定義洗掉操作對應的 SQL 映射,關鍵代碼如下:

<delete id="deleteObjects"> 
      delete from sys_notice
      <where>
         <if test="ids!=null and ids.length>0"> 
         id in
         <foreach collection="ids" open="(" close=")" 
            separator="," item="id">
            #{id}
         </foreach>
        </if> 
        or 1=2
      </where>
</delete>

在 src/java/test 目錄下定義測驗類,對 NoticeDao 物件進行應用測驗,

package com.cy.pj.sys.dao; import java.sql.SQLException; import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class NoticeDaoTests {
     @Autowired
     private NoticeDao noticeDao;.
}

4.5小節總結(Summary)

4.5.1重難點分析

4.5.2FAQ 分析

4.5.3BUG 分析

5Service 物件設計及實作

5.1概述

分層架構設計中通常會借助業務邏輯物件處理請求的核心和拓展業務,

5.2快速入門實踐

定義通知業務邏輯介面及相關方法,關鍵代碼如下:

package com.cy.pj.sys.service; 
public interface SysNoticeService {
      int saveNotice(Notice notice); 
      List<Notice> findNotices(Notice notice); 
      int deleteById(Integer[] ids);
      Notice findById(Integer id);
      Int updateNotice(Notice notice);
}

5.2.2 實作類設計

定義通知業務邏輯介面的實作類,并重寫業務方法,關鍵代碼如下:

package com.cy.pj.sys.service;
 @Service
public class SysNoticeServiceImpl implements SysNoticeService {

      @Autowired
      private SysNoticeDao sysNoticeDao; 
      public int saveNotice(Notice notice){
         int rows=sysNoticeDao.insertNotice(notice); 
         return rows;
      }
      public List<Notice> findNotices(Notice notice){
         return sysNoticeDao.selectNotices();
      }
      public int deleteById(Integer[] ids){
          int rows=sysNoticeDao.deleteById(ids); 
          return rows;
      }

      public Notice findById(Integer id){
      Notice notice=sysNoticeDao.selectById(id); 
      return notice;
      }
      public int updateNotice(Notice notice){
      int rows=sysNoticeDao.updateNotice(notice);
      return rows;
}

5.2.3 單元測驗分析


package com.cy.pj.sys.service;
@SpringBootTest
public class NoticeServiceTests{
      @Autowired
      private SysNoticeService noticeService;..
}

6 Spring Web 模塊設計及實作

6.1概述

MybatisSpring MVC 是 Spring 框架中基于 MVC 設計思想,實作的一個用于處理 Web 請求的模塊,這個模塊封裝了對 Servlet 的技術的應用,簡化了程式員對請求和回應程序中資料的處理,其簡易架構分析如圖-37 所示:
在這里插入圖片描述
圖-9 中,核心組件分析:

圖-37

DispatcherServlet :前端控制器, 處理請求的入口,
HandlerMapping:映射器物件, 用于管理 url 與對應 controller 的映射關系,
Interceptors:攔截器,實作請求回應的共性處理,
Controller:后端控制器-handler, 負責處理請求的控制邏輯,

備注:假如希望了解 Spring MVC 的詳細處理流程可以基于斷點除錯法進行跟蹤,

6.2初始配置

添加 Spring Web 依賴(提供了 spring mvc 依賴支持),代碼如下:

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

其中,這個依賴添加時,會關聯下載一個 tomcat 依賴(這個 tomcat 為一個嵌入式tomcat 服務器)

6.3快速入門實踐

6.3.1Controller 類及方法

創建 SysNoticeController 類,處理客戶端請求,
第一步:創建 SysNoticeController 類,并關聯 service 物件,關鍵代碼如下

package com.cy.pj.sys.web.controller;


@RestController 
@RequestMapping("/notice/")
public class SysNoticeController { 
@Autowired
private SysNoticeService sysNoticeService;
}

第二步:添加處理請求的方法,關鍵代碼如下:

@RequestMapping("doUpdateNotice")
Public String doUpdateNotice(Notice notice){ 
      sysNoticeService.updateNotice(notice);
       return "update ok";
}
      @RequestMapping("doFindById/{id}")
      public Notice doFindById(@PathVariable Integer id){
       return sysNoticeService.findById(id);
      }

      @RequestMapping ("doSaveNotice")
      Public String doSaveNotice (Notice notice){
       sysNoticeService.saveNotice(notice);
        return "save ok";
      }

      @RequestMapping("doDeleteById")
      public Notice doDeleteById(Integer… ids){
         return sysNoticeService.deleteById(ids);
      }

      @RequestMapping("doFindNotices")
      public List<Notice> doFindNotices(Notice){
         return sysNoticeService.findNotices(Notice);
      }

6.3.2Postman 應用

基于 Postman 向服務端發送請求,進行訪問測驗,

6.4小節總結(Summary)

7總結(Sumamry)

7.1重難點分析

7.2FAQ 分析

7.3Bug 分析

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/253597.html

標籤:其他

上一篇:“寒武紀大爆發”之后的云原生,2021年走向何處?

下一篇:一致性哈希原理應用

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more