【mybatis-plus的增删改查】

  • Post author:
  • Post category:其他




二、mybatis-plus与spring boot



2.1 数据库与表

创建一个数据库:


create database mytest;

创建一个表:

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
	id BIGINT(20) NOT NULL AUTO_INCREMENT 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)
);

其对应的数据库 Data 脚本如下:

DELETE FROM user;

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');



2.2 引入依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-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.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>



2.3 配置properties文件

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=123456



2.4 实体类

@Data
@TableName(value = "user")//指定表名
public class User {
    @TableId(value = "id", type = IdType.AUTO) //这个要搭配着表的自增主键使用才可以。
    private Long id;
    private String name;
    private Integer age;
    private String email;
}



2.5 mapper

public interface UserMapper extends BaseMapper<User> {

}



2.6 启动类

@SpringBootApplication
//你自己写的UserMapper类的位置
@MapperScan("com.example.mybatisplusdemo.mapper")
public class MybatisPlusDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusDemoApplication.class, args);
    }

}



2.7 测试类

@SpringBootTest
class MybatisPlusDemoApplicationTests {
    @Autowired
    private UserMapper userMapper;

    @Test
    void contextLoads() {
        System.out.println(("----- selectAll method test ------"));
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }

}



2.8 结果

----- selectAll method test ------
User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)



2.9 MapperScan和ComponentScan

1、首先@MapperScan和@ComponentScan都是扫描包

2、@ComponentScan是组件扫描注解,用来扫描@Controller @Service @Repository这类,主要就是定义扫描的路径从中找出标志了需要装配的类到Spring容器中

3、@MapperScan 是扫描mapper类的注解,就不用在每个mapper类上加@MapperScan(或者@Mapper)了

这两个注解是可以同时使用的。



2.10 @Mapper 、@MapperScan、 @Repository使用


1、@Mapper


作用:用在接口类上,在编译之后会生成相应的接口实现类,是mybatis的注解。

位置:对应的某个接口类上面

如果想要每个接口都要变成实现类,那么需要在每个接口类上加上@Mapper注解,比较麻烦,解决这个问题用 @MapperScan 。


2、@MapperScan


作用:扫描指定包下所有的接口类,然后所有接口在编译之后都会生成相应的实现类

位置:是在SpringBoot启动类上面添加,

SpringBootApplication 启动类

@MapperScan(“com.springboot.mapper”)
@SpringBootApplication
public class SpringBootApplication {
    public static void main(String[] args) {
    	SpringApplication.run(SpringBootApplication.class, args);
    }
}

添加 @MapperScan(“com.springboot.mapper”) 注解以后,扫描 com.springboot.mapper 包下面所有的接口类,在编译之后都会生成相应的实现类。


2.1、@MapperScan 扫描多个包


@MapperScan 也支持多个包的扫描。

@MapperScan({“com.emp.mapper”,“com.dep.mapper”})
@SpringBootApplication
public class SpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplication.class, args);
    }
}


2.2、 @MapperScan 使用表达式,来扫描的包和其子包下面的类

@SpringBootApplication
@MapperScan({“com..mapper","org..mapper”})
public class SpringBootApplication {
    public static void main(String[] args) {
    	SpringApplication.run(SpringBootApplication.class, args);
    }
}


3、@Repository


@Repository注解是Spring的注解,把类注册成一个bean。使用了此注解在mapper上后,需要在主启动类添加@MapperScan才能编译之后会生成相应的接口实现类。

@Repository用不用无所谓。如果不用, 使用@Autowire注入mapper接口时, 会出现以下爆红情况. 说什么Could not autowire. No beans of xxxxxxxx。但是其实并不会影响运行, 如果强迫症看到爆红就是不舒服, 可以在每个mapper接口上打上注解 @Repository.

@Repository注解是Spring的注解,使用该注解和@Autowired注解,就不会出现爆红的情况了,原因很简单,因为@Repository注解是Spring的注解,把当前类注册成一个bean了。


4、总结:


@Mapper 是对单个类的注解。是单个操作。

@MapperScan 是对整个包下的所有的接口类的注解。是批量的操作。

@Repository是spring注解需要和@MapperScan配合使用。



三、spring boot注解



3.1 @PathVariable、@RequestParam

使用@RequestParam时,URL是这样的:http://host:port/path?参数名=参数值

使用@PathVariable时,URL是这样的:http://host:port/path/参数值

它们还可以混用。

实例:

@RequestMapping(value = "/email/{name}", method = RequestMethod.GET)
@ResponseBody
public String getEmail(@PathVariable("name") String name, @RequestParam("age") Integer age){
    log.info("url:/user/email/{}?age={}", name, age);
    return userService.getEmail(name, age);
}

但是注意,它会与下面的方法冲突:

@RequestMapping(value = "/email/{age}", method = RequestMethod.GET)
@ResponseBody
public String getEmail1(@PathVariable("age") Integer age, @RequestParam("name") String name){
    log.info("url:/user/email/{}?name={}", age, name);
    return userService.getEmail(name, age);
}

对于请求:http://localhost:8080/user/email/21?name=Jack,servlet不知道该分发给谁来处理。


ERROR: Ambiguous handler methods mapped for '/user/email/21': {public java.lang.String com.example.mybatisplusdemo.controller.UserController.getEmail1(java.lang.Integer,java.lang.String), public java.lang.String com.example.mybatisplusdemo.controller.UserController.getEmail(java.lang.String,java.lang.Integer)}]

在注释掉

getEmail1

方法后,请求的url如下,结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7FCd9TS1-1637809906588)(D:\fangtuoqian1\Documents\工作学习记录\image-20211124181804203.png)]



3.2 @SpringBootTest

该注解用于测试类上。如果不加这个注解,测试类无法自动注入bean。



二、mybatis-plus增删改查



2.1 查

@Test
public void test1() {
    userManagerImpl.list().forEach(System.out::println);
}

@Test
public void test2() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.ge("age", 23);
    userManagerImpl.list(wrapper).forEach(System.out::println);
}

@Test
public void test3() {
    List<Map<String, Object>> maps = userManagerImpl.listMaps();
    for (Map<String, Object> map: maps
         ) {
        for (Map.Entry<String, Object> entry: map.entrySet()
             ) {
            System.out.printf("%s=%s, ", entry.getKey(), entry.getValue());
        }
        System.out.println();
    }
}

@Test
public void test4() {
    Map<String, Object> map = new HashMap<>(16);
    map.put("age", 21);
    map.put("name", "Sandy");
    List<User> users = userManagerImpl.listByMap(map);
    users.forEach(System.out::println);
}

@Test
public void test5() {
    //返回的是id,为Long型
    userManagerImpl.listObjs().forEach(System.out::println);
}



2.2 增

@Test
public void test6() {
    User user = new User();
    user.setName("ZhouSb");
    user.setAge(29);
    user.setEmail("zhoupeigen@qq.com");

    boolean save = userManagerImpl.save(user);
    System.out.println(save);
}

@Test
public void test7() {
    List<User> users = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        User user = new User();
        user.setName("test_" + (i+1));
        user.setAge(i+20);
        user.setEmail("test" + (i+1) + "@qq.com");
        users.add(user);
    }

    boolean saveBatch = userManagerImpl.saveBatch(users);
    log.info("{}", saveBatch);
}

@Test
public void test7_() {
    List<User> users = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        User user = new User();
        //从这里可以看出,即使是自增主键,如果指定了id值,那么最终的id是以指定的为准
        //如果没有指定,则自增
        user.setId((long) (i+6));
        user.setName("test_" + (i+1));
        user.setAge(i+20);
        user.setEmail("test" + (i+1) + "@qq.com");
        users.add(user);
    }

    boolean saveBatch = userManagerImpl.saveBatch(users);
    log.info("{}", saveBatch);

    userManagerImpl.list().forEach(System.out::println);
}



2.3 改

@Test
public void test8() {
    //sql : update user set email="test1@163.com" where name="test_1";
    //使用条件构造器实现
    UpdateWrapper<User> wrapper = new UpdateWrapper<>();
    wrapper.eq("name", "test_1");

    User user = new User();
    user.setEmail("test1@163.com");

    boolean update = userManagerImpl.update(user, wrapper);
    log.info("{}", update);

    userManagerImpl.list().forEach(System.out::println);
}

@Test
public void test9() {
    //sql : update user set email="test2@gmail.com" where name="test_2";
    //使用条件构造器实现
    UpdateWrapper<User> wrapper = new UpdateWrapper<>();
    //用于添加where条件
    wrapper.eq("name", "test_2");
    //注意这个只用于设置sql语句的set部分
    wrapper.setSql("email='test2@gmail.com'");

    userManagerImpl.update(wrapper);

    userManagerImpl.list().forEach(System.out::println);
}



2.4 删

@Test
public void test10() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name", "ZhouSb");
    System.out.println(userManagerImpl.remove(wrapper));

    userManagerImpl.list().forEach(System.out::println);
}

@Test
public void test11() {
    User user = new User();
    user.setId(8L);
    user.setName("");
    user.setAge(0);
    user.setEmail("");

    //可以看到这个方法只关注id,其余属性存不存在,是多少都无关
    System.out.println(userManagerImpl.removeById(user));
    //id为8的数据已被删除,尽管它的name,age,email都与上面的对象不相同
    userManagerImpl.list().forEach(System.out::println);
}



版权声明:本文为weixin_43036882原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。