MyBatisPlus

瓜亭發表於2024-10-18

一、快速開始

1、pom檔案依賴搞一份:

<dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.4.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

資料庫:

CREATE TABLE `grade`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '年級編號',
  `grade_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '年級名稱',
  `float_col` float NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of grade
-- ----------------------------
INSERT INTO `grade` VALUES (1, '大一', 1.2);
INSERT INTO `grade` VALUES (2, '大二', 1.3);
INSERT INTO `grade` VALUES (3, '大三', 1.4);
INSERT INTO `grade` VALUES (4, '大四', 1.5);

2、執行自動生成程式碼Main函式

public class MybatisGenerator {
    public static void main(String[] args) {
        //建立Generator物件
        AutoGenerator autoGenerator = new AutoGenerator();

        /***********資料來源配置****************/
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
        dataSourceConfig.setUrl("jdbc:mysql://hadoop-100:3306/school?useUnicode=true&characterEncoding=UTF-8");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("root");
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        autoGenerator.setDataSource(dataSourceConfig);

        /***********全域性配置****************/
        GlobalConfig globalConfig = new GlobalConfig();
        //獲取當前系統目錄usr.dir,然後後面跟自己的模組名和程式碼路徑
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatisplus-demo/src/main/java");
        globalConfig.setOpen(true);
        globalConfig.setAuthor("lihaiyu");
        autoGenerator.setGlobalConfig(globalConfig);

        /***********包配置****************/
        PackageConfig packageConfig = new PackageConfig();
        //父package
        packageConfig.setParent("cn.lihaiyu");
        //本身package名,可以不設定
        packageConfig.setModuleName("generator");
        //controller包名
        packageConfig.setController("controller");
        //service包名
        packageConfig.setService("service");
        //serviceImpl包名
        packageConfig.setServiceImpl("service.impl");
        //mapper包名
        packageConfig.setMapper("mapper");
        //實體類包名
        packageConfig.setEntity("entity");
        autoGenerator.setPackageInfo(packageConfig);

        /***********配置策略****************/
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setEntityLombokModel(true);
        //設定自動生成哪張表,不設定預設生成全部表
        strategyConfig.setInclude("grade");
        //邏輯刪除欄位設定
        strategyConfig.setLogicDeleteFieldName("deleted");
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        autoGenerator.setStrategy(strategyConfig);

        autoGenerator.execute();
    }
}

得到結構如下:

3、建立一個sprinboot啟動程式

這裡需要主要配置一下需要掃描的包mapper

@SpringBootApplication
@MapperScan("cn.lihaiyu.generator.mapper")
public class MybatisPlusApplication {
    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class);
    }
}

4、這樣就弄好了,讓我們在controller中寫一個方法吧

① 剛開始我寫了這個:

@Controller
@RequestMapping("api/v1")
public class GradeController {
    @Autowired
    GradeMapper gradeMapper;

    @GetMapping("/get")
    public int get(){
        int count = gradeMapper.selectCount(null);
        return count;
    }
}

② 然後就報錯了,從這裡找到答案,然後修改為符合RestFul風格的程式碼

@Controller
@RequestMapping("api/v1")
public class GradeController {
    @Autowired
    GradeMapper gradeMapper;

    @GetMapping("/get")
    public int get(){
        int count = gradeMapper.selectCount(null);
        return count;
    }
}

成功返回結果

③ 增加一個響應類,修改返回值

@Data
public class GlobalResponse<T> {
    private Integer code = -1;
    private T data;
    private String msg;

    public GlobalResponse(Integer code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }
}
@RestController
@RequestMapping("api/v1")
public class GradeController {
    @Autowired
    GradeMapper gradeMapper;

    @GetMapping("/get")
    public GlobalResponse get(){
        int count = gradeMapper.selectCount(null);
        if (count >= 0) {
            return new GlobalResponse(0, count, "成功");
        } else {
            return new GlobalResponse(-1, null, "失敗");
        }
    }
}

哎~,有內味兒了 

二、整點別的

2.1 selectById

    //這裡使用{id}和@PathVariable提供一個佔位符
    @GetMapping("queryById/{id}")
    public GlobalResponse queryById(@PathVariable int id){
        Grade result = gradeMapper.selectById(id);
        return new GlobalResponse(0,result,"成功");
    }

2.2 selectOne

//@RequestParam表示這是需要傳遞一個引數
    @GetMapping("selectOne")
    public GlobalResponse selectOne(@RequestParam String gradeName){
        Grade grade = new Grade();
        grade.setGradename(gradeName);
        QueryWrapper<Grade> wrapper = new QueryWrapper(grade);
        Grade result = gradeMapper.selectOne(wrapper);
        return new GlobalResponse(0,result,"成功");
    }

使用這部分替代上述程式碼功能,LambdaQueryWrapper的好處就是不用建立物件,同時還支援流式操作。

@GetMapping("selectOne")
    public GlobalResponse selectOne(@RequestParam String gradeName){
        LambdaQueryWrapper<Grade> wrapper = new LambdaQueryWrapper();
        wrapper.eq(Grade::getGradename,gradeName);
        Grade result = gradeMapper.selectOne(wrapper);
        return new GlobalResponse(0,result,"成功");
    }
 @GetMapping("selectOne")
    public GlobalResponse selectOne(@RequestParam String gradeName){
        LambdaQueryWrapper<Grade> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Grade::getGradeName,gradeName);
        Grade result = gradeMapper.selectOne(queryWrapper);
        return new GlobalResponse(0,result,"成功");
    }

 

2.3 更新操作

@PutMapping("updateEntity")
    public GlobalResponse updateByEntity(@RequestBody Grade grade,@RequestParam String gradeName){
        LambdaUpdateWrapper<Grade> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Grade::getGradeName,gradeName);
        gradeMapper.update(grade,updateWrapper);
        return new GlobalResponse(0,null,"更新成功");
    }

端怎麼傳都可以,只傳遞一個gradeName也可以呢,那麼預設其他欄位就是null,但是更新到資料庫中,其他欄位不會被null替代

先把資料庫中得“大一大一大一“修改回“大一”,前端傳送不完整得body

可以看到gradeName被更新,但是float_col不會更新為null 

另一種更新方法:單獨更新某個欄位:使用set可以更新多個欄位,lambda方式支援流式操作

@PutMapping("updateEntity")
    public GlobalResponse updateByEntity(@RequestParam String gradeName){
        LambdaUpdateWrapper<Grade> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Grade::getGradeName,gradeName).set(Grade::getFloatCol,10.1);
        gradeMapper.update(null,updateWrapper);
        return new GlobalResponse(0,null,"更新成功");
    }

updateById

@PutMapping("updateById")
    public GlobalResponse updateById(){
        Grade grade = new Grade();
        grade.setId(1);
        grade.setGradeName("dayi");
        grade.setFloatCol((float) 0.01);
        gradeMapper.updateById(grade);
        return new GlobalResponse(0,null,"更新成功");
    }

那麼我們剛才知道使用gradeMapper.update(Entity)更新得時候,如果Entity中得欄位存在null,不會將null覆蓋資料庫中對應得欄位的,那麼使用updateById是不是也不會覆蓋呢?我們驗證一下:

更新前:

 其中,grade物件中的floatCol屬性為null:

@PutMapping("updateById")
    public GlobalResponse updateById(){
        Grade grade = new Grade();
        grade.setId(1);
        grade.setFloatCol((float) 1.222222);
        gradeMapper.updateById(grade);
        return new GlobalResponse(0,null,"更新成功");
    }

結論:null不會覆蓋任何值,所以如果要真實修改庫中的欄位,如果用於修改資料庫的物件的欄位有null值存在會導致之前存在的資料沒有被覆蓋

嘗試寫個校驗,使用@Valid

@Data
public class Person {
    @NotBlank(message = "名字不能為空")
    String name;
    int age;
}
@PutMapping("test")
    public String test(@Valid @RequestBody Person person, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            return bindingResult.getFieldError().getDefaultMessage();
        }
        System.out.println(person);
        return person.toString();
    }

 pom中新增,這裡有個坑就是如果沒有新增hibernate-validator的話@NotBlank不會生效

    <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.13.Final</version>
    </dependency>

三、使用mapper.xml

 

 

 

 

相關文章