Mybatis框架的集成使用

1_框架概述

框架是一個半成品,已經對基礎的代碼進行了封裝并提供相應的API,開發者在使用框架時直接調用封裝好的api可以省去很多代碼編寫,從而提高工作效率和開發速度,框架是一種經過校驗、具有一定功能的半成品軟件.

經過校驗:指框架本身經過測試,且框架自身所具有的功能已經實現具有一定功能:指框架可以完成特定的功能,不同的框架功能不同

半成品軟件:指框架自身是一個軟件,但是該軟件無法直接運行,需要配合其他的程序才可以完成指定的工作.

框架的工作模式:

開發工程師建立在框架的基礎之上完成開發部分功能 加 框架自身完成部分功能組成一個完整的產品

2_MyBatis 基礎

2.1_MyBatis的概述

MyBatis 是一款優秀的持久層框架,它支持定制化?SQL、存儲過程以及高級映射。MyBatis?避免了幾乎所有的?JDBC 代碼和手動設置參數以及獲取結果集MyBatis?可以使用簡單的?XML?或注解來配置和映射原生類型、接口和?Java ?POJOPlain Old Java Objects,普通老式?Java 對象)為數據庫中的記錄。

mybatis框架架構圖:

我們把Mybatis的功能架構分為三層:

  1. API接口層:提供給外部使用的接口API開發人員通過這些本地API來操縱數據庫。接口層一接收到調用請求就會調用數據處理層來完成具體的數據處理。
  2. 數據處理層:負責具體的SQL查找、SQL解析、SQL執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次數據庫操作。
  3. 基礎支撐層:負責最基礎的功能支撐,包括連接管理、事務管理、配置加載和緩存處理,這些都是共用的東西,將他們抽取出來作為最基礎的組件。為上層的數據處理層提供最基礎的支撐。

2.2_環境準備

需求: 向用戶表中添加一條數據

  1. 添加項目需要的?jar
  2. lombok-1.16.6.jar(新的IDEA不用添加)

Lombok自動生成?getter/setter/toString 等方法使用的前提是已經在?idea 中安裝了?lombok 插件

  1. mysql-connector-java-5.1.26-bin.jar

MySQL 數據庫的?JDBC 驅動包,訪問?MySQL 必須導入備?jar

  1. mybatis-3.4.5.jar MyBatis 框架的核心?jar
  2. 創建一張用戶表:user

