Mybatis框架,MyBatis-Plus - 快速入門

 2023-11-05 阅读 25 评论 0

摘要:Mybatis框架? 1、數據庫建表 # 創建用戶表 CREATE TABLE user (id BIGINT(20) PRIMARY KEY NOT NULL COMMENT '主鍵',name VARCHAR(30) DEFAULT NULL COMMENT '姓名',age INT(11) DEFAULT NULL COMMENT '年齡',email VARCHAR(50) DEFAULT NULL COMM

Mybatis框架?

1、數據庫建表

# 創建用戶表
CREATE TABLE user (id BIGINT(20) PRIMARY KEY NOT NULL COMMENT '主鍵',name VARCHAR(30) DEFAULT NULL COMMENT '姓名',age INT(11) DEFAULT NULL COMMENT '年齡',email VARCHAR(50) DEFAULT NULL COMMENT '郵箱',manager_id BIGINT(20) DEFAULT NULL COMMENT '直屬上級id',create_time DATETIME DEFAULT NULL COMMENT '創建時間',CONSTRAINT manager_fk FOREIGN KEY (manager_id)REFERENCES user (id)
)  ENGINE=INNODB CHARSET=UTF8;# 初始化數據:
INSERT INTO user (id, name, age, email, manager_id, create_time)
VALUES (1087982257332887553, '大boss', 40, 'boss@baomidou.com', NULL, '2019-01-11 14:20:20'),(1088248166370832385, '王天風', 25, 'wtf@baomidou.com', 1087982257332887553, '2019-02-05 11:12:22'),(1088250446457389058, '李藝偉', 28, 'lyw@baomidou.com', 1088248166370832385, '2019-02-14 08:31:16'),(1094590409767661570, '張雨琪', 31, 'zjq@baomidou.com', 1088248166370832385, '2019-01-14 09:15:15'),(1094592041087729666, '劉紅雨', 32, 'lhm@baomidou.com', 1088248166370832385, '2019-01-14 09:48:16');

2、依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</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.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.2</version>
</dependency>

3、SpringBoot 配置文件

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: rooturl: jdbc:mysql://localhost:3306/test?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
logging:level:root: warnorg.ywb.demo.dao: tracepattern:console: '%p%m%n'

4、創建相關包,如圖

Mybatis。

5、在pojo包中新建和數據庫user表映射的類

@Data
public class User {private Long id;private String name;private Integer age;private String email;private String managerId;private LocalDateTime createTime;
}

6、在dao包中創建mapper接口,并集成mybatisPlus的BaseMapper

public interface UserMapper extends BaseMapper<User> {}

7、在springboot啟動類添加@MapperScan掃描dao層接口

@MapperScan("org.ywb.demo.dao")
@SpringBootApplication
public class MybatisPlusDemoApplication {public static void main(String[] args) {SpringApplication.run(MybatisPlusDemoApplication.class, args);}}

8、編寫測試類

@RunWith(SpringRunner.class)
@SpringBootTest
public class MybatisPlusDemoApplicationTests {@Resourceprivate UserMapper userMapper;@Testpublic void select(){List<User> users = userMapper.selectList(null);users.forEach(System.out::println);}}

9、運行結果

MySQL菜鳥教程,

新增方法

UserMapper代碼

package com.neo.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.neo.model.User;
import org.apache.ibatis.annotations.Mapper;//要使用mp,就要集成BaseMapper
@Mapper
public interface UserMapper extends BaseMapper<User> {}

在測試方法中調用userMapper中的insert方法

@Test
public void insert(){User user = new User();user.setName("黃小明");user.setAge(20);user.setManagerId(1088248166370832385L);user.setCreateTime(LocalDateTime.now());int rows = userMapper.insert(user);System.out.println("影響記錄數:"+rows);}

測試結果

DEBUG==> Preparing: INSERT INTO user ( id, name, age, manager_id, create_time ) VALUES ( ?, ?, ?, ?, ? ) DEBUG==> Parameters: 1223961279246393345(Long), 黃小明(String), 20(Integer), 1088248166370832385(Long), 2020-02-02T21:28:03.621(LocalDateTime) DEBUG<== Updates: 1 影響記錄數:1

常用注解

java priorityqueue?MyBatisPlus提供了一些注解供我們在實體類和表信息出現不對應的時候使用。通過使用注解完成邏輯上匹配。

注解名稱說明
@TableName實體類的類名和數據庫表名不一致
@TableId實體類的主鍵名稱和表中主鍵名稱不一致
@TableField實體類中的成員名稱和表中字段名稱不一致

