springboot集成MyBatisPlus、自定义xml、打印SQL、分页多条件查询、条件构造器Wrapper、@EnumValue、乐观锁、@KeySequence

之前一直用MyBatis,现在刚入职的公司在用MyBatisPlus,所以自己记录一下。
使用感想就是:简单的单表增删改查用MyBatisPlus,复杂的多表操作使用自定义SQL。工具始终是工具,要自己权衡利弊,没有任何工具是绝对的!MyBatisPlus = JPA简单的单表增删改查操作 + MyBatis复杂的多表操作xml里写SQL

  1. 创建一个普通的springboot项目,pom.xml引入相关依赖
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--lombok可选-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                        	<!--不打包lombok,因为lombok只在编译时使用,编译后就没用了-->
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
  1. application.yml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&userSSL=false
    username: root
    password: 123456

mybatis-plus:
  #类型别名
  type-aliases-package: com.fu.mybatisplus.entity
  # 扫描通用枚举包,需要配置@EnumValue注解使用
  type-enums-package: com.fu.mybatisplus.enums
  #读取xml
  mapper-locations: classpath:mapper/*.xml
  configuration:
    #打印sql
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  #设置全局配置
  global-config:
    db-config:
      #设置表的统一前缀(可以不设置)
      table-prefix: t_
      #统一主键生成策略,一般就2种策略一个是自增auto,一个是雪花算法assign_id(可以不设置)
      id-type: auto
  1. MybatisPlusDemoApplication启动类扫描Mapper
@MapperScan("com.fu.mybatisplusdemo.dao")
@SpringBootApplication
public class MybatisPlusDemoApplication {

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

}
  1. Easy Code生成Controller、Service、ServiceImpl、Dao、Mapper、Entity(Pojo)
    在这里插入图片描述
    在这里插入图片描述
    默认的模板生成的代码有些问题,这些可以自己去改模板生成代码,这里不再赘述,可以自己去看看。
    在这里插入图片描述
    这些都是生成的一步到位后端代码,要是你还懂前端,去弄弄前端的模板,直接前后端一步到位!
  2. 实体类
    SexEnum性别枚举类
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;

@Getter
public enum SexEnum {
    MAN(0,"男"),
    WOMEN(1,"女");

    @EnumValue
    private Integer sex;

    @JsonValue
    private String sexCN;

    SexEnum(Integer sex, String sexCN) {
        this.sex = sex;
        this.sexCN = sexCN;
    }
}

User实体类

@Data   //lombok生成Set、Get、equals、hashCode、toString
@TableName("user")  //解决数据库表名和实体类名不一致的问题,如表名叫t_user,则@TableName("t_user")
@EqualsAndHashCode(callSuper=false) //lombok重写Equals和HashCode方法,因为继承了Model类callSuper表示是否考虑父类的方法
public class User extends Model<User> {     //Model<实体类>,这个Model的作用非常奇怪,居然可以用来直接调用数据库的数据,如:User user = new User();user.setName("姓名");Assert.assertTrue(user.insert());居然可以直接这样调用!!!
    //主键,value的值表示数据库的值,比如:数据库里的主键不叫id,叫uid,则value = "uid"
    //IdType.AUTO数据库ID自增(确保数据库设置了ID自增,否则无效),IdType.ASSIGN_ID雪花算法(默认)
    @TableId(type = IdType.AUTO,value = "id")    //使用数据库自增主键,解决数据库没有设置自增主键的问题
    private Long id;
    //姓名
    @TableField(value = "name") //解决数据库字段名和变量名不一致的问题如数据库叫p_name,则value = "p_name"
    private String name;
    //性别(0:男 1:女)用枚举类型存储
    private SexEnum sex;
    //年龄
    private Integer age;
    //邮箱
    private String email;
    //密码
    @TableField(select = false)     //查询时不返回该字段
    private String pwd;
    //修改时间
    @TableField(fill = FieldFill.INSERT_UPDATE)     //修改数据时刷新时间
    private Date updateTime;
    //创建时间
    @TableField(fill = FieldFill.INSERT)    //新增数据时创建时间
    @JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")    //JSON格式转换,把日期转成指定字符串格式
    private Date createTime;

	//逻辑删除(0:否 1:是)
	//物理删除SQL语句为:DELETE FROM user WHERE id=?
	//设置@TableLogic逻辑删除注解SQL语句为:UPDATE user SET is_deleted=1 WHERE id=? AND is_deleted=0
    @TableLogic//逻辑删除标识
    private int isDeleted;
}
  1. UserDao.java
public interface UserDao extends BaseMapper<User> {
    /**
     * 自定义接口使用xml的sql语句进行查询
     * @param id
     * @return
     */
    User selectOneByIdUser(@Param("id") Long id);
    
	/**
     * 自定义接口使用xml的sql语句进行批量新增
     * @param userList 用户列表
     * @return
     */
	boolean insertBatch(@Param("userList") List<User> userList);
}
  1. UserDao.xml