CREATE TABLE `user` (

`id` bigint(20) NOT?NULL?AUTO_INCREMENT,

`name` varchar(255) DEFAULT NULL,

`age` int(255) DEFAULT NULL,

`salary` decimal(10,0) DEFAULT NULL

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2?DEFAULT CHARSET=utf8;

  1. 根據表結構創建實體類

@Getter@Setter@ToString

@NoArgsConstructor@AllArgsConstructor

public class User?{

private Long?id;

private String?name;

private Integer?age;

private BigDecimal salary;

private Date hiredate;

}

  1. mybatis主配置文件: mybatis-config.xml
  2. 在項目的resources(source folder)下創建mybatis-config.xml配置文件
  3. 拷貝xml的約束

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration

PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

添加環境配置(事務管理器?/ 連接池?/ 映射文件)

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration

PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<environments default="dev">

<environment id="dev">

<!--

MyBatis 內置的事務管理器

JDBC:org.apache.ibatis.transaction.jdbc.JdbcTransaction的別名

-->

<transactionManager type="JDBC"/>

<!--

MyBatis 內置的連接池

POOLED:org.apache.ibatis.datasource.pooled.PooledDataSource的別

-->

<dataSource type="POOLED">

<!--

driver:這是POOLED連接池對象的驅動類的屬性名,

Druid連接池對象的驅動類屬性名是driverClassName

-->

<property name="driver"?value="com.mysql.jdbc.Driver"/> <property name="url"?value="jdbc:mysql:///mybatis"/

<property name="username"?value="root"/>

<property name="password"?value="admin"/>

</dataSource>

</environment>

</environments>

<mappers>

<mapper resource="cn/UserMapper.xml"/> </mappers>

</configuration>

  1. mapper 映射文件: UserMapper.xml

mybatis,訪問數據庫的SQL語句是編寫在mapper配置文件中的,程序員按照這個文件約定的格式進行配置即可

中創建配置文件: UserMapper.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">

在配置文件中添加?SQL 語句

<!--

一個項目可以操作多張表

每張表都需要一個mapper配置文件來編寫SQL語句

每條SQL語句都需要有一個唯一的標識

這個唯一的標識由?namespace + sqlid 組成

使用下面的namespace+sqlid就得到了保存用戶信息的唯一標識:

insert 接下來,我們就可以使用上面的標識找到這條SQL語句了

-->

<mapper namespace="cn.UserMapper"> <insert id="insert">

insert into user(name,age,salary,hiredate)

values(#{name}, #{age}, #{salary}, #{hiredate})

</insert>

</mapper>

注意: 一定記得在?mybatis-config.xml 配置文件中關聯映射文件

<mappers>

<!--

這里是mapper文件的路徑,所以使用/分割

-->

<mapper resource="cn/UserMapper.xml"/> </mappers>

2.3_DAO層開發

  1. dao接口

創建?dao 接口: IUserDAO.java

public interface IUserDAO?{

/**

  • user表中插入一條數據
  • @param u 要插入的數據

?*/

void insert(User u);

}

  1. dao 接口實現類

創建?dao 的實現類: UserDAOImpl.java

按以下?API 實現數據的保存操作:

  1. SqlSessionFactory : 對連接池(DataSource)的封裝

SqlSession openSession() : 獲取SqlSession對象

  1. SqlSession,對連接(Connection)的封裝

int insert(String statementid, Object param);

statementid: mapper配置文件中的namespace+sqlid組成?void commit(): 提交事務

void close() : 釋放資源

  1. 調用?SqlSession 中的?insert 方法,執行指定的?SQL

public class UserDAOImpl?implements IUserDAO?{?public void?insert(User u) {

try {

InputStream in =?Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactory fac =?new

SqlSessionFactoryBuilder().build(in);

SqlSession session =?fac.openSession();

session.insert("UserMapper.insert",

);

session.commit();

session.close();

} catch?(Exception e) {

e.printStackTrace();

}

}

}

在測試類中測試?insert 方法

public class UserDAOTest?{

private IUserDAO dao?=?new UserDAOImpl();

@Test

public void?testInsert() {

User u =?new?User(null,"張三",20,new?BigDecimal(20000),?new?Date());?dao.insert(u);

}

}

2.4_MyBatis 執行流程

  • 加載主配置文件(mybatis-config.xml)到內存中,將數據封裝成對象Configuration/Environment/TransactionManager/DataSource
  • 通過操作拿到訪問數據庫的基本信息,根據這些數據創建?SqlSessionFactory 對象
  • ?SqlSessionFactory 對象中獲取到?SqlSession 對象,然后執行SQL
  • INSERT INTO user(name,age,salary,hiredate) VALUES(#{name},#{age},#{salary},#{hiredate})

被翻譯成

INSERT INTO user(name,age,salary,hiredate)

VALUES(?, ?, ?, ?)

  1. 使用?PreparedStatement 來執行指定的SQL

從傳遞進來的?User 對象中依次獲取到?name/age/salary/hiredate這些屬性的值這里需要使用到內省機制來訪問對象中的屬性

:

在加載完當前映射文件之后,會將SQL中的?#{} OGNL表達式翻譯成對應的占位符?,

執行上面的SQL,需要將數據設置給當前的語句對象?ps.setObect(1, 從參數中獲取到name屬性的值); ps.setObect(2, 從參數中獲取到age屬性的值); ps.setObect(3, 從參數中獲取到salary屬性的值); ps.setObect(4, 從參數中獲取到hiredate屬性的值);

操作步驟回顧:

  1. 創建項目,導入jar
  2. 創建表和模型

3 創建?mybatis-config.xml 配置環境

4 創建?UserMapper.xml 文件 存在?mapper包中,配置sql語句

5 創建?dao 接口和實現類

6 啟動?MyBatis 去執行插入操作

  1. 測試插入操作

3_獲取插入數據生成的主鍵

在開發中,如果需要獲取到數據庫中自動生成的主鍵,那么使用?MyBatis 應該如何實現呢?

<insert id="insert"?useGeneratedKeys="true"?keyProperty="id"?keyColumn="id"> insert into user(name,age,salary,hiredate)

values(#{name}, #{age}, #{salary}, #{hiredate})

</insert>

useGeneratedKeys: 是否要獲取自動生成的主鍵

keyColumn: 表中的主鍵列

keyProperties: 主鍵列對應的屬性

表示從獲取哪個列的值封裝到哪個屬性中

通過上面的配置,在執行了保存操作后,mybatis 會自動將主鍵值封裝到傳遞進來的?User 對象的?id 屬性

所以,此時的?User 對象的?id 屬性就有值了(在保存之前是沒有的)

parameterType : 參數類型,可以不用寫,MyBatis自己通過用戶傳入的對象去推導.

4_更新和刪除操作

和保存操作的開發流程一致,在完成了保存操作之后,更新和刪除操作一樣可以實現?dao 中更新的實現

@Overrid

public void?update(User u) {

try {

InputStream in =?Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactory fac =?new?SqlSessionFactoryBuilder().build(in);

SqlSession session =?fac.openSession();

session.update("UserMapper.update",?u);

session.commit();

session.close();

} catch?(Exception e) { e.printStackTrace();

}

}

更新在?mapper 中的?SQL

<update id="insert">

update user

set?name=#{name}, age = #{age}, salary = #{salary}, hiredate = #{hiredate} where

id = #{id}

</insert>

dao 中刪除的實現

@Override

public void?delete(long?id) {

try {

InputStream in =?Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactory fac =?new?SqlSessionFactoryBuilder().build(in);

SqlSession session =?fac.openSession();

session.delete("UserMapper.delete",?id);

session.commit();

session.close();

} catch?(Exception e) { e.printStackTrace();

}

}

刪除在?mapper 中的?SQL

<delete id="delete">

delete from user where id = #{id}

</delete>

注意:

1 當傳入的只有一個普通類型(一個值)的時候#{} 中的名稱可以隨便寫,但是建議見名知義

2 不管使用的是?insert 方法還是?delete 方法,底層調用的還是update方法,通過sql語句來區別dml操作

5_查詢操作

根據?id 查詢用戶

dao 實現

@Override

public User?selectOne(long?id) {

User u =?null;

try {

InputStream in =?Resources.getResourceAsStream("mybatis-config.xml");?SqlSessionFactory fac =?new?SqlSessionFactoryBuilder().build(in);?SqlSession session =?fac.openSession();

u =?session.selectOne("cn.UserMapper.selectOne",

id);

session.close();

} catch?(Exception e) {

e.printStackTrace();

}

return u;

}

mapper 中的?SQL

<select id="selectOne"?resultType="cn.domain.User"> select * from user where id = #{id}

</select>

?DML 不一樣的地方,查詢操作需要指定把查詢的結果集數據封裝成什么類型的對象,resultType 屬性就是這個作用

思考: resultType 可以不配置嗎? 不可以,需要告訴?MyBatis 把一行數據封裝成什么類型的對象

目前: 需要模型的屬性和表的列需要一一匹配,如果不匹配,無法獲取到數據.

查詢所有用戶

dao 實現

@Override

public List<User>?selectList() {

List<User>?users =?null;

try {

InputStream in =?Resources.getResourceAsStream("mybatis-config.xml");?SqlSessionFactory fac =?new?SqlSessionFactoryBuilder().build(in);?SqlSession session =?fac.openSession();?users =

session.selectList("cn.UserMapper.selectAll");

session.close();

} catch?(Exception e) { e.printStackTrace();

}

return users;

}

mapper 中的?SQL

<select id="selectAll"?resultType="cn.domain.User"> select * from user

</select>

6_細節處理

類型別名

在查詢操作中, 我們需要使用result屬性指定數據封裝的類型, 這里的值類型的全限定名, 每次都編寫的話比較麻煩,為了簡化這里的配置,我們可以在主配置文件(mybatis-config.xml)中對指定的類型做別名的配置

<!-- 為指定包中的類來生成別名,默認是類的簡單名稱?-->

<typeAliases>

<package name="cn.domain"/> </typeAliases>

如此,我們在查詢的SQL, 使用類的全限定名和使用別名是等價的修改前:

<select id="selectAll"?resultType="cn.User"> select * from user

</select>

修改后:

<select id="selectAll"?resultType="User">

select * from user

</select>

日志管理

在持久層的開發過程中,我們程序員需要隨時觀察SQL的執行情況,如果sql有問題,我們能夠及時發現所以,如果能夠在控制臺中將我們執行的SQL全部打印出來,那么就可以方便的觀察SQL的相關問題

配置日志文件監控MyBatis的運行.

  1. 將日志相關的jar包添加到項目中

???????

2. resources(source folder)中創建配置文件, log4j.properties ,添加下面的內容(直接拷貝)

  1. Global logging configuration log4j.rootLogger=ERROR, stdout
  2. 配置要打印日志的包 log4j.loggr..mybatis=TRACE
  3. Console output...

log4j.appender.stdout=org.apache.log4j.ConsoleAppender?log4j.appender.stdout.layout=org.apache.log4j.PatternLayout?log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

將配置中的 包路徑修改為項目中對應的路徑,我們這里可以使用: cn.mybatis

到此,我們每執行一條?SQL, 都會在控制臺中打印出來,這非常有助于我們對?SQL 的分析,特別是?SQL 不正確的時候

7_抽取?MyBatisUtil 工具類

?JDBC 中的連接池使用一樣,在整個項目中,我們只需要一個SqlSessionFactory對象,而不需要每次都創建一個新的,

所以,我們將SqlSessionFactory的創建和SqlSession對象的獲取都抽取到工具類中: MyBatisUtil

注意:

加載配置文件沒有填寫:

8_抽取db.properties

在主配置文件中配置的內容較多, 其中包括我們修改頻率較高的數據庫連接信息(driver/url/username/password),我們可以在修改這些信息的過程中誤改或者誤刪到其他的配置,為了解決這個問題,我們仍然是將這些信息配置到db.propertie配置文件中,然后再合并到主配置文件即可,如下:

db.properties

driverClassName=com.mysql.jdbc.Driver

url=jdbc:mysql://localhost:3306/javaweb

username=root

password=admin

mybatis-cofnig.xml

<configuration>

<!-- 關聯db.properties:為了把連接數據庫的信息單獨放到一個配置文件?--> <properties resource="db.properties"?/>

<!-- 為指定包中的類來生成別名?-->

<typeAliases>

<package name="cn.domain"/> </typeAliases>

<!-- 連接數據庫的環境

default:指定使用哪一個環境的配置

-->

<environments default="dev">

<environment id="dev">

<transactionManager type="JDBC"/>

<dataSource type="POOLED">

<!--

使用${key}取出db.properties中配置的信息

keydb.properties文件中的可以一直即可

-->

<property name="driver"?value="${driverClassName}"/> <property name="url"?value="${url}"/>

<property name="username"?value="${username}"/> <property name="password"?value="${password}"/>

</dataSource>

</environment>

</environments>

<!-- 關聯映射文件?-->

<mappers>

<mapper resource="cn\mapper\ProductMapper.xml"/> </mappers>

</configuration>

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

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

相關文章

【超萬卡GPU集群關鍵技術深度分析 2024】

文末有福利&#xff01; 1. 集群高能效計算技術 隨著大模型從千億參數的自然語言模型向萬億參數的多模態模型升級演進&#xff0c;超萬卡集群吸需全面提升底層計算能力。 具體而言&#xff0c;包括增強單芯片能力、提升超節點計算能力、基于 DPU (Data Processing Unit) 實現…

淺聊權限系統設計模型

淺聊權限系統設計模型 設計權限目的 目前主流的各類權限管理模型,如基于用戶、角色組、實體等等的權限模型,結合產品本身的業務、面臨的問題和未來的發展兼容,進行權限模型選型,找到適合產品本身的權限范式體系。 權限模型類型 ACL:權限控制列表(Access Control List)D…

Mx Admin 基于react18的后臺管理系統

前言 Mx Admin 基于React18 vite5 antd5的后臺管理系統&#xff0c; 基于RBAC的權限控制系統&#xff0c;動態菜單和動態路由支持tab路由緩存嵌套菜單支持多種菜單布局模式亮暗色主題切換

Enzo Life Sciences熱點分享:細胞治療中的T細胞活化

細胞治療&#xff08;Cell Therapy&#xff09;作為一種新近發展起來的癌癥治療方法&#xff0c;是一種利用患者自體&#xff08;或異體&#xff09;的成體細胞&#xff08;或干細胞&#xff09;對組織、器官進行修復的治療方法。通常是由免疫細胞和相關的細胞產生調節細胞功能…

Java判斷范圍型的數據是否存在重疊(數值類型、日期類型)

為什么寫這么一篇文章呢&#xff1f; 遇到了個問題&#xff0c;同一天可以輸入多個時間段&#xff0c;但是每個時間段的時間不能出現重疊。 納尼&#xff0c;這不就是判斷數據返回是否有重疊的變種嘛~ 簡單&#xff0c;開搞 數字范圍是否重疊判斷 這里以int類型為例了&…

linux配置qqbot(Mirai+Alicebot)

雖然最終沒有成功配置好qqbot&#xff0c;但是感覺這個過程還是值得記錄的&#xff0c;所以寫出了下文 最終因為登陸qq時的code45問題導致沒有成功登錄&#xff0c;據說更換qq號或者配置簽名服務器是有可能可行的。 安裝環境 安裝mcl&#xff08;mirai的控制臺&#xff09; …

【單片機畢業設計選題24046】-基于單片機的智能魚缸設計

系統功能: 檢測水溫&#xff0c;水溫過低開啟PTC加熱。檢測水位&#xff0c;水位過低開啟水泵抽水。檢測濕度&#xff0c;濕度過高則開啟風扇通風。 檢測PH值和渾濁度&#xff0c;TTS語音播報功能&#xff0c;OLED顯示系統信息&#xff0c;藍牙模塊連接手機APP。 系統上電后…

IT專業入門,高考假期預習指南—初識產品經理BRD、MRD 和 PRD

七月來臨&#xff0c;各省高考分數已揭榜完成。而高考的完結并不意味著學習的結束&#xff0c;而是新旅程的開始。對于有志于踏入IT領域的高考少年們&#xff0c;這個假期是開啟探索IT世界的絕佳時機。作為該領域的前行者和經驗前輩&#xff0c;你是否愿意為準新生們提供一份全…

AI 芯片之戰:開啟智能新時代的關鍵角逐

在科技發展的浪潮中&#xff0c;一場圍繞 AI 芯片的激烈競爭正在全球范圍內如火如荼地展開。多家巨頭紛紛投身其中&#xff0c;使得這場混戰已然進入白熱化階段。 AI 芯片&#xff0c;作為推動人工智能發展的核心硬件&#xff0c;其作用舉足輕重。它能夠高效地處理海量的數據&a…

生物分子生物學實驗過程的自動化與智能監控系統設計

開題報告&#xff1a;生物分子生物學實驗過程的自動化與智能監控系統設計 一、引言 隨著生物科學技術的飛速發展&#xff0c;生物分子生物學實驗在科研、醫療、農業等領域的應用日益廣泛。然而&#xff0c;傳統的生物分子生物學實驗過程大多依賴于人工操作&#xff0c;存在操…

java web 部分

jsp作用域由大到小 過濾器有哪些作用&#xff1f; 過濾器的用法&#xff1f;&#xff08;對客戶端的請求統一編碼和對客戶端進行認證&#xff09; JSP和Servlet中的請求轉發分別如何實現&#xff1f; JSP 和 Servlet 有哪些相同點和不同點&#xff0c;他們之間的聯系是什么…

PCB設計時,信號走線要先過ESD/TVS管,這是為什么?

目錄 為什么有上面這個問題&#xff1f; 問題的原因——走線電感 走線電感的阻抗 電感的影響 小結 都說接口處的信號要先過ESD/TVS管&#xff0c;然后拉到被保護器件&#xff0c;為什么不這樣做效果就不好&#xff1f;那如果受板子實際情況限制&#xff0c;必須這樣layout…

Python - 單引號與雙引號

Python 版本 3.11.4 字符串 單個文字符稱為字符&#xff0c;多個文字符成為字符串。 字符串需要被&#xff08;單引號&#xff09;或者""&#xff08;雙引號&#xff09;包括。 language "Python"language Python 以上寫法都是合法的。 單引號與雙…

Zabbix 配置MySQL數據庫監控

Zabbix MySQL數據庫監控簡介 通過 Zabbix 監控 MySQL 數據庫&#xff0c;可以獲取有關數據庫性能、運行狀況和資源使用情況的詳細信息&#xff0c;幫助及時發現和解決問題。 Zabbix官方提供了一個名為MySQL by Zabbix agent的監控模板&#xff0c;該模板專為 Zabbix 通過 Zabb…

探索Vim表達式寄存器:提升文本處理的高級技巧

探索Vim表達式寄存器&#xff1a;提升文本處理的高級技巧 Vim是一款功能強大的文本編輯器&#xff0c;它擁有豐富的寄存器系統&#xff0c;用于存儲文本、命令等。表達式寄存器是Vim中一種特殊的寄存器&#xff0c;允許用戶存儲并操作表達式的結果。本文將詳細介紹如何在Vim中…

使用Spring Boot和mkcert解決本地及局域網HTTPS訪問

在現代Web開發中&#xff0c;HTTPS已經成為保障數據傳輸安全的標準。然而&#xff0c;在開發和測試階段&#xff0c;配置HTTPS可能會帶來一些額外的復雜性。尤其是在本地開發環境和局域網內網環境中&#xff0c;獲得和配置證書通常是一個挑戰。本文將介紹如何使用Spring Boot和…

關于在自己的生活里面,增加喝咖啡的這道手續

前言&#xff1a;我總在告訴我自己&#xff0c;我自己應該如何&#xff1f;我的未來應該如何&#xff1f;到那時實際上&#xff0c;自己沒有辦法能夠理解的確實我的現在&#xff0c;我應該依靠咖啡度過我自己剩下的歲月&#xff0c;接下來&#xff0c;讓自己用自己的方式來不斷…

華為5288 V5服務器安裝BCLinux8U4手記

本文記錄了華為5288 V5服務器安裝BCLinux8U4操作系統的過程。 一、系統環境 1、服務器 華為FusionServer Pro 5288 V5服務器 2、操作系統 BCLinux-R8-U4-Server-x86_64-220725.iso 官網下載地址 sha256sum&#xff1a;1d31d3b8e02279e89965bd3bea61f14c65b9d32ad2ab6d4eb…

DTP 抽取出錯:data target is locked by process***

怎么會顯示被幾年前的一個process lock住了呢&#xff1f; 搞不明白。 不管怎樣&#xff0c;去RSPM_MONITOR改&#xff0c;data target填上ADSO名&#xff0c;選時間&#xff0c;Process status選Y。 找到這條&#xff0c;雙擊&#xff0c;發現是active的狀態。可能是因為前后…

springboot城市菜園共享系統-計算機畢業設計源碼00524

目 錄 摘要 1 緒論 1.1 研究背景與意義 1.2 國內外研究現狀和發展趨勢 1.3論文結構與章節安排 2 城市菜園共享系統系統分析 2.1 可行性分析 2.2 系統流程分析 2.2.1 數據增加流程 2.2.2 數據修改流程 2.2.3 數據刪除流程 2.3 系統功能分析 2.3.1 功能性分析 2.3.…