@TabName注解

當修改數據庫表明卻不想修改實體類型時,可以通過@TabName("數據庫表名")來指定表名,否則會運行報錯。

@Data
@TableName("mp_user")
public class User {//主鍵private Long id;//姓名private String name;//年齡private Integer age;//郵箱private String email;//直屬上級private Long managerId;//創建時間private LocalDateTime createTime;
}

@TabId注解

當實例中主鍵與數據庫中的主鍵名稱不一致時(例如實例中為駝峰命名,數據庫表中為下劃線命名),可使用該注解。

@TableField注解

Spring boot、當實例中的字段與數據庫中的字段不同時,就可以使用該注解映射,如下例

@TableField("name")
private String realName;

排除非表字段的三種方式

第一:在聲明類屬性時使用?transient?關鍵字聲明。

第二:如上方法可能無法序列化該字段,故可以在聲明類屬性時:使用?static?關鍵字聲明為靜態變量(注意,用static 聲明的靜態變量lombok不會為其添加set和get方法)。

第三:使用@TableField(exist = false)注解注解 其中括號中的 exist = false 表示該字段不是數據庫表中的字段,無需映射。

基本查詢方法

vue+MySQL、通過id查詢:selectById()方法

@Test
public void selectById() {User user = userMapper.selectById(1094590409767661570L);System.out.println(user);
}

批量查詢:selectBatchIds()

@Test
public void selectByIds() {List<Long> idsList = Arrays.asList(1094592041087729666L, 1223961279246393345L, 1088250446457389058L);List<User> users = userMapper.selectBatchIds(idsList);users.forEach(System.out::println);
}

通過map查詢

@Test
public void selectByMap() {Map<String,Object> columnMap = new HashMap<>();columnMap.put("name","王天風");columnMap.put("age",25);//通過此map會執行類似 where name="王天風" and age=25 的sqlList<User> userList = userMapper.selectByMap(columnMap);userList.forEach(System.out::println);
}

注意:此map中的鍵名為數據表中列名,并非實體類中的屬性名

以條件構造器為參數的查詢方法

/* 查詢要求:1、名字中包含雨并且年齡小于40name like '%雨%' and age<40*/
@Test
public void selectByWrapper() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//等同于//QueryWrapper<User> query = Wrappers.<User>query();queryWrapper.like("name","雨").lt("age",40);//注意:此處的鍵名依舊為數據庫中的列名List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}/*2、名字中包含雨年并且齡大于等于20且小于等于40并且email不為空name like '%雨%' and age between 20 and 40 and email is not null*/
@Test
public void selectByWrapper2() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//等同于//QueryWrapper<User> query = Wrappers.<User>query();queryWrapper.like("name","雨").between("age",20,40).isNotNull("email");//注意:此處的鍵名依舊為數據庫中的列名List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}/*3、名字為王姓或者年齡大于等于25,按照年齡降序排列,年齡相同按照id升序排列name like '王%' or age>=25 order by age desc,id asc*/
@Test
public void selectByWrapper3() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//等同于//QueryWrapper<User> query = Wrappers.<User>query();queryWrapper.likeRight("name","王").or().ge("age",25).orderByDesc("age").orderByAsc("id");//注意:此處的鍵名依舊為數據庫中的列名List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}/*4、創建日期為2019年2月14日并且直屬上級為名字為王姓date_format(create_time,'%Y-%m-%d')='2019-02-14' and manager_id in (select id from user where name like '王%')*/
@Test
public void selectByWrapper4() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//等同于//QueryWrapper<User> query = Wrappers.<User>query();queryWrapper.apply("date_format(create_time,'%Y-%m-%d')={0}","2019-02-14").inSql("manager_id","select id from user where name like '王%'");//注意:此處的鍵名依舊為數據庫中的列名List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}
// 注意:以上方法查詢為推薦查詢,不建議寫如下方式查詢:會導致sql注入風險
//queryWrapper.apply("date_format(create_time,'%Y-%m-%d')="2019-02-14")/*5、名字為王姓并且(年齡小于40或郵箱不為空)name like '王%' and (age<40 or email is not null)*/
@Test
public void selectByWrapper5() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//等同于//QueryWrapper<User> query = Wrappers.<User>query();queryWrapper.likeRight("name","王").and(wq->wq.lt("age",40).or().isNotNull("email"));//注意:此處的鍵名依舊為數據庫中的列名List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}/*6、名字為王姓或者(年齡小于40并且年齡大于20并且郵箱不為空)name like '王%' or (age<40 and age>20 and email is not null)*/
@Test
public void selectByWrapper6() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//等同于//QueryWrapper<User> query = Wrappers.<User>query();queryWrapper.likeRight("name","王").or(wq->wq.lt("age",40).gt("age",20).isNotNull("email"));//注意:此處的鍵名依舊為數據庫中的列名List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}/*7、(年齡小于40或郵箱不為空)并且名字為王姓(age<40 or email is not null) and name like '王%'*/
@Test
public void selectByWrapper7() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//等同于//QueryWrapper<User> query = Wrappers.<User>query();queryWrapper.nested(wq->wq.lt("age",40).or().isNotNull("email")).likeRight("name","王");//注意:此處的鍵名依舊為數據庫中的列名List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}/*8、年齡為30、31、34、35age in (30、31、34、35)*/
@Test
public void selectByWrapper8() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//等同于//QueryWrapper<User> query = Wrappers.<User>query();queryWrapper.in("age",Arrays.asList(30,31,34,35));//注意:此處的鍵名依舊為數據庫中的列名List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}
/*** 無視優化規則直接拼接到 sql 的最后(有sql注入的風險,請謹慎使用)* <p>例: last("limit 1")</p>* <p>注意只能調用一次,多次調用以最后一次為準</p>** @param condition 執行條件* @param lastSql   sql語句* @return children*/
Children last(boolean condition, String lastSql);/*** 9. 只返回滿足條件的一條語句即可*    limit 1*/
@Test
public void selectWrapper7(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.in("age", Arrays.asList(30,31,34,35)).last("limit 1");List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}

  • last 有SQL注入的風險!!!

