Java技术:Mybatis-plus常用API全套教程,值得收藏!
前言
官網(wǎng):
https://baomidou.com/
創(chuàng)建數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)名為mybatis_plus
創(chuàng)建表
創(chuàng)建user表
DROP?TABLE?IF?EXISTS?user; CREATE?TABLE?user ( id?BIGINT(20)?NOT?NULL?COMMENT?'主鍵ID', name?VARCHAR(30)?NULL?DEFAULT?NULL?COMMENT?'姓名', age?INT(11)?NULL?DEFAULT?NULL?COMMENT?'年齡', email?VARCHAR(50)?NULL?DEFAULT?NULL?COMMENT?'郵箱', PRIMARY?KEY?(id) ); INSERT?INTO?user?(id,?name,?age,?email)?VALUES (1,?'Jone',?18,?'test1@baomidou.com'), (2,?'Jack',?20,?'test2@baomidou.com'), (3,?'Tom',?28,?'test3@baomidou.com'), (4,?'Sandy',?21,?'test4@baomidou.com'), (5,?'Billie',?24,?'test5@baomidou.com');注意:-- 真實(shí)開(kāi)發(fā)中往往都會(huì)有這四個(gè)字段,version(樂(lè)觀鎖)、deleted(邏輯刪除)、gmt_create(創(chuàng)建時(shí)間)、gmt_modified(修改時(shí)間)
初始化項(xiàng)目
使用SpringBoot器?初始化!
導(dǎo)入依賴
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> </dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId> </dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.5</version> </dependency>注意:盡量不要同時(shí)導(dǎo)入 mybatis 和 mybatis-plus!避免版本的差異造成無(wú)法預(yù)知的問(wèn)題。
連接數(shù)據(jù)庫(kù)
創(chuàng)建application.yml
spring:profiles:active:?devdatasource: #?驅(qū)動(dòng)不同?mysql?5??com.mysql.jdbc.Driver #?????????mysql?8??com.mysql.cj.jdbc.Driver、需要增加時(shí)區(qū)的配置serverTimezone=GMT%2B8url:?jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8driver-class-name:?com.mysql.cj.jdbc.Driverusername:?rootpassword:?root業(yè)務(wù)代碼
實(shí)體類
@Data @AllArgsConstructor @NoArgsConstructor public?class?User?{private?Long?id;private?String?name;private?Integer?age;private?String?email; }?mapper接口
import?com.baomidou.mybatisplus.core.mapper.BaseMapper; import?com.kuang.pojo.User; import?org.springframework.stereotype.Repository; //?在對(duì)應(yīng)的Mapper上面繼承基本的類?BaseMapper @Repository?//?代表持久層 public?interface?UserMapper?extends?BaseMapper<User>?{//?所有的CRUD操作都已經(jīng)編寫完成了 }注意點(diǎn),我們需要在主啟動(dòng)類上去掃描我們的mapper包下的所有接口 @MapperScan(“com.kwhua.mapper”)
測(cè)試
@SpringBootTest class?MybatisPlusApplicationTests?{//?繼承了BaseMapper,所有的方法都來(lái)自己父類//?我們也可以編寫自己的擴(kuò)展方法!@Autowiredprivate?UserMapper?userMapper;@Testvoid?contextLoads()?{//?參數(shù)是一個(gè) Wrapper ,條件構(gòu)造器,這里我們先設(shè)置條件為空,查詢所有。List<User>?users?=?userMapper.selectList(null);users.forEach(System.out::println);} }?所有數(shù)據(jù)輸出
配置日志
我們所有的sql現(xiàn)在是不可見(jiàn)的,我們希望知道它是怎么執(zhí)行的,所有我們要配置日志的輸出 application.yml文件添加日志配置
#配置日志 mybatis-plus:configuration:log-impl:?org.apache.ibatis.logging.stdout.StdOutImpl查看執(zhí)行sql的日志信息
Mybatis-plus的CRUD
插入操作
//?測(cè)試插入@Testpublic?void?testInsert(){User?user?=?new?User();user.setName("kwhua_mybatis-plus_insertTest");user.setAge(15);user.setEmail("310697723@qq.com");int?result?=?userMapper.insert(user);?//?幫我們自動(dòng)生成idSystem.out.println(result);?//?受影響的行數(shù)System.out.println(user);?//?看到id會(huì)自動(dòng)填充。????}??看到id會(huì)自動(dòng)填充。數(shù)據(jù)庫(kù)插入的id的默認(rèn)值為:全局的唯一id
主鍵生成策略
1)主鍵自增 1、實(shí)體類字段上 @TableId(type = IdType.AUTO)
2、數(shù)據(jù)庫(kù)id字段設(shè)置為自增!
3、再次測(cè)試(可以看到id值比上次插入的大1)id的生成策略源碼解釋
public?enum?IdType?{AUTO(0),?//?數(shù)據(jù)庫(kù)id自增NONE(1),?//?未設(shè)置主鍵INPUT(2),?//?手動(dòng)輸入ID_WORKER(3),?//?默認(rèn)的方式,全局唯一idUUID(4),?//?全局唯一id?uuidID_WORKER_STR(5);?//ID_WORKER?字符串表示法 }以上不再逐一測(cè)試。
更新操作
?@Testpublic?void?testUpdate(){User?user?=?new?User();//?通過(guò)條件自動(dòng)拼接動(dòng)態(tài)sqluser.setId(1302223874217295874L);user.setName("kwhua_mybatis-plus_updateTest");user.setAge(20);//?注意:updateById 但是參數(shù)是一個(gè)對(duì)象!int?i?=?userMapper.updateById(user);System.out.println(i);} 圖片自動(dòng)填充
創(chuàng)建時(shí)間、修改時(shí)間!這兩個(gè)字段操作都是自動(dòng)化完成的,我們不希望手動(dòng)更新!阿里巴巴開(kāi)發(fā)手冊(cè):所有的數(shù)據(jù)庫(kù)表都要配置上gmt_create、gmt_modified!而且需要自動(dòng)化!
方式一:數(shù)據(jù)庫(kù)級(jí)別(工作中一般不用)
1、在表中新增字段 gmt_create, gmt_modified
2、把實(shí)體類同步
private?Date?gmtCreate; private?Date?gmtModified;3、再次查看
方式二:代碼級(jí)別 1、刪除數(shù)據(jù)庫(kù)的默認(rèn)值、更新操作!
2、實(shí)體類字段屬性上需要增加注解
????//?字段添加填充內(nèi)容@TableField(fill?=?FieldFill.INSERT)private?Date?gmt_create;@TableField(fill?=?FieldFill.INSERT_UPDATE)private?Date?gmt_modified;3、編寫處理器來(lái)處理這個(gè)注解即可!
@Slf4j @Component?//?一定不要忘記把處理器加到IOC容器中! public?class?MyMetaObjectHandler?implements?MetaObjectHandler?{//?插入時(shí)的填充策略@Overridepublic?void?insertFill(MetaObject?metaObject)?{log.info("start?insert?fill.....");//?setFieldValByName(String?fieldName,?Object?fieldVal,?MetaObject?metaObjectthis.setFieldValByName("gmt_create",new?Date(),metaObject);this.setFieldValByName("gmt_modified",new?Date(),metaObject);}//?更新時(shí)的填充策略@Overridepublic?void?updateFill(MetaObject?metaObject)?{log.info("start?update?fill.....");this.setFieldValByName("gmt_modified",new?Date(),metaObject);} }4、測(cè)試插入和更新,檢查時(shí)間變化。
樂(lè)觀鎖
樂(lè)觀鎖 : 顧名思義,十分樂(lè)觀,它總是認(rèn)為不會(huì)出現(xiàn)問(wèn)題,無(wú)論干什么不去上鎖!如果出現(xiàn)了問(wèn)題, 再次更新值測(cè)試 悲觀鎖:顧名思義,十分悲觀,它總是認(rèn)為總是出現(xiàn)問(wèn)題,無(wú)論干什么都會(huì)上鎖!再去操作!
樂(lè)觀鎖實(shí)現(xiàn)方式:
取出記錄時(shí),獲取當(dāng)前version 更新時(shí),帶上這個(gè)version 執(zhí)行更新時(shí), set version = newVersion where version = oldVersion 如果version不對(duì),就更新失敗
樂(lè)觀鎖:1、先查詢,獲得版本號(hào) version = 1
--?A update?user?set?name?=?"kwhua",?version?=?version?+?1 where?id?=?2?and?version?=?1 -- B 線程搶先完成,這個(gè)時(shí)候 version = 2,會(huì)導(dǎo)致 A 修改失敗! update?user?set?name?=?"kwhua",?version?=?version?+?1 where?id?=?2?and?version?=?1樂(lè)觀鎖測(cè)試
1、給數(shù)據(jù)庫(kù)中增加version字段!
2、實(shí)體類加對(duì)應(yīng)的字段
????@Version?//樂(lè)觀鎖Version注解private?Integer?version;3、注冊(cè)組件
//?掃描我們的?mapper?文件夾 @MapperScan("com.kwhua.mapper") @EnableTransactionManagement @Configuration?//?配置類 public?class?MyBatisPlusConfig?{//?注冊(cè)樂(lè)觀鎖插件@Beanpublic?OptimisticLockerInterceptor?optimisticLockerInterceptor()?{return?new?OptimisticLockerInterceptor();}}4、測(cè)試
//?測(cè)試樂(lè)觀鎖成功!@Testpublic?void?testOptimisticLocker(){//?1、查詢用戶信息User?user?=?userMapper.selectById(1L);//?2、修改用戶信息user.setName("kwhua");user.setEmail("123456@qq.com");//?3、執(zhí)行更新操作userMapper.updateById(user);}version字段已經(jīng)由1變成了2
//?測(cè)試樂(lè)觀鎖失敗!多線程下@Testpublic?void?testOptimisticLocker2(){//?線程?1User?user?=?userMapper.selectById(1L);user.setName("kwhua111");user.setEmail("123456@qq.com");//?模擬另外一個(gè)線程執(zhí)行了插隊(duì)操作User?user2?=?userMapper.selectById(1L);user2.setName("kwhua222");user2.setEmail("123456@qq.com");userMapper.updateById(user2);//?自旋鎖來(lái)多次嘗試提交!userMapper.updateById(user);?//?如果沒(méi)有樂(lè)觀鎖就會(huì)覆蓋插隊(duì)線程的值!}可以看到線程1執(zhí)行更新失敗
查詢操作
//?測(cè)試查詢@Testpublic?void?testSelectById(){User?user?=?userMapper.selectById(1L);System.out.println(user);}//?測(cè)試批量查詢!@Testpublic?void?testSelectByBatchId(){List<User>?users?=?userMapper.selectBatchIds(Arrays.asList(1,?2,?3));users.forEach(System.out::println);}//?按條件查詢之一使用map操作@Testpublic?void?testSelectByBatchIds(){HashMap<String,?Object>?map?=?new?HashMap<>();//?自定義要查詢map.put("name","kwhua");map.put("age",15);List<User>?users?=?userMapper.selectByMap(map);users.forEach(System.out::println);}1、配置攔截器組件
//?分頁(yè)插件 @Bean public?PaginationInterceptor?paginationInterceptor()?{return??new?PaginationInterceptor(); }2、直接使用Page對(duì)象即可!
//?測(cè)試分頁(yè)查詢 @Test public?void?testPage(){//?參數(shù)一:當(dāng)前頁(yè)//?參數(shù)二:頁(yè)面大小Page<User>?page?=?new?Page<>(2,5);userMapper.selectPage(page,null);page.getRecords().forEach(System.out::println);System.out.println(page.getTotal()); }物理刪除
//?測(cè)試刪除@Testpublic?void?testDeleteById(){userMapper.deleteById(1L);}//?通過(guò)id批量刪除@Testpublic?void?testDeleteBatchId(){userMapper.deleteBatchIds(Arrays.asList(2L,3L));}//?通過(guò)map刪除@Testpublic?void?testDeleteMap(){HashMap<String,?Object>?map?=?new?HashMap<>();map.put("name","kwhua");userMapper.deleteByMap(map);}邏輯刪除
物理刪除 :從數(shù)據(jù)庫(kù)中直接移除 邏輯刪除 :在數(shù)據(jù)庫(kù)中沒(méi)有被移除,而是通過(guò)一個(gè)變量來(lái)讓它失效!
deleted = 0 => deleted = 1 管理員可以查看被刪除的記錄!防止數(shù)據(jù)的丟失,類似于回收站!
1、在數(shù)據(jù)表中增加一個(gè) deleted 字段
2、實(shí)體類中增加屬性
?@TableLogic?//邏輯刪除private?Integer?deleted;3、配置
//?邏輯刪除組件!@Beanpublic?ISqlInjector?sqlInjector()?{return?new?LogicSqlInjector();}配置文件配置
?global-config:db-config:logic-delete-value:?1logic-not-delete-value:?04、測(cè)試 測(cè)試刪除
字段值也從0修改成了1測(cè)試查詢
圖片性能分析插件
作用:性能分析攔截器,用于輸出每條 SQL 語(yǔ)句及其執(zhí)行時(shí)間 MP也提供性能分析插件,如果超過(guò)這個(gè)時(shí)間就停止運(yùn)行!
1、導(dǎo)入插件
???/***?SQL執(zhí)行效率插件*/@Bean@Profile({"dev","test"})//?設(shè)置?dev?test?環(huán)境開(kāi)啟,保證我們的效率public?PerformanceInterceptor?performanceInterceptor()?{PerformanceInterceptor?performanceInterceptor?=?new?PerformanceInterceptor();performanceInterceptor.setMaxTime(100);?//ms?設(shè)置sql執(zhí)行的最大時(shí)間,如果超過(guò)了則不執(zhí)行performanceInterceptor.setFormat(true);return?performanceInterceptor;}圖片條件構(gòu)造器(Wrapper)
isNotNull .gt
@Testvoid?contextLoads()?{//?查詢name不為空的用戶,并且郵箱不為空的用戶,年齡大于等于12QueryWrapper<User>?wrapper?=?new?QueryWrapper<>();wrapper.isNotNull("name")?//不為空.isNotNull("email").ge("age",18);userMapper.selectList(wrapper).forEach(System.out::println);?//?和我們剛才學(xué)習(xí)的map對(duì)比一下} 圖片.eq
?@Testvoid?test2(){//?查詢名字kwhuaQueryWrapper<User>?wrapper?=?new?QueryWrapper<>();wrapper.eq("name","kwhua");User?user?=?userMapper.selectOne(wrapper);?//?查詢一個(gè)數(shù)據(jù)用selectOne,查詢多個(gè)結(jié)果使用List?或者?MapSystem.out.println(user);}其他方法可以自己測(cè)試...
代碼自動(dòng)生成器
//?代碼自動(dòng)生成器 public?class?generateCode?{public?static?void?main(String[]?args)?{//?需要構(gòu)建一個(gè)?代碼自動(dòng)生成器?對(duì)象AutoGenerator?mpg?=?new?AutoGenerator();//?配置策略//?1、全局配置GlobalConfig?gc?=?new?GlobalConfig();String?projectPath?=?System.getProperty("user.dir");gc.setOutputDir(projectPath+"/src/main/java");gc.setAuthor("kwhua");//作者名稱gc.setOpen(false);gc.setFileOverride(false);?//?是否覆蓋gc.setIdType(IdType.ID_WORKER);gc.setDateType(DateType.ONLY_DATE);gc.setSwagger2(true);//實(shí)體屬性?Swagger2?注解//?自定義文件命名,注意?%s 會(huì)自動(dòng)填充表實(shí)體屬性!gc.setServiceName("%sService");?gc.setControllerName("%sController");gc.setServiceName("%sService");gc.setServiceImplName("%sServiceImpl");gc.setMapperName("%sMapper");gc.setXmlName("%sMapper");mpg.setGlobalConfig(gc);//2、設(shè)置數(shù)據(jù)源DataSourceConfig?dsc?=?new?DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/kwhua_test? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");dsc.setDriverName("com.mysql.cj.jdbc.Driver");//?dsc.setDriverName("com.mysql.jdbc.Driver");?//mysql5.6以下的驅(qū)動(dòng)dsc.setUsername("root");dsc.setPassword("root");dsc.setDbType(DbType.MYSQL);mpg.setDataSource(dsc);//3、包的配置PackageConfig?pc?=?new?PackageConfig();pc.setParent("com.kwhua");?//包名pc.setModuleName("model");?//模塊名pc.setEntity("entity");pc.setMapper("mapper");pc.setService("service");pc.setController("controller");mpg.setPackageInfo(pc);//4、策略配置StrategyConfig?strategy?=?new?StrategyConfig();strategy.setInclude("user","course");?//?設(shè)置要映射的表名strategy.setNaming(NamingStrategy.underline_to_camel);strategy.setColumnNaming(NamingStrategy.underline_to_camel);strategy.setEntityLombokModel(true);?//?自動(dòng)lombok;strategy.setLogicDeleteFieldName("deleted");//?自動(dòng)填充配置TableFill?gmtCreate?=?new?TableFill("gmt_create",?FieldFill.INSERT);TableFill?gmtModified?=?new?TableFill("gmt_modified",FieldFill.INSERT_UPDATE);ArrayList<TableFill>?tableFills?=?new?ArrayList<>();tableFills.add(gmtCreate);tableFills.add(gmtModified);strategy.setTableFillList(tableFills);//?樂(lè)觀鎖strategy.setVersionFieldName("version");//根據(jù)你的表名來(lái)建對(duì)應(yīng)的類名,如果你的表名沒(méi)有下劃線,比如test,那么你就可以取消這一步strategy.setTablePrefix("t_");strategy.setRestControllerStyle(true);?//rest請(qǐng)求//自動(dòng)轉(zhuǎn)下劃線,比如localhost:8080/hello_id_2strategy.setControllerMappingHyphenStyle(true);?mpg.setStrategy(strategy);mpg.execute();?//執(zhí)行} }執(zhí)行主方法即可生成對(duì)應(yīng)代碼
IT技術(shù)分享社區(qū)
個(gè)人博客網(wǎng)站:https://programmerblog.xyz
文章推薦程序員效率:畫流程圖常用的工具程序員效率:整理常用的在線筆記軟件遠(yuǎn)程辦公:常用的遠(yuǎn)程協(xié)助軟件,你都知道嗎?51單片機(jī)程序下載、ISP及串口基礎(chǔ)知識(shí)硬件:斷路器、接觸器、繼電器基礎(chǔ)知識(shí)
總結(jié)
以上是生活随笔為你收集整理的Java技术:Mybatis-plus常用API全套教程,值得收藏!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 上海电信光猫设置虚拟服务器,你们想要的上
- 下一篇: java美元兑换,(Java实现) 美元