全網(wǎng)最新springboot整合mybatis-plus的過程
一,簡介
1. 什么是mybatis-plus
MyBatis-Plus(簡稱MP)是一個MyBatis的增強工具,旨在在MyBatis的基礎(chǔ)上只做增強不做改變,以簡化開發(fā)、提高效率。MyBatis-Plus保持了MyBatis原有的所有特性,同時增加了一些實用的功能,使得開發(fā)者能夠更加便捷地進行數(shù)據(jù)庫操作。以下是MyBatis-Plus的一些主要特點和功能:
2.mybatis-plus特點
- 無侵入:引入MyBatis-Plus不會對現(xiàn)有的MyBatis工程產(chǎn)生影響,可以無縫集成到現(xiàn)有的項目中。
- 損耗?。簡訒r自動注入基本的CRUD操作,幾乎不消耗額外的性能,可以直接面向?qū)ο蟛僮鲾?shù)據(jù)庫。
- 強大的CRUD操作:內(nèi)置通用Mapper、通用Service,通過少量配置即可實現(xiàn)單表的大部分CRUD操作。同時,MyBatis-Plus提供了強大的條件構(gòu)造器,滿足復(fù)雜的查詢需求。
- 支持Lambda形式調(diào)用:利用Lambda表達式方便地編寫查詢條件,避免了字段名稱錯誤的問題。
- 支持主鍵自動生成:提供了多種主鍵生成策略,包括分布式唯一ID生成器,解決了主鍵問題。
- 支持ActiveRecord模式:通過繼承特定的基類,可以像操作對象一樣操作數(shù)據(jù)庫。
- 支持自定義全局通用操作:允許開發(fā)者注入自己的通用方法。
- 內(nèi)置分頁插件:基于MyBatis的物理分頁,開發(fā)者可以輕松實現(xiàn)分頁查詢。
- 支持多種數(shù)據(jù)庫:兼容MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、PostgreSQL、SQL Server等多種數(shù)據(jù)庫。
- 內(nèi)置性能分析插件:可以輸出SQL語句及其執(zhí)行時間,有助于快速定位慢查詢。
- 內(nèi)置全局?jǐn)r截插件:提供全表刪除、更新操作的智能分析阻斷,防止誤操作。
二,搭建基本環(huán)境
1. 導(dǎo)入基本依賴:
<!--mybatis-plus依賴--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.7</version> </dependency> <!--mysql連接依賴--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <!--連接池依賴--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.18</version> </dependency>
2. 編寫配置文件
spring: data: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mybatis_study?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root type: com.alibaba.druid.pool.DruidDataSource
3. 創(chuàng)建實體類
package org.example.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.util.Date; @TableName("student") public class Student { @TableId(type = IdType.AUTO) private int id; private String studentNumber; private String name; private int gender; // 0 表示女性,1 表示男性 private Date dateOfBirth; // Getters and Setters }
4. 編寫controller層
package org.example.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/students") public class StudentController { }
5. 編寫service接口
package org.example.service; import com.baomidou.mybatisplus.extension.service.IService; import org.example.pojo.Student; public interface StudentService extends IService<Student> { }
6. 編寫service層
package org.example.service.serviceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.example.mapper.StudentMapper; import org.example.pojo.Student; import org.example.service.StudentService; import org.springframework.stereotype.Service; @Service public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService { }
7. 編寫mapper層
package org.example.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.example.pojo.Student; @Mapper public interface StudentMapper extends BaseMapper<Student> { }
三,基本知識介紹
1. 基本注解 @TableName
主要用于指定表名,實現(xiàn)實體類與表名的綁定,作用于類上,適用于表名與實體類名稱不統(tǒng)一的情況,統(tǒng)一的情況可以不用寫。
import com.baomidou.mybatisplus.annotation.TableName; //此處表名稱為t_user,實體類名稱為User不統(tǒng)一 @TableName("t_user") public class User { private Long id; private String name; private Integer age; private String email; // Getters and Setters }
如果所有的表結(jié)構(gòu)與實體類只是多了一個前綴,可以直接在配置文件里面配置全局的前綴,就可以不使用注解了,兩種方式都可以,根據(jù)具體場景選擇,配置如下:
mybatis-plus: global-config: db-config: table-prefix: t_
@TableId
作用于主鍵上,指明主鍵字段,并設(shè)置主鍵的生成方式。
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; @TableName("user_info") // 指定該實體類對應(yīng)的數(shù)據(jù)表名 public class UserInfo { //此處value也可以作用于映射,當(dāng)實體類中 //的id字段名和數(shù)據(jù)庫中的字段名不相同時,可以使用其屬性做增強 @TableId(value = "id", type = IdType.AUTO) // 標(biāo)記為主鍵,并指定主鍵生成策略為自增 private Long id; private String username; private String password; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
注解屬性:
value:指定表中主鍵字段,多用于主鍵字段和實體類字段不同意
type:id生成策略
對于IdType做出如下說明:
屬性 | 說明 | 適用場景 |
---|---|---|
AUTO | 數(shù)據(jù)庫自增主鍵 | 適用于 MySQL、SQL Server 等支持自增主鍵的數(shù)據(jù)庫 |
NONE | 不使用任何主鍵生成策略 | 通常用于主鍵已經(jīng)存在的情況 |
ASSIGN_ID | 全局唯一ID(默認基于Snowflake算法生成) | 適用于分布式系統(tǒng),確保全局唯一性 |
ASSIGN_UUID | 全局唯一UUID,生成32位的字符串 | 適用于需要字符串主鍵的場景 |
INPUT | 自定義輸入主鍵值 | 適用于某些特殊場景,如導(dǎo)入數(shù)據(jù)時需要手動指定主鍵 |
改注解作用眾多,多用于表字段和實體類字段名稱不統(tǒng)一,做映射處理,也可用于零時字段,不存入數(shù)據(jù)庫,或者是一些字段的填充處理(此處需要編寫填充處理器)。
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import java.util.Date; @TableName("user_info") public class UserInfo { @TableId(value = "id", type = IdType.AUTO) private Long id; @TableField("username") private String username; //此字段不參與查詢 @TableField("password", select=false ) private String password; @TableField("email") private String email; //注意,此處應(yīng)該編寫相應(yīng)的填充邏輯 @TableField(value = "create_time", fill = FieldFill.INSERT) private Date createTime; @TableField(value = "update_time", fill = FieldFill.UPDATE) private Date updateTime; @TableField(exist = false) private String tempField; // 臨時字段,不在數(shù)據(jù)庫中 // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getTempField() { return tempField; } public void setTempField(String tempField) { this.tempField = tempField; } }
屬性說明:
value:同上面注解一樣,用于字段綁定,單個屬性的時候可以不寫
select:在值為false的情況下用于設(shè)置不參查詢,查詢之后不會返回回來
exist :用于類中的零時變量,數(shù)據(jù)庫中沒有該字段,只在java中使用
fill:用于自動填充,比如create_time,update_time這一類,但需要編寫相應(yīng)的處理器
對應(yīng)處理器代碼:
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); this.strictInsertFill(metaObject, "updateTime", Date.class, new Date()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); } }
@TableLogic
該字段用于指定邏輯刪除的字段,當(dāng)執(zhí)行刪除語句時,做更新操作,只改變當(dāng)前字段的值,設(shè)置為刪除狀態(tài),數(shù)據(jù)不做真實處理,查詢時也只查詢狀態(tài)為未刪除的數(shù)據(jù)(此過程不需要手動實現(xiàn),mybatis-plus已經(jīng)幫忙實現(xiàn)了,我們只需要添加字段,設(shè)置相應(yīng)的狀態(tài)值)注:該字段也需要加入到對應(yīng)的表里
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; @TableName("user_info") public class UserInfo { @TableId(value = "id", type = IdType.AUTO) private Long id; private String username; private String password; private String email; @TableLogic private Integer isDeleted; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getIsDeleted() { return isDeleted; } public void setIsDeleted(Integer isDeleted) { this.isDeleted = isDeleted; } }
在配置文件中添加如下配置:
mybatis-plus: global-config: db-config: # 邏輯刪除字段名 logic-delete-field: deleted # 邏輯刪除字面值:未刪除為0 logic-not-delete-value: 0 # 邏輯刪除字面值:刪除為1 logic-delete-value: 1
@Version
用于配置樂觀鎖字段,配置之后的更新操作都會先去比較版本,然后在去操作,整體采用cas機制實現(xiàn)。注:該字段也需要加入到對應(yīng)的表里
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.Version; @TableName("order_info") public class OrderInfo { @TableId(value = "id", type = IdType.AUTO) private Long id; private String orderNo; private Double amount; @Version private Integer version; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getOrderNo() { return orderNo; } public void setOrderNo(String orderNo) { this.orderNo = orderNo; } public Double getAmount() { return amount; } public void setAmount(Double amount) { this.amount = amount; } public Integer getVersion() { return version; } public void setVersion(Integer version) { this.version = version; } }
此處需加相關(guān)的攔截器:
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }
樂觀鎖的作用:
樂觀鎖假設(shè)在并發(fā)環(huán)境中沖突較少,因此在操作數(shù)據(jù)時不立即獲取鎖,而是等到提交更新時才檢查是否有其他事務(wù)修改過數(shù)據(jù)。如果發(fā)現(xiàn)數(shù)據(jù)已被修改,則更新失敗,通常會拋出異常。
特點:在提交更新時檢查版本號,如果版本號匹配則更新成功,否則更新失敗。
效果:多個事務(wù)可以同時讀取和處理數(shù)據(jù),但在提交更新時會檢查版本號,確保數(shù)據(jù)的一致性。
@Transient
作用于實體類字段,使其不參與數(shù)據(jù)庫的操作,其中包括(Insert,Update,Select),@TableField(exist=false)作用相同,充當(dāng)零時變量。
@TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; @Transient private String tempField; // getters and setters }
2. Wrapper的介紹*
概念:MyBatisPlus提供了QueryWrapper、LambdaQueryWrapper、UpdateWrapper和LambdaUpdateWrapper等條件類,大大簡化了我們的開發(fā),可以使代碼更加清晰和易于管理,其中包括多條件查詢、排序、條件優(yōu)先級以及有條件時才加入條件的場景,并提供了示例代碼展示如何進行數(shù)據(jù)庫查詢和更新操作。
大致的條件(此處粗略列舉):
方法 | 描述 |
---|---|
eq | 等于 |
ne | 不等于 |
gt | 大于 |
ge | 大于等于 |
lt | 小于 |
le | 小于等于 |
like | 模糊查詢 |
notLike | 反向模糊查詢 |
in | 在某集合內(nèi) |
notIn | 不在某集合內(nèi) |
isNull | 為空 |
isNotNull | 不為空 |
between | 在某個區(qū)間內(nèi) |
notBetween | 不在某個區(qū)間內(nèi) |
set | 設(shè)置字段值 |
QueryWrapper
作用于查詢設(shè)置查詢條件。
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public List<User> getUsersByConditions() { // 創(chuàng)建 QueryWrapper 對象 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); // 添加查詢條件 queryWrapper.eq("name", "張三") .ge("age", 18) .orderByDesc("create_time"); // 執(zhí)行查詢 return userMapper.selectList(queryWrapper); } }
此處執(zhí)行的sql語句:
SELECT * FROM user WHERE name = '張三' AND age >= 18 ORDER BY create_time DESC;
UpdateWrapper
作用于更新設(shè)置條件。
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public int updateUserById() { // 創(chuàng)建 UpdateWrapper 對象 UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); // 添加更新條件 updateWrapper.eq("id", 1); // 創(chuàng)建要更新的對象 User user = new User(); user.setName("李四"); // 執(zhí)行更新 return userMapper.update(user, updateWrapper); } }
此處執(zhí)行的sql語句:
UPDATE user SET name = '李四' WHERE id = 1;
LambdaQueryWrapper
在QueryWrapper做了增強,作用一樣,用于設(shè)置查詢條件。
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public List<User> getUsersByLambdaConditions() { // 創(chuàng)建 LambdaQueryWrapper 對象 LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); // 添加查詢條件 lambdaQueryWrapper.eq(User::getName, "張三") .ge(User::getAge, 18) .orderByDesc(User::getCreateTime); // 執(zhí)行查詢 return userMapper.selectList(lambdaQueryWrapper); } }
此處執(zhí)行的sql語句:
SELECT * FROM user WHERE name = '張三' AND age >= 18 ORDER BY create_time DESC;
LambdaUpdateWrapper
在UpdateWrapper做了增強,作用一樣,用于設(shè)置跟新條件。
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public int updateUserByIdWithLambda() { // 創(chuàng)建 LambdaUpdateWrapper 對象 LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>(); // 添加更新條件 lambdaUpdateWrapper.eq(User::getId, 1); // 創(chuàng)建要更新的對象 User user = new User(); user.setName("李四"); // 執(zhí)行更新 return userMapper.update(user, lambdaUpdateWrapper); } }
此處執(zhí)行的sql語句:
UPDATE user SET name = '李四' WHERE id = 1;
Wrappers
用于更簡便的條件設(shè)置
import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public List<User> getUsersByConditionsUsingWrappers() { // 創(chuàng)建 QueryWrapper 對象 QueryWrapper<User> queryWrapper = Wrappers.<User>query() .eq("name", "張三") .ge("age", 18) .orderByDesc("create_time"); // 執(zhí)行查詢 return userMapper.selectList(queryWrapper); } }
此處執(zhí)行的sql語句:
SELECT * FROM user WHERE name = '張三' AND age >= 18 ORDER BY create_time DESC;
3. 分頁查詢
1. 配置相應(yīng)的攔截器
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
2. 實現(xiàn)分頁邏輯
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.entity.User; import com.example.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private UserMapper userMapper; public IPage<User> getUserPage(int current, int size) { // 創(chuàng)建 Page 對象,傳入當(dāng)前頁碼和每頁大小 Page<User> page = new Page<>(current, size); // 創(chuàng)建 QueryWrapper 對象,添加查詢條件 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("status", 1) .orderByDesc("create_time"); // 執(zhí)行分頁查詢 IPage<User> userPage = userMapper.selectPage(page, queryWrapper); // 獲取分頁數(shù)據(jù) List<User> users = userPage.getRecords(); // 獲取總記錄數(shù) long total = userPage.getTotal(); // 獲取當(dāng)前頁碼 int current = userPage.getCurrent(); // 獲取每頁大小 int size = userPage.getSize(); // 獲取總頁數(shù) int pages = userPage.getPages(); return userPage; } }
執(zhí)行對應(yīng)的sql語句是:
-- 分頁查詢 SELECT * FROM user WHERE status = 1 ORDER BY create_time DESC LIMIT 0, 10; -- 當(dāng)前頁碼為1,每頁大小為10
四,結(jié)語
在本文中,我們詳細介紹了 MyBatis-Plus 的核心功能和使用方法,包括如何配置分頁插件、編寫分頁查詢代碼、使用各種 Wrapper 構(gòu)建復(fù)雜查詢條件等。通過這些內(nèi)容,相信你已經(jīng)對 MyBatis-Plus 有了更深入的了解,并能夠在實際項目中靈活應(yīng)用這些功能。
MyBatis-Plus 作為一個強大的 MyBatis 增強工具,不僅簡化了數(shù)據(jù)訪問層的開發(fā)工作,還提供了許多便捷的功能,如分頁查詢、鏈?zhǔn)骄幊獭酚^鎖等。它能夠顯著提升開發(fā)效率,減少重復(fù)代碼,使你的項目更加簡潔和高效。
如果你在閱讀本文后對 MyBatis-Plus 感興趣,不妨在自己的項目中嘗試一下。實踐是最好的老師,通過實際操作,你會更加深刻地理解這些功能的奧妙。同時,也歡迎你在評論區(qū)分享你的使用經(jīng)驗和遇到的問題,我們一起探討和解決。
最后,感謝你花時間閱讀本文,希望本文能為你帶來幫助。如果你覺得本文對你有幫助,別忘了點贊和分享,讓更多的人受益。讓我們一起在技術(shù)的道路上不斷前行,共同成長!
- SpringBoot整合Mybatis-plus實現(xiàn)多級評論功能
- SpringBoot3整合mybatis-plus的實現(xiàn)
- Springboot3整合Mybatis-plus3.5.3報錯問題解決
- SpringBoot整合mybatis-plus實現(xiàn)分頁查詢功能
- springboot3.2整合mybatis-plus詳細代碼示例
- SpringBoot3和mybatis-plus整合出現(xiàn)的問題解決辦法
- SpringBoot3.2.2整合MyBatis-Plus3.5.5依賴不兼容的問題解決
- SpringBoot整合Mybatis-Plus實現(xiàn)關(guān)聯(lián)查詢
- SpringBoot3.3.X整合Mybatis-Plus的實現(xiàn)示例
相關(guān)文章
淺談三分鐘學(xué)習(xí)Java泛型中T、E、K、V、?的含義
這篇文章主要介紹了淺談三分鐘學(xué)習(xí)Java泛型中T、E、K、V、?的含義,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12IDEA MyBatis Plugins自動生成實體類和mapper.xml
這篇文章主要介紹了IDEA MyBatis Plugins自動生成實體類和mapper.xml,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07java實現(xiàn)Excel的導(dǎo)入導(dǎo)出
這篇文章主要為大家詳細介紹了java實現(xiàn)Excel的導(dǎo)入導(dǎo)出,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-06-06Mybatis?Web中的數(shù)據(jù)庫操作方法舉例詳解
Mybatis是一款優(yōu)秀的持久化框架,用于簡化JDBC的開發(fā),下面這篇文章主要給大家介紹了關(guān)于Mybatis?Web中數(shù)據(jù)庫操作方法的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-09-09