select中字段不全出現的處理方法

并非每次查詢都要查詢所有字段,測試可用如下方法查詢

/*10、名字中包含雨并且年齡小于40(需求1加強版)第一種情況select id,namefrom userwhere name like '%雨%' and age<40
*/
@Test
public void selectByWrapperSuper() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("id","name").like("name","雨").lt("age",40);List<User> userList =userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}/*第二種情況select id,name,age,emailfrom userwhere name like '%雨%' and age<40
*/
@Test
public void selectByWrapperSuper2() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("name","雨").lt("age",40).select(User.class,info->!info.getColumn().equals("create_time")&&!info.getColumn().equals("manager_id"));List<User> userList =userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}

條件構造器中condition作用

@Test
public void testCondition() {String name="王";String email="";condition(name,email);
}public void condition(String name,String email){QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//       if(StringUtils.isNotEmpty(name)){
//           queryWrapper.like("name",name);
//       }
//        if(StringUtils.isNotEmpty(email)){
//            queryWrapper.like("email",email);
//        }// 以上代碼過于臃腫,可采用如下代碼代替queryWrapper.like(StringUtils.isNotEmpty(name),"name",name).like(StringUtils.isNotEmpty(email),"email",email);List<User> userList =userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}

創建條件構造器時傳入實體對象

如果想通過對象中某些屬性進行模糊查詢,我們可以在跟數據庫表對應的實體類中相應的屬性標注注解即可。
比如我們想通過姓名進行模糊查詢用戶列表。

@TableField(condition = SqlCondition.LIKE)
private String name;
@Test
public void selectWrapper10(){User user = new User();user.setName("紅");user.setAge(32);QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);List<User> userList = userMapper.selectList(queryWrapper);userList.forEach(System.out::println);
}

  • 當然可以通過源碼對照?SqlCondition 對應的作用

  • 如果源碼中沒有找到想要的功能,還可以自定義,如圖

條件構造器中allEq用法

/*** allEq*/
@Test
public void selectList_allEq() {QueryWrapper<User> query = new QueryWrapper<>();Map<String, Object> params = new HashMap<>();params.put("name", "劉明強");params.put("age", 31);params.put("email", null);
//        query.allEq(params,false);//第二個參數表示如果列值為null是否按IS NULL查詢,false則忽略null列的查詢query.allEq((k, v) -> !k.equals("name"), params, false);//第一個參數是過濾器List<User> list = userMapper.selectList(query);list.forEach(System.out::println);
}

其他以條件構造器為參數的查詢方法