<?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.fu.mybatisplusdemo.dao.UserDao">

    <resultMap type="com.fu.mybatisplusdemo.entity.User" id="UserMap">
        <result property="id" column="id" jdbcType="BIGINT"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="age" column="age" jdbcType="INTEGER"/>
        <result property="email" column="email" jdbcType="VARCHAR"/>
        <result property="isDeleted" column="is_deleted" jdbcType="INTEGER"/>
    </resultMap>
    
    <sql id="userSql">
        id,`name`,age,email,is_deleted
    </sql>

    <!--自定义sql-->
    <select id="selectOneByIdUser" resultMap="UserMap">
        select <include refid="userSql"/> from user where id = #{id}
    </select>

	<!--批量新增-->
	<insert id="insertBatch" parameterType="java.util.List">
        insert into user (<include refid="userSql"/>)
        VALUES
        <foreach collection="userList" item="item" separator=",">
            (#{item.id},#{item.name},#{item.gae},#{item.email})
        </foreach>
    </insert>
</mapper>
  1. UserService
public interface UserService extends IService<User> {
    User selectOneByIdUser(Long id);
}
  1. UserServiceImpl
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    @Resource
    private UserDao userDao;

    @Override
    public User selectOneByIdUser(Long id) {
        return userDao.selectOneByIdUser(id);
    }
}
  1. UserController
@RestController
@RequestMapping("user")
public class UserController {
    @Resource
    private UserService userService;

	/**
     * 自定义接口
     * @param id
     * @return
     */
    @GetMapping("/one")
    public User selectOneByIdUser(@RequestParam Long id) {
        return userService.selectOneByIdUser(id);
    }

    /**
     * 分页查询所有数据
     *
     * @param page 分页对象
     * @param user 查询实体
     * @return 所有数据
     */
    @GetMapping
    public Page<User> selectAll(Page<User> page, User user) {
        return this.userService.page(page, new QueryWrapper<>(user));
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public User selectOne(@PathVariable Serializable id) {
        return this.userService.getById(id);
    }

    /**
     * 新增数据
     *
     * @param user 实体对象
     * @return 新增结果
     */
    @PostMapping
    public boolean insert(@RequestBody User user) {
        return this.userService.save(user);
    }

    /**
     * 修改数据
     *
     * @param user 实体对象
     * @return 修改结果
     */
    @PutMapping
    public boolean update(@RequestBody User user) {
        return this.userService.updateById(user);
    }

    /**
     * 删除数据
     *
     * @param idList 主键结合
     * @return 删除结果
     */
    @DeleteMapping
    public boolean delete(@RequestParam("idList") List<Long> idList) {
        return this.userService.removeByIds(idList);
    }
}

postman测试MyBatisPlus生成的接口

  1. localhost:88/user就是调用分页查询的方法
  2. localhost:88/user/1就是调用根据id查询一条数据的方法

测试自定义的方法

  1. localhost:88/user/one?id=1就是调用自定义的方法使用xml里面的sql去获取数据库的数据

分页多条件查询

第一种方法(不推荐)

Controller
	//Dto直接放Page<Objecy>
	@PostMapping("/page" )
    public R getPage(@RequestBody UserDto userDto) {
        return R.ok(userService.getPage(userDto.getPage(),userDto));
    }
Dto
@Data
@EqualsAndHashCode(callSuper=false)
public class UserDto extends User{

	/**
	 * 分页
	 */
	private Page<User> page;
	
	/**
	 * 结束时间
	 */
	private LocalDateTime endTime;
}
Service
public interface UserService extends IService<User> {
	Page<User> getPage(Page<User> page, UserDto userDto);
}

