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語句
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實體
@Data
@NoArgsConstructor
@AllArgsConstructor
/**
* 指定該實體對應(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主啟動類MybatisPlusApplication
@MapperScan("cn.yx.zg.mapper")
@SpringBootApplication
public class MybatisPlusApplication {
public static void main(String[] args) {
// 啟動spring 應(yīng)用
SpringApplication.run(MybatisPlusApplication.class, args);
}
}通過以上代碼,咱們就搭建了一個SpringBoot+MP的環(huán)境。
六、測試類
@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自動回填到對象中:{}", 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ù)庫自增,開發(fā)者無需賦值。
AUTO(0),
//MP set 主鍵,雪花算法實現(xiàn)。 也是MP默認(rèn)的方式
NONE(1),
//需要開發(fā)者手動賦值
INPUT(2),
//全局唯一ID (idWorker)
ID_WORKER(3),
//主鍵的數(shù)據(jù)類型必須是 String,自動生成 UUID 進行賦值
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
/**
* 指定該實體對應(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個:
- 對象中的屬性名和數(shù)據(jù)庫字段名不一致的問題(非駝峰)。
- 對象中的屬性字段在數(shù)據(jù)庫字段中不存在。
@Data
@NoArgsConstructor
@AllArgsConstructor
/**
* 指定該實體對應(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ù)庫中是email,實體中是mail時,用該字段映射
@TableField(value = "email")
private String mail;
/**
* 該字段在數(shù)據(jù)庫中不存在,如果不使用注解,則查詢會報錯
* 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è)置為刪除的條件,多個之間為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("張三");
//將實體對象進行包裝,包裝為操作條件
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é)果超過一條會報錯
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中的分頁
新建分頁配置類
@Configuration
public class MybatisPlusConfig {
/**
* 分頁插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}分頁測試方法
/**
* MP分頁
*/
@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("總頁數(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ù)庫連接配置
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ù)庫駝峰命名,比如數(shù)據(jù)庫字段user_name,實體類userName可以自動映射上
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進階用法
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ù)庫字段名, value 為字段值.
* null2IsNull:為true時,params的值為空時,則調(diào)用is null; 為false時,params的值為空時則忽略,默認(rèn)true.
* condition:為true時,params過慮條件生效,為false時,過濾條件不生效,默認(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ù),是否允許字段傳入比對條件中
* condition,params與null2IsNull同上個案例一樣
* */
@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:主動調(diào)用or表示緊接著下一個方法不是用 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方法進行指定字段。
@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<實體>(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談SpringSecurity注解與AOP切面執(zhí)行順序
這篇文章主要介紹了淺談SpringSecurity注解與AOP切面執(zhí)行順序,引入Spring Security后,在Controller的方法中會出現(xiàn)Spring Security的方法注解與AOP同時存在的問題,這是就會設(shè)計順序問題,需要的朋友可以參考下2023-10-10
java 利用反射機制,獲取實體所有屬性和方法,并對屬性賦值
這篇文章主要介紹了 java 利用反射機制,獲取實體所有屬性和方法,并對屬性賦值的相關(guān)資料,需要的朋友可以參考下2017-01-01
SpringBoot多環(huán)境切換的靈活配置詳細教程
在真實項目開發(fā)的時候,一定會有多個環(huán)境,下面這篇文章主要給大家介紹了關(guān)于SpringBoot多環(huán)境切換靈活配置的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-04-04
詳解Java中finally和return的執(zhí)行順序
try-catch-finally是一種針對程序運行時出錯的響應(yīng)手段,對于一些可以預(yù)料到的出錯類型,在發(fā)生時對其進行報告和補救,這篇文章主要介紹了Java中finally和return的執(zhí)行順序,需要的朋友可以參考下2024-01-01
使用jaxp進行dom解析_動力節(jié)點Java學(xué)院整理
這篇文章主要介紹了使用jaxp進行dom解析的相關(guān)資料,需要的朋友可以參考下2017-08-08