/*** selectMaps的應用場景1:當表中的列特別多,但實際只需要幾個列時,這時返回一個實體類有些不必要*/
@Test
public void selectMaps() {QueryWrapper<User> query = new QueryWrapper<>();query.like("name", "雨").lt("age", 40).select("name", "age");List<Map<String, Object>> maps = userMapper.selectMaps(query);maps.forEach(System.out::println);
}/*** selectMaps的應用場景2:查詢統計結果* 按照直屬上級分組,查詢每組的平均年齡、最大年齡、最小年齡,并且只取年齡總和小于100的組* SELECT AVG(age) avg_age,MIN(age) min_age,MAX(age) max_age* FROM `user`* GROUP BY `manager_id`* HAVING SUM(age)<100;*/
@Test
public void selectMaps2() {QueryWrapper<User> query = new QueryWrapper<>();query.select("AVG(age) avg_age", "MIN(age) min_age", "MAX(age) max_age").groupBy("manager_id").having("SUM(age)<{0}", 100);List<Map<String, Object>> maps = userMapper.selectMaps(query);maps.forEach(System.out::println);
}/*** selectObjs只返回第一列,其它列被遺棄* 應用場景:只需返回一列的時候*/
@Test
public void selectObjs() {QueryWrapper<User> query = new QueryWrapper<>();query.like("name", "雨").lt("age", 40).select("name", "age");List<Object> list = userMapper.selectObjs(query);list.forEach(System.out::println);
}/*** 返回總記錄數*/
@Test
public void selectCount() {QueryWrapper<User> query = new QueryWrapper<>();query.like("name", "雨").lt("age", 40);Integer count = userMapper.selectCount(query);System.out.println("總記錄數:" + count);
}/*** selectOne:只能查詢一條記錄,查詢到多條會報錯*/
@Test
public void selectOne() {QueryWrapper<User> query = new QueryWrapper<>();query.like("name", "劉紅雨").lt("age", 40);User user = userMapper.selectOne(query);System.out.println(user);
}

Lambda條件構造器

/*** lambda條件構造器*/
@Test
public void lambdaQueryWrapper1() {
//        LambdaQueryWrapper<User> lambdaQ = new QueryWrapper<User>().lambda();
//        LambdaQueryWrapper<User> lambdaQ = new LambdaQueryWrapper<>();LambdaQueryWrapper<User> lambdaQ = Wrappers.<User>lambdaQuery();lambdaQ.like(User::getName, "雨").lt(User::getAge, 40);List<User> list = userMapper.selectList(lambdaQ);list.forEach(System.out::println);
}/*** lambda條件構造器:防誤寫(例如列名"name"可能被誤寫)*/
@Test
public void lambdaQueryWrapper2() {LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();query.likeRight(User::getName, "王").and(q -> q.lt(User::getAge, 40).or().isNotNull(User::getEmail));List<User> list = userMapper.selectList(query);list.forEach(System.out::println);
}/*** 鏈式lambda條件構造器:更優雅的書寫方式*/
@Test
public void lambdaQueryChainWrapper() {List<User> list = new LambdaQueryChainWrapper<User>(userMapper).likeRight(User::getName, "王").and(q -> q.lt(User::getAge, 40).or().isNotNull(User::getEmail)).list();list.forEach(System.out::println);
}

使用條件構造器的自定義SQL

(要求版本大于等于3.0.7)

在UserMapper中定于接口方法(采用注解的方式)

@Select("select * from user ${ew.customSqlSegment}")
List<User> selectAll(@Param(Constants.WRAPPER)Wrapper<User> wrapper);

在測試中使用自定義方法