	//impl
	@Override
	public Page<User> getPage(Page<User> page, UserDto userDto) {
		return UserMapper.getPage(page,userDto);
	}
Mapper
@Mapper
public interface UserMapper extends BaseMapper<User> {
	Page<User> getPage(@Param("page") Page<User> page, @Param("userDto") UserDto userDto);
}
Mapper.xml
	<select id="getPage" resultMap="BaseResultMap">
		SELECT <include refid="Base_Column_List"/> FROM user
		<where>
			<if test="userDto.createStartTime != null">
				AND	create_time <![CDATA[>=]]> #{userDto.createTime}
			</if>
			<if test="qualityTestingStandardEntityDto.createEndTime != null">
				AND	create_time <![CDATA[<=]]> #{userDto.endTime}
			</if>
		</where>
		ORDER BY create_time DESC
	</select>
PostMan调用接口

在这里插入图片描述

第二种方法(推荐)

主要区别在于Dto

Controller
	//把分页参数放到Dto
	@GetMapping("/page" )
    public R getPage(UserDto userDto) {
        return R.ok(userService.getPage(userDto));
    }
Dto
@Data
@EqualsAndHashCode(callSuper=false)
public class UserDto extends User{
	/**
	 * 分页:当前页
	 */
	private long current;
	/**
	 * 分页:每页数量
	 */
	private long size;
	/**
	 * 结束时间
	 */
	private LocalDateTime endTime;
}
Service
public interface UserService extends IService<User> {
	Page<User> getPage(UserDto userDto);
}

	//impl
	@Override
	public Page<User> getPage(UserDto userDto) {
		return userMapper.getPage(Page.of(userDto.getCurrent(),userDto.getSize()),userDto);
	}
PostMan测试

在这里插入图片描述

分页、乐观锁插件

新增MyBatisPlusConfig配置类

/**
 * MyBatisPlus分页、乐观锁插件
 */
@Configuration
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //添加分页插件。addInnerInterceptor设置数据库类型
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //添加乐观锁插件(个人感觉一般般不是很好用)
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

新增Product实体类
在这里插入图片描述

@Data
@TableName("product")
public class Product {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer price;
    @Version//标识乐观锁版本号字段
    private Integer version;
}

修改UserDao或者UserMapper

@Repository//防止@Autowired注解在idea报红波浪线
public interface UserMapper extends BaseMapper<User> {

    /**
     * 自定义分页:通过年龄查询用户信息并分页
     * @param page MyBatisPlus所提供的分页对象,必须位于第一个参数
     * @param age 年龄
     * @return
     */
    Page<User> selectPageVo(@Param("page") Page<User> page,@Param("age") Integer age);
}

mapper.xml

<?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.fu.mybatisplus.mapper.UserMapper">
    <select id="selectPageVo" resultType="User">
        select id,`name`,`age`,email from user where age > #{age}
    </select>
</mapper>

新增ProductMapper

@Repository
public interface ProductMapper extends BaseMapper<Product> {}

新增分页、乐观锁插件测试类

@SpringBootTest
public class MyBatisPlusPluginsTest {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ProductMapper productMapper;

    /**
     * 自带分页插件
     */
    @Test
    public void page(){
        //current会减1
        Page<User> page = new Page<>(2,3);
        System.out.println(userMapper.selectPage(page, null));
        System.out.println("获取当前页数据"+page.getRecords());
        System.out.println("获取总页数"+page.getPages());
        System.out.println("获取总记录数"+page.getTotal());
        System.out.println("获取有没有下一页"+page.hasNext());
        System.out.println("获取有没有上一页"+page.hasPrevious());
    }

    /**
     * 自定义分页功能
     */
    @Test
    public void pageVo(){
        Page<User> page = new Page<>(1,3);
        userMapper.selectPageVo(page,25);
        System.out.println("获取当前页数据"+page.getRecords());
        System.out.println("获取总页数"+page.getPages());
        System.out.println("获取总记录数"+page.getTotal());
        System.out.println("获取有没有下一页"+page.hasNext());
        System.out.println("获取有没有上一页"+page.hasPrevious());
    }

    /**
     * 前提数据库有Product表和实体类
     * 使用了乐观锁插件(个人感觉一般般不是很好用,建议能用redis(jedis)就用redis吧)
     */
    @Test
    public void product(){
        //小李查询商品价格
        Product productLi = productMapper.selectById(1L);
        System.out.println("小李查询的商品价格为:"+productLi.getPrice());
        //小王查询商品价格
        Product productWang = productMapper.selectById(1L);
        System.out.println("小王查询的商品价格为:"+productWang.getPrice());
        //小李将商品价格加50
        productLi.setPrice(productLi.getPrice() + 50);
        productMapper.updateById(productLi);
        //小王将商品价格减30
        productWang.setPrice(productWang.getPrice() - 30);
        int result = productMapper.updateById(productWang);
        if(result == 0){
            //操作失败,重试
            Product productNew = productMapper.selectById(1L);
            productNew.setPrice(productNew.getPrice()-30);
            productMapper.updateById(productNew);
        }
        //老板查询商品价格,预期是120
        Product productBoss = productMapper.selectById(1L);
        System.out.println("老板查询的商品价格为:"+productBoss.getPrice());
    }
}

MyBatisPlus简单操作方法

@SpringBootTest
public class MyBatisPlusTest {
    @Autowired//防止@Autowired注解在idea报红波浪线需要在XXXMapper接口上面加上@Repository注解
    private UserMapper userMapper;

