Java的MybatisPlus詳解
SpringBoot+MP工程搭建
一、yml內(nèi)容
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.yx.zg</groupId> <artifactId>SpringBoot-MybatisPlus</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- mybatis plus 代碼生成器 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
二、建表sql語(yǔ)句
CREATE TABLE `tb_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID', `user_name` varchar(20) NOT NULL COMMENT '用戶名', `password` varchar(20) NOT NULL COMMENT '密碼', `name` varchar(30) DEFAULT NULL COMMENT '姓名', `age` int(11) DEFAULT NULL COMMENT '年齡', `email` varchar(50) DEFAULT NULL COMMENT '郵箱', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; INSERT INTO `tb_user` VALUES (1, 'zhangsan2', '123456', '張三', 20, 'test@itcast.cn'); INSERT INTO `tb_user` VALUES (2, 'lisi', '123456', '李四', 20, 'test2@itcast.cn'); INSERT INTO `tb_user` VALUES (3, 'wangwu', '123456', '王五', 28, 'test3@itcast.cn'); INSERT INTO `tb_user` VALUES (4, 'zhaoliu', '123456', '趙六', 21, 'test4@itcast.cn'); INSERT INTO `tb_user` VALUES (5, 'sunqi', '123456', '孫七', 24, 'test5@itcast.cn');
三、User實(shí)體
@Data @NoArgsConstructor @AllArgsConstructor /** * 指定該實(shí)體對(duì)應(yīng)的表名,如果不使用@TableName注解, * 表名稱默認(rèn)是類名,首字母小寫 */ @TableName("tb_user") public class User { private Long id; private String userName; private String password; private String name; private Integer age; private String email; }
四、Mapper接口
public interface UserMapper extends BaseMapper<User> { }
五、SpringBoot主啟動(dòng)類MybatisPlusApplication
@MapperScan("cn.yx.zg.mapper") @SpringBootApplication public class MybatisPlusApplication { public static void main(String[] args) { // 啟動(dòng)spring 應(yīng)用 SpringApplication.run(MybatisPlusApplication.class, args); } }
通過以上代碼,咱們就搭建了一個(gè)SpringBoot+MP的環(huán)境。
六、測(cè)試類
@RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class UserMapperTest { @Autowired private UserMapper userMapper; /** * 查詢 */ @Test public void testSelect() { List<User> userList = userMapper.selectList(null); for (User user : userList) { log.info(user.toString()); } } /** * 新增 */ @Test public void testInsert() { User user = new User(); user.setAge(20); user.setEmail("test@itcast.cn"); user.setName("曹操"); user.setUserName("caocao"); user.setPassword("123456"); int result = userMapper.insert(user); //返回的result是受影響的行數(shù),并不是自增 后的id log.info("result = " + result); log.info("插入后的自增ID自動(dòng)回填到對(duì)象中:{}", user.getId()); } @Test public void testUpdate() { User user = new User(); user.setAge(20); user.setEmail("test@itcast.cn"); user.setName("張三"); user.setUserName("zhangsan2"); user.setPassword("123456"); user.setId(1L); int result = userMapper.updateById(user); //返回的result是受影響的行數(shù),并不是自增 后的id log.info("result = " + result); } }
MP中的一些注解、屬性
主鍵策略
枚舉IdType 中定義了主鍵支持的策略。
public enum IdType { //默認(rèn)就是數(shù)據(jù)庫(kù)自增,開發(fā)者無需賦值。 AUTO(0), //MP set 主鍵,雪花算法實(shí)現(xiàn)。 也是MP默認(rèn)的方式 NONE(1), //需要開發(fā)者手動(dòng)賦值 INPUT(2), //全局唯一ID (idWorker) ID_WORKER(3), //主鍵的數(shù)據(jù)類型必須是 String,自動(dòng)生成 UUID 進(jìn)行賦值 UUID(4), //字符串全局唯一ID (idWorker 的字符串表示) ID_WORKER_STR(5); private final int key; private IdType(int key) { this.key = key; } public int getKey() { return this.key; } }
修改主鍵ID是自增策略。插入數(shù)據(jù)后返回自增ID。
@Data @NoArgsConstructor @AllArgsConstructor /** * 指定該實(shí)體對(duì)應(yīng)的表名,如果不使用@TableName注解, * 表名稱默認(rèn)是類名,首字母小寫 */ @TableName("tb_user") public class User { //修改主鍵ID是自增策略 @TableId(type = IdType.AUTO) private Long id; private String userName; private String password; private String name; private Integer age; private String email; }
@TableField屬性
在MP中通過@TableField注解可以指定字段的一些屬性,常常解決的問題有2個(gè):
- 對(duì)象中的屬性名和數(shù)據(jù)庫(kù)字段名不一致的問題(非駝峰)。
- 對(duì)象中的屬性字段在數(shù)據(jù)庫(kù)字段中不存在。
@Data @NoArgsConstructor @AllArgsConstructor /** * 指定該實(shí)體對(duì)應(yīng)的表名,如果不使用@TableName注解, * 表名稱默認(rèn)是類名,首字母小寫 */ @TableName("tb_user") public class User { //修改主鍵ID是自增策略 @TableId(type = IdType.AUTO) private Long id; private String userName; private String password; private String name; private Integer age; //數(shù)據(jù)庫(kù)中是email,實(shí)體中是mail時(shí),用該字段映射 @TableField(value = "email") private String mail; /** * 該字段在數(shù)據(jù)庫(kù)中不存在,如果不使用注解,則查詢會(huì)報(bào)錯(cuò) * Cause: java.sql.SQLSyntaxErrorException: Unknown column 'address' in 'field list' * 如果使用了注解,查詢正常 */ @TableField(exist = false) private String address; }
MP中增刪改查的一些寫法
/** * QueryWrapper更新 */ @Test public void testUpdate2() { //User存放更新的字段,QueryWrapper存放更新的條件 User user = new User(); user.setAge(99); QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("id", 5); wrapper.eq("name", "孫七"); userMapper.update(user, wrapper); } /** * UpdateWrapper更新 */ @Test public void testUpdate3() { //更新的條件以及字段 UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.eq("id", 5); wrapper.eq("name", "孫七"); wrapper.set("age", 44); userMapper.update(null, wrapper); } /** * 刪除1 */ @Test public void testDeleteByMap() { Map<String, Object> columnMap = new HashMap<>(); columnMap.put("age", 20); columnMap.put("name", "張三"); //將columnMap中的元素設(shè)置為刪除的條件,多個(gè)之間為and關(guān)系 int result = this.userMapper.deleteByMap(columnMap); System.out.println("result = " + result); } /** * 刪除2 */ @Test public void testDeleteByMap2() { User user = new User(); user.setAge(20); user.setName("張三"); //將實(shí)體對(duì)象進(jìn)行包裝,包裝為操作條件 QueryWrapper<User> wrapper = new QueryWrapper<>(user); int result = this.userMapper.delete(wrapper); System.out.println("result = " + result); } /** * 根據(jù)ID批量刪除 */ @Test public void deleteBatchIds() { //根據(jù)id集合批量刪除 int result = this.userMapper.deleteBatchIds(Arrays.asList(1L, 10L, 20L)); System.out.println("result = " + result); } /** * 批量查詢 */ @Test public void selectBatchIds() { //根據(jù)id集合批量查詢 List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 10L)); for (User user : users) { System.out.println(user); } } /** * selectOne * 根據(jù) entity 條件,查詢一條記錄 */ @Test public void TestselectOne() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.eq("name", "李四"); //根據(jù)條件查詢一條數(shù)據(jù),如果結(jié)果超過一條會(huì)報(bào)錯(cuò) User user = this.userMapper.selectOne(wrapper); System.out.println(user); } /** * selectCount * 根據(jù) Wrapper 條件,查詢總記錄數(shù) */ @Test public void TestselectCount() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.gt("age", 23); //年齡大于23歲 // 根據(jù)條件查詢數(shù)據(jù)條數(shù) Integer count = this.userMapper.selectCount(wrapper); System.out.println(count); } /** * selectList * 根據(jù) Wrapper 條件,查詢list */ @Test public void TestselectList() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.gt("age", 23); //年齡大于23歲 // 根據(jù)條件查詢數(shù)據(jù) List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println("user = " + user); } }
MP中的分頁(yè)
新建分頁(yè)配置類
@Configuration public class MybatisPlusConfig { /** * 分頁(yè)插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
分頁(yè)測(cè)試方法
/** * MP分頁(yè) */ @Test public void testSelectPage() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.gt("age", 20); //年齡大于20歲 Page<User> page = new Page<>(1, 1); //根據(jù)條件查詢數(shù)據(jù) IPage<User> iPage = this.userMapper.selectPage(page, wrapper); System.out.println("數(shù)據(jù)總條數(shù):" + iPage.getTotal()); System.out.println("總頁(yè)數(shù):" + iPage.getPages()); List<User> users = iPage.getRecords(); for (User user : users) { System.out.println("user = " + user); } }
MP在application.yml的一些配置
server: port: 80 spring: #數(shù)據(jù)庫(kù)連接配置 datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=false username: root password: root mybatis-plus: #mapper配置文件 mapper-locations: classpath:mapper/*.xml #類別名 type-aliases-package: cn.yx.zg.pojo #開啟駝峰命名 configuration: #開啟數(shù)據(jù)庫(kù)駝峰命名,比如數(shù)據(jù)庫(kù)字段user_name,實(shí)體類userName可以自動(dòng)映射上 map-underscore-to-camel-case: true # 延遲加載 lazy-loading-enabled: true #false 為按需加載 aggressive-lazy-loading: false global-config: db-config: #統(tǒng)一設(shè)置主鍵自增策略 id-type: auto #統(tǒng)一設(shè)置表名前綴,可省略TableName()配置 table-prefix: tb_
SpringBoot+MP進(jìn)階用法
allEq用法
代碼案例1
/** * allEq(Map<R, V> params) ; * allEq(Map<R, V> params, boolean null2IsNull) ; * allEq(boolean condition, Map<R, V> params, boolean null2IsNull); * * 參數(shù)說明: * params:key為數(shù)據(jù)庫(kù)字段名, value 為字段值. * null2IsNull:為true時(shí),params的值為空時(shí),則調(diào)用is null; 為false時(shí),params的值為空時(shí)則忽略,默認(rèn)true. * condition:為true時(shí),params過慮條件生效,為false時(shí),過濾條件不生效,默認(rèn)是true. */ @Test public void testWrapper1() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); Map<String, Object> params = new HashMap<>(); params.put("name", "曹操"); params.put("age", "20"); params.put("password", null); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (password IS NULL AND name = ? AND age = ?) // wrapper.allEq(params); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (name = ? AND age = ?) // wrapper.allEq(params,false); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (name = ? AND age = ?) wrapper.allEq(false,params,true); List<User> users = this.userMapper.selectList(wrapper); users.stream().forEach(System.out::println); }
代碼案例2
/** * allEq(BiPredicate<R, V> filter, Map<R, V> params) * allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) * allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) * 參數(shù)說明 * filter: 過濾函數(shù),是否允許字段傳入比對(duì)條件中 * condition,params與null2IsNull同上個(gè)案例一樣 * */ @Test public void testWrapper2() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); Map<String, Object> params = new HashMap<>(); params.put("name", "曹操"); params.put("age", "20"); params.put("password", null); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (name = ? AND age = ?) wrapper.allEq((k, v) -> (k.equals("name") || k.equals("age")) ,params); List<User> users = this.userMapper.selectList(wrapper); users.stream().forEach(System.out::println); }
基本比較操作
/** * eq:等于 = * ne:不等于 <> * gt:大于 > * ge:大于等于 >= * lt:小于 < * le:小于等于 <= * between:BETWEEN 值1 AND 值2 * notBetween:NOT BETWEEN 值1 AND 值2 * in:字段 IN (value.get(0), value.get(1), ...) * notIn:字段 NOT IN (v0, v1, ...) */ @Test public void testWrapper3() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (password = ? AND age >= ? AND name IN (?,?,?)) wrapper.eq("password", "123456") .ge("age", 20) .in("name", "李四", "王五", "趙六"); List<User> users = this.userMapper.selectList(wrapper); users.stream().forEach(System.out::println); }
模糊查詢
/** * like:LIKE '%值%' * notLike:NOT LIKE '%值%' * likeLeft:LIKE '%值' * likeRight:LIKE '值%' */ @Test public void testWrapper4() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (name LIKE '%曹%') wrapper.like("name", "曹"); List<User> users = this.userMapper.selectList(wrapper); users.stream().forEach(System.out::println); }
排序
/** * orderBy:ORDER BY 字段, ... * orderByAsc:ORDER BY 字段, ... ASC * orderByDesc:ORDER BY 字段, ... DESC */ @Test public void testWrapper5() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user ORDER BY age DESC wrapper.orderByDesc("age"); List<User> users = this.userMapper.selectList(wrapper); users.stream().forEach(System.out::println); }
邏輯查詢
/** * or:主動(dòng)調(diào)用or表示緊接著下一個(gè)方法不是用 and 連接 (不調(diào)用 or 則默認(rèn)為使用 and 連接) * and: */ @Test public void testWrapper6() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (name = ? OR age = ?) // wrapper.eq("name", "李四").or().eq("age", 24); //SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE ( (name = ?) ) OR ( (age = ?) ) wrapper.and(i->i.eq("name","李四")).or(i->i.eq("age",24)); List<User> users = this.userMapper.selectList(wrapper); users.stream().forEach(System.out::println); }
select 指定字段查詢
在MP查詢中,默認(rèn)查詢所有的字段,如果有需要也可以通過select方法進(jìn)行指定字段。
@Test public void testWrapper7() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); //SELECT id,name,age FROM tb_user WHERE (name = ? OR age = ?) wrapper.eq("name", "李四") .or().eq("age", 24) .select("id", "name", "age"); List<User> users = this.userMapper.selectList(wrapper); users.stream().forEach(System.out::println); }
騷氣的Lambad寫法(推薦)
獲得LambdaQueryWrapper的三種方法
@Test public void testWrapperLambad1() { //創(chuàng)建lambda 條件構(gòu)造器 的三種方法 LambdaQueryWrapper<User> lambda1 = new LambdaQueryWrapper<>(); LambdaQueryWrapper<User> lambda2 = new QueryWrapper<User>().lambda(); //SQL: SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (name LIKE ? AND age < ?) LambdaQueryWrapper<User> lambda3 = Wrappers.<User>lambdaQuery(); lambda3.like(User::getName, "雨") .lt(User::getAge, 40); List<User> users = this.userMapper.selectList(lambda3); users.stream().forEach(System.out::println); }
LambdaQueryChainWrapper<實(shí)體>(xxxxMapper)
//MP3.0.7 新增的方式 @Test public void testWrapperLambad2() { //SQL:SELECT id,password,email AS mail,name,user_name,age FROM tb_user WHERE (name LIKE ? AND age >= ?) List<User> users = new LambdaQueryChainWrapper<User>(userMapper) .like(User::getName, "雨").ge(User::getAge, 20).list(); users.stream().forEach(System.out::println); }
多表查詢
如果是多表查詢,我們就要自己寫sql了, 自己寫sql,有兩種寫法。這兩種寫法都不需要額外的配置,直接寫就行。
寫法1:
直接再mapper接口上加注解寫自定義sql,圖片中只寫了單表查詢,多表也是一樣的。
寫法2
mybatis一樣,接口定義方法,xml文件寫sql。
到此這篇關(guān)于Java的MybatisPlus詳解的文章就介紹到這了,更多相關(guān)MybatisPlus詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot集成es插入和查詢的簡(jiǎn)單使用示例詳解
這篇文章主要介紹了springboot集成es 插入和查詢的簡(jiǎn)單使用,本文分步驟結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(3)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-07-07淺談SpringSecurity注解與AOP切面執(zhí)行順序
這篇文章主要介紹了淺談SpringSecurity注解與AOP切面執(zhí)行順序,引入Spring Security后,在Controller的方法中會(huì)出現(xiàn)Spring Security的方法注解與AOP同時(shí)存在的問題,這是就會(huì)設(shè)計(jì)順序問題,需要的朋友可以參考下2023-10-10java 利用反射機(jī)制,獲取實(shí)體所有屬性和方法,并對(duì)屬性賦值
這篇文章主要介紹了 java 利用反射機(jī)制,獲取實(shí)體所有屬性和方法,并對(duì)屬性賦值的相關(guān)資料,需要的朋友可以參考下2017-01-01SpringBoot多環(huán)境切換的靈活配置詳細(xì)教程
在真實(shí)項(xiàng)目開發(fā)的時(shí)候,一定會(huì)有多個(gè)環(huán)境,下面這篇文章主要給大家介紹了關(guān)于SpringBoot多環(huán)境切換靈活配置的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04詳解Java中finally和return的執(zhí)行順序
try-catch-finally是一種針對(duì)程序運(yùn)行時(shí)出錯(cuò)的響應(yīng)手段,對(duì)于一些可以預(yù)料到的出錯(cuò)類型,在發(fā)生時(shí)對(duì)其進(jìn)行報(bào)告和補(bǔ)救,這篇文章主要介紹了Java中finally和return的執(zhí)行順序,需要的朋友可以參考下2024-01-01使用jaxp進(jìn)行dom解析_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了使用jaxp進(jìn)行dom解析的相關(guān)資料,需要的朋友可以參考下2017-08-08