@Test
public void selectMy() {
//        LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
//        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();lambdaQuery.like(User::getName,"雨").lt(User::getAge,40);//where name like '%雨%'List<User> userList = userMapper.selectAll(lambdaQuery);//此處使用自定義接口方法userList.forEach(System.out::println);}

如果不想把自定義sql寫在接口中,例如寫在xml中,還可以采用如下方法:

第一步:在yml配置文件中配置接口對應的xml路徑

Mybatis-plus:mapper-locations: classpath:mp/mapper/*.xml

在配置路徑下新建UserMapper.xml文件,同時去除接口中的注解sql

<?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" >
<mapper namespace="com.neo.mapper.UserMapper" ><select id="selectAll" resultType="com.neo.model.User">select * from user ${ew.customSqlSegment}</select>
</mapper>

mybatis中提供分頁方法,但是該分頁是邏輯分頁,而非物理分頁。

MP分頁插件實現物理分頁

新建配置包(com.neo.configuration)并新建配置分頁類MybatisPlusConfig:

@Configuration
public class MybatisPlusConfig {@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}
}

測試(selectPage)

@Test
public void selectPage() {QueryWrapper<User> queryWrapper = new QueryWrapper<User>();queryWrapper.ge("age", 26);Page<User> page = new Page<>(1, 2);IPage<User> iPage = userMapper.selectPage(page, queryWrapper);System.out.println("總頁數:" + iPage.getPages());System.out.println("總記錄數:" + iPage.getTotal());List<User> userlist = iPage.getRecords();userlist.forEach(System.out::println);
}運行日志:DEBUG==>  Preparing: SELECT COUNT(1) FROM user WHERE age >= ? 
DEBUG==> Parameters: 26(Integer)
TRACE<==    Columns: COUNT(1)
TRACE<==        Row: 7
DEBUG==>  Preparing: SELECT id,name,age,email,manager_id,create_time FROM user WHERE age >= ? LIMIT ?,? 
DEBUG==> Parameters: 26(Integer), 0(Long), 2(Long)
TRACE<==    Columns: id, name, age, email, manager_id, create_time
TRACE<==        Row: 1087982257332887553, 大boss, 40, boss@baomidou.com, null, 2019-01-11 14:20:20
TRACE<==        Row: 1088250446457389058, 李藝偉, 28, lyw@baomidou.com, 1088248166370832385, 2019-02-14 08:31:16
DEBUG<==      Total: 2
總頁數:4
總記錄數:7
User(id=1087982257332887553, name=大boss, age=40, email=boss@baomidou.com, managerId=null, createTime=2019-01-11T14:20:20)
User(id=1088250446457389058, name=李藝偉, age=28, email=lyw@baomidou.com, managerId=1088248166370832385, createTime=2019-02-14T08:31:16)

測試(selectMapsPage)

@Test
public void selectPage() {QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//        queryWrapper.ge("age",26);Page<User> page = new Page<>(1, 2);
//        IPage<User> iPage = userMapper.selectPage(page, queryWrapper);
//        System.out.println("總頁數:"+ iPage.getPages());
//        System.out.println("總記錄數:"+ iPage.getTotal());
//        List<User> userlist = iPage.getRecords();IPage<Map<String, Object>> iPage = userMapper.selectMapsPage(page, queryWrapper);System.out.println("總頁數:"+ iPage.getPages());System.out.println("總記錄數:"+ iPage.getTotal());List<Map<String, Object>> userlist = iPage.getRecords();userlist.forEach(System.out::println);
}DEBUG==>  Preparing: SELECT COUNT(1) FROM user 
DEBUG==> Parameters: 
TRACE<==    Columns: COUNT(1)
TRACE<==        Row: 13
DEBUG==>  Preparing: SELECT id,name,age,email,manager_id,create_time FROM user LIMIT ?,? 
DEBUG==> Parameters: 0(Long), 2(Long)
TRACE<==    Columns: id, name, age, email, manager_id, create_time
TRACE<==        Row: 1087982257332887553, 大boss, 40, boss@baomidou.com, null, 2019-01-11 14:20:20
TRACE<==        Row: 1088248166370832385, 王天風, 25, wtf@baomidou.com, 1087982257332887553, 2019-02-05 11:12:22
DEBUG<==      Total: 2
總頁數:7
總記錄數:13
{createTime=2019-01-11 14:20:20.0, name=大boss, id=1087982257332887553, age=40, email=boss@baomidou.com}
{createTime=2019-02-05 11:12:22.0, name=王天風, id=1088248166370832385, managerId=1087982257332887553, age=25, email=wtf@baomidou.com}

從以上兩個例子看以看出每個是執行了兩條sql語句,如果只想要查詢結果,不想要查詢總數,只需要將page的第三個參數變為false,即可:

Page<User> page = new Page<>(1, 2,false);
  • 當我們在做多表聯查時,就不能使用如上方式查詢了,此時可以在xml文件中自定義sql。

根據id更新

@Test
public void updateById(){User user= new User();user.setId(1088248166370832385L);user.setAge(26);user.setEmail("wtf2@baomidou.com");int rows = userMapper.updateById(user);System.out.println("影響記錄數:"+ rows);
}運行日志:DEBUG==>  Preparing: UPDATE user SET age=?, email=? WHERE id=? 
DEBUG==> Parameters: 26(Integer), wtf2@baomidou.com(String), 1088248166370832385(Long)
DEBUG<==    Updates: 1
影響記錄數:1

以條件構造器作為參數的更新方法

@Test
public void updateByWrapper(){UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("name","李藝偉").eq("age",28);User user = new User();user.setEmail("lyw2020@baomidou.com");user.setAge(29);int rows = userMapper.update(user, updateWrapper);System.out.println("影響行數:"+rows);
}運行日志:
DEBUG==>  Preparing: UPDATE user SET age=?, email=? WHERE name = ? AND age = ? 
DEBUG==> Parameters: 29(Integer), lyw2020@baomidou.com(String), 李藝偉(String), 28(Integer)
DEBUG<==    Updates: 1
影響行數:1

條件構造器中set方法使用

(只修改少量字段時)

@Test
public void updateByWrapper(){UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();//通過條件構造器的鏈式編程設置更新信息updateWrapper.eq("name","李藝偉").eq("age",29).set("email","liw888@qq.com");//   User user = new User();int rows = userMapper.update(null, updateWrapper);System.out.println("影響行數:"+rows);
}

lambda條件構造器更新

@Test
public void updateByWrapperLambda(){LambdaUpdateWrapper<User> lambdaUpdate = Wrappers.<User>lambdaUpdate();lambdaUpdate.eq(User::getName,"李藝偉").eq(User::getAge,29).set(User::getAge,31);int rows = userMapper.update(null, lambdaUpdate);System.out.println("影響行數:"+rows);
}

根據id刪除的方法

@Test
public void deleteById() {int rows= userMapper.deleteById(1223976086888599553L);System.out.println("影響行數:"+rows);
}

根據id批量刪除

@Test
public void deleteBatchIds() {int rows =  userMapper.deleteBatchIds(Arrays.asList(1223973741031141377L,1223972327026405378L,1223970002606067714L));System.out.println("影響行數:"+rows);
}

其他普通刪除方法

@Test
public void deleteByMap() {Map<String,Object> columnMap= new HashMap<>();columnMap.put("name","向后");columnMap.put("age","31");int rows = userMapper.deleteByMap(columnMap);System.out.println("影響行數:"+rows);
}

以條件構造器為參數的刪除方法

AR模式(Active Record)

直接通過實體類完成對數據的增刪改查。

實體類繼承Model類

@Data
@EqualsAndHashCode(callSuper = false)
public class User extends Model<User> {private Long id;@TableField(condition = SqlCondition.LIKE)private String name;private Integer age;private String email;private Long managerId;private LocalDateTime createTime;
}

Model類中封裝了很多增刪改查方法,不用使用UserMapper即可完成對數據的增刪改查。

查詢所有用戶信息

@Test
public void test(){User user = new User();user.selectAll().forEach(System.out::println);
}

主鍵策略

MyBatisPlus的主鍵策略封裝在IdType枚舉類中。

@Getter
public enum IdType {/*** 數據庫ID自增*/AUTO(0),/*** 該類型為未設置主鍵類型(將跟隨全局)*/NONE(1),/*** 用戶輸入ID* <p>該類型可以通過自己注冊自動填充插件進行填充</p>*/INPUT(2),/* 以下3種類型、只有當插入對象ID 為空,才自動填充。 *//*** 全局唯一ID (idWorker)*/ID_WORKER(3),/*** 全局唯一ID (UUID)*/UUID(4),/*** 字符串全局唯一ID (idWorker 的字符串表示)*/ID_WORKER_STR(5);private final int key;IdType(int key) {this.key = key;}
}

在實體類中對應數據庫中的主鍵id屬性上標注注解TableId(type='xxx')即可完成主鍵配置。

@TableId(type = IdType.AUTO)
private Long id;

這種配置方式的主鍵策略只能在該表中生效,但是其他表還需要進行配置,為了避免冗余,麻煩,MybatisPlus提供了全局配置,在配置文件中配置主鍵策略即可實現。

mybatis-plus:mapper-locations: mapper/*.xmlglobal-config:db-config:id-type: auto
  • 如果全局策略和局部策略全都設置,局部策略優先。

基本配置

mybatis-plus:mapper-locations: mapper/*.xmlglobal-config:db-config:# 主鍵策略id-type: auto# 表名前綴table-prefix: t# 表名是否使用下劃線間隔,默認:是table-underline: true# 添加mybatis配置文件路徑config-location: mybatis-config.xml# 配置實體類包地址type-aliases-package: org.ywb.demo.pojo# 駝峰轉下劃線configuration:map-underscore-to-camel-case: true
  • config-location & configuration 不能同時出現,否則報錯。

通用Service

定義接口繼承IService

public interface UserService extends IService<User>{}

定義接口的實現類

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{}

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/168385.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息