    /**
     * 查询
     */
    @Test
    public void getUsers() {
        //通过ID查询
        System.out.println("通过单个ID查询:" + userMapper.selectById(1L));

        //通过多个ID查询
        //SELECT id,name,age,email,create_time,update_time FROM user WHERE id IN ( ? , ? , ? )
        List<Long> list = Arrays.asList(10L, 20L, 30L);
        List<User> users = userMapper.selectBatchIds(list);
        users.forEach(System.out::println);

        //通过Map查询,map是条件(不推荐)
        //SELECT id,name,age,email,create_time,update_time FROM user WHERE name = ? AND age = ?
        Map<String,Object> map = new HashMap<>();
        map.put("name","Meta");
        map.put("age",26);
        List<User> selectByMap = userMapper.selectByMap(map);
        selectByMap.forEach(System.out ::println);

        //通过条件构造器查询一个list集合,如果没有条件,则设置为null
        //SELECT id,name,age,email,create_time,update_time FROM user
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }

    /**
     * 插入(不推荐)
     */
    @Test
    public void setUser() {
        User user = new User();
//        user.setId(2L);
        user.setName("靓仔");
        user.setAge(26);
        user.setPwd("123456");
        user.setEmail("12345@xx.com");
        int result = userMapper.insert(user);
        System.out.println("结果:" + result);
        System.out.println("id:" + user.getId());
    }

    /**
     * 删除
     */
    @Test
    public void delUser() {
        //通过ID删除
        //物理删除:DELETE FROM user WHERE id=?
        //如果实体类设置了@TableLogic逻辑删除注解则SQL语句为:UPDATE user SET is_deleted=1 WHERE id=? AND is_deleted=0
        System.out.println("通过单个ID删除" + userMapper.deleteById(1L));


        //通过Map批量删除,map里面放的是条件(不推荐)
        //DELETE FROM user WHERE name = ? AND age = ?
        Map<String, Object> map = new HashMap<>();
        map.put("name", "靓仔");
        map.put("age", 26);
        System.out.println("通过Map批量删除,map里面放的是条件:" + userMapper.deleteByMap(map));


        //通过多个id批量删除
        List<Long> list = Arrays.asList(10L, 20L, 30L);
        System.out.println("通过多个id批量删除" + userMapper.deleteBatchIds(list));
    }

    /**
     * 修改(不推荐)
     */
    @Test
    public void updateUser() {
        User user = new User();
        user.setId(2L);
        //没有设置Age则不进行修改
        user.setName("MetaA");
        user.setPwd("123456");
        user.setEmail("12345@xx.com");
        userMapper.updateById(user);
    }

	/**
     * 查询总条数
     */
    @Test
    public void getCount(){
        //SELECT COUNT( * ) FROM user
        System.out.println("无条件查询所有数据条数:"+userService.count());
    }

    /**
     * 批量插入数据
     */
    @Test
    public void saveUser(){
        List<User> list = new ArrayList<>();
        for (int i = 0;i<=10;i++){
            User user = new User();
            user.setName("ybc"+i);
            user.setAge(20+i);
            list.add(user);
        }
        //INSERT INTO user ( id, name, age, create_time, update_time ) VALUES ( ?, ?, ?, ?, ? )
        //INSERT SQL语句执行了10次。。。
        System.out.println("批量插入数据是否成功:"+userService.saveBatch(list));
    }
}

条件构造器Wrapper

@SpringBootTest
public class MyBatisPlusWrapperTest {
    @Autowired
    private UserMapper userMapper;

    /**
     * 条件查询(不推荐)
     */
    @Test
    public void whereQuery() {
        //SELECT id,name,age,email,create_time,update_time,is_deleted FROM user WHERE is_deleted=0 AND (name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
        //查询用户姓名包含a,年龄在20-30之间,邮箱信息不为null的用户信息
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.like("name", "a")
                .between("age", 20, 30)
                .isNotNull("email");
        List<User> users = userMapper.selectList(qw);
        users.forEach(System.out::println);
    }

    /**
     * 排序(不推荐)
     */
    @Test
    public void orderByQuery() {
        //SELECT id,name,age,email,create_time,update_time,is_deleted FROM user WHERE is_deleted=0 ORDER BY age DESC,id ASC
        //查询用户信息,按照年龄降序排序,若年龄相同,则按照id升序排序
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.orderByDesc("age")
                .orderByAsc("id");
        List<User> users = userMapper.selectList(qw);
        users.forEach(System.out::println);
    }

    /**
     * 删除(不推荐)
     */
    @Test
    public void delete() {
        //因为设置了逻辑删除注解,所以是update操作
        //UPDATE user SET is_deleted=1 WHERE is_deleted=0 AND (email IS NULL)
        //删除邮箱地址为null的用户信息
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.isNull("email");
        System.out.println("删除邮箱地址为null的用户信息:" + userMapper.delete(qw));
    }

    /**
     * 修改(不推荐,推荐使用UpdateWrapper)
     */
    @Test
    public void update() {
        //UPDATE user SET name=?, email=?, update_time=? WHERE is_deleted=0 AND (age > ? AND name LIKE ? OR email IS NULL)
        //将年龄大于20并且用户名包含a或邮箱地址为null的用户信息修改
        QueryWrapper<User> qw = new QueryWrapper<>();
        //gt表示大于
        qw.gt("age", 20)
                .like("name", "a")
                .or()//默认是and,拼接or要手动加上or()方法
                .isNull("email");
        User user = new User();
        user.setName("小明");
        user.setEmail("12345@qq.com");
        System.out.println("将年龄大于20并且用户名包含a或邮箱地址为null的用户信息修改" + userMapper.update(user, qw));
    }

    /**
     * 条件优先级(不推荐)
     */
    @Test
    public void updatePriority() {
        //UPDATE user SET name=?, email=?, update_time=? WHERE is_deleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL))
        //将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改
        //lambda中的条件优先执行
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.like("name", "a")
                .and(i -> i.gt("age", 20)
                        .or()
                        .isNull("email"));
        User user = new User();
        user.setName("小红");
        user.setEmail("54321@qq.com");
        System.out.println("将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改" + userMapper.update(user, qw));
    }

    /**
     * 组装select字句(不推荐)
     */
    @Test
    public void query() {
        //SELECT name,name,email FROM user WHERE is_deleted=0
        //查询用户的用户名、年龄、邮箱信息
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.select("name","age","email");
        List<Map<String, Object>> maps = userMapper.selectMaps(qw);
        maps.forEach(System.out::println);
    }

    /**
     * 子查询(不推荐)
     */
    @Test
    public void subQuery() {
        //SELECT id,name,age,email,create_time,update_time,is_deleted FROM user WHERE is_deleted=0 AND (id IN (select id from user where id < 5))
        //查询id小于5的用户信息
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.inSql("id","select id from user where id < 5");
        List<User> users = userMapper.selectList(qw);
        users.forEach(System.out::println);
    }

    /**
     * 使用UpdateWrapper实现修改功能(推荐)
     */
    @Test
    public void updateWrapper() {
        //将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改
        UpdateWrapper<User> uw = new UpdateWrapper<>();
        uw.like("name","a")
        .and(i ->i.gt("age",20)
        .or()
        .isNull("email"));
        uw.set("name","小黑")
        .set("email","abc@it.com");
        System.out.println("将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改"+userMapper.update(null, uw));
    }

    /**
     * 条件组装查询(不推荐)
     */
    @Test
    public void conditionalAssembly(){
        //SELECT id,name,age,email,create_time,update_time,is_deleted FROM user WHERE is_deleted=0 AND (name LIKE ? AND age <= ?)
        String name = "a";
        Integer ageBegin = null;
        Integer ageEnd = 30;
        QueryWrapper<User> qw = new QueryWrapper<>();
        if (StringUtils.hasLength(name)){
            //hasLength判断字符串是否不为空字符串、不为null、不为空白符
            qw.like("name",name);
        }
        if (ageBegin != null){
            //ge表示大于等于
            qw.ge("age",ageBegin);
        }
        if (ageEnd != null){
            //le表示小于等于
            qw.le("age",ageEnd);
        }
        List<User> users = userMapper.selectList(qw);
        users.forEach(System.out::println);
    }

    /**
     * 条件组装查询,可以少写很多if判断。但是字段名容易写错(不推荐)
     */
    @Test
    public void conditionalAssembly2(){
        //SELECT id,name,age,email,create_time,update_time,is_deleted FROM user WHERE is_deleted=0 AND (name LIKE ? AND age <= ?)
        String name = "a";
        Integer ageBegin = null;
        Integer ageEnd = 30;
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.like(StringUtils.hasLength(name),"name","a")
        .ge(ageBegin != null,"age",ageBegin)
        .le(ageEnd != null,"age",ageEnd);
        List<User> users = userMapper.selectList(qw);
        users.forEach(System.out::println);
    }

    /**
     * 条件组装查询LambdaQueryWrapper,可以防止字段名写错(推荐)
     */
    @Test
    public void lambdaQueryWrapper(){
        //SELECT id,name,age,email,create_time,update_time,is_deleted FROM user WHERE is_deleted=0 AND (name LIKE ? AND age <= ?)
        String name = "a";
        Integer ageBegin = null;
        Integer ageEnd = 30;
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.hasLength(name),User::getName,name)
        .ge(ageBegin != null,User::getAge,ageBegin)
        .le(ageEnd != null,User::getAge,ageEnd);
        List<User> users = userMapper.selectList(lqw);
        users.forEach(System.out::println);
    }

    /**
     * 条件组装修改lambdaUpdateWrapper,可以防止字段名写错(推荐)
     */
    @Test
    public void lambdaUpdateWrapper(){
        //UPDATE user SET name=?,email=? WHERE is_deleted=0 AND (name LIKE ? AND (age > ? OR email IS NOT NULL))
        //将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改
        LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
        luw.like(User::getName,"a")
        .and(i->i.gt(User::getAge,20)
        .or()
        .isNotNull(User::getEmail));
        luw.set(User::getName,"小黑")
        .set(User::getEmail,"abc@12345.com");
        System.out.println("LambdaUpdateWrapper将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改"+userMapper.update(null, luw));
    }
}

通用枚举

@SpringBootTest
public class MyBatisPlusEnumTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void sexEnum(){
        User user = new User();
        user.setName("admin");
        user.setAge(33);
        user.setSex(SexEnum.MAN);//需要在枚举类设置@EnumValue注解,并在yml配置扫描枚举类包
        int result = userMapper.insert(user);
        System.out.println(result);
    }
}

ORACLE使用@KeySequence序列号作为主键的用法

配置类

目前支持以下数据库序列生成
在这里插入图片描述

@Configuration
public class MyBatisPlusConfig {
    @Bean
    public IKeyGenerator keyGenerator() {
    	//对应的数据库主键生成策略
        return new OracleKeyGenerator();
    }
}

实体类

@Data
//SEQ_MS_SFFP是Oracle里设置好的序列名称,dbType是数据库类型
@KeySequence(value = "SEQ_MS_SFFP", dbType = DbType.ORACLE)
public class MsSffp {
	//TableId的type必须设置为IdType.INPUT
    @TableId(type = IdType.INPUT)
    private Long sbxh;
}

用法

	@Autowired
    MsSffpMapper msSffpMapper;

	public void m(){
		MsSffp msSffp = new MsSffp();
		//不用setSbxh。
		msSffpMapper.insert(msSffp);
	}
MyBatis-Plus 是一个基于 MyBatis 的增强工具,它提供了一些便捷的方法和功能来简化开发过程。要实现多组条件查询,可以使用 MyBatis-Plus 提供的 Lambda 查询和 QueryWrapper 来构建查询条件。 1. Lambda 查询: 使用 Lambda 查询可以使用实体类的属性名作为查询条件,可以方便地组合多个查询条件。 ```java import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 示例代码 public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { public List<User> searchUsers(String username, Integer age) { LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(); queryWrapper.like(User::getUsername, username) .eq(User::getAge, age); return baseMapper.selectList(queryWrapper); } } ``` 2. QueryWrapper 查询: QueryWrapperMyBatis-Plus 提供的功能强大的查询构造器,它可以拼接多个查询条件,并支持复杂的查询逻辑。 ```java import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 示例代码 public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { public List<User> searchUsers(String username, Integer age) { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.like("username", username) .eq("age", age); return baseMapper.selectList(queryWrapper); } } ``` 以上是使用 MyBatis-Plus 实现多组条件查询的两种常见方式。可以根据具体的需求选择合适的方式进行查询。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值