6

Mybatis-Plus入门实践 - Naylor

 2 years ago
source link: https://www.cnblogs.com/Naylor/p/16164441.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Mybatis-Plus 简称 MP ,是 Mybatis 的增强工具,提供了一批开箱即用的功能、特性、接口、注解,简化了应用程序访问数据库的相关操作,完善了Mybatis作为ORM仅能做到半自动的不足,提高了开发人员的开发效率。

MP是社区产品,当前源代码在Github上面进行维护,基于Apache2.0开源协议,可放心在商业项目上使用。

  • TableName:表名注解,标识实体类对应的数据库表
  • TableId:主键注解,标识此属性对应数据库中的主键字段
  • TableField:字段注解(非主键)

CRUD接口

MP的宗旨就是简化编码,所以一般而言,都是尽量直接使用 service 层接口。若确需手写 sql , 在 mapper 层中编写注解,当然也可以编写xml,更加推荐注解方式,因为xml方式下类型推导和引用会失效。

以下内容摘抄自官网

Service层接口

// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

saveOrUpdate

// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

remove

// 根据 entity 条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

update

// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

count

// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);

chain

// 链式查询 普通
QueryChainWrapper<T> query();
// 链式查询 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery();

// 示例:
query().eq("column", value).one();
lambdaQuery().eq(Entity::getId, value).list();

Mapper层接口

insert

// 插入一条记录
int insert(T entity);

delete

// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

update

// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

select

// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

需要添加的maven依赖:

  • mysql-connector-java:Mysql 官方的jdbc驱动器
  • spring-boot-starter-jdbc:数据源自动配置;提供一个JdbcTemplate 简化使用;事物管理。
  • druid-spring-boot-starter:数据库连接池管理
  • mybatis-plus-boot-starter:MP的依赖,引入MP之后无需再次引入mybatis。
  • springfox-boot-starter:swagger3.0,接口自测工具

jdbc是Java提供的一种标准规范,具体的实现由各个数据库厂商去实现。对开发者来说屏蔽了不同数据库之间的区别,可以使用相同的方式(Java API)去操作不同的数据库。两个设备之间要进行通信需要驱动,不同数据库厂商对jdbc的实现类就是去连接数据库的驱动,如mysql-connector-java连接mysql数据库的驱动。

数据源配置

spring:
  application:
    name: mp-service
  datasource:
    #url: jdbc:mysql://192.168.1.152:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    #username: root
    #password: 123456
    #driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      #或 spring.datasource.url
      url: jdbc:mysql://192.168.1.152:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
      #或 spring.datasource.username
      username: dev-luyubo
      #或 spring.datasource.password
      password: KjJhAjXJ
      #或 spring.datasource.driver-class-name
      driver-class-name: com.mysql.cj.jdbc.Driver

#配置mp日志打印到输出。此配置若和logging.level.org.apache.ibatis.logging: debug 同时存在,后者将不生效
#mybatis-plus:
#configuration:
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


logging:
  level:
    com.ramble: debug
    #配置mp日志打印到项目配置的日志实现框架,默认为logback
    org.apache.ibatis.logging: debug




SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint NOT NULL COMMENT '主键ID',
  `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '姓名',
  `age` int NULL DEFAULT NULL COMMENT '年龄',
  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱',
  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'Jone', 18, '[email protected]', NULL);
INSERT INTO `user` VALUES (2, 'Jack', 20, '[email protected]', NULL);
INSERT INTO `user` VALUES (3, 'Tom', 28, '[email protected]', NULL);
INSERT INTO `user` VALUES (4, 'Sandy', 21, '[email protected]', NULL);
INSERT INTO `user` VALUES (5, 'Billie', 24, '[email protected]', NULL);
SET FOREIGN_KEY_CHECKS = 1;




实体model


@TableName("user")
@Data
@Accessors(chain = true)
public class User implements Serializable {
    @TableId
    private Long id;
    @TableField("name")
    private String name;
    private Integer age;
    private String email;
}

repository

若使用 Repository 注解,需手动设置扫描路径,建议使用 Mapper 注解


@Mapper
public interface UserMapper extends BaseMapper<User> {
}

service

UserService:


public interface UserService  extends IService<User> {
    List<User> findList(UserConditionDto condition);
    Page<User> search(UserConditionDto condition);
}

UserServiceImpl:


@Slf4j
@Service
@AllArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    /**
     * 获取列表数据
     *
     * @param condition
     * @return
     */
    @Override
    public List<User> findList(UserConditionDto condition) {
        return this.list(this.buildQueryWrapper(condition));
    }
    /**
     * 搜索数据
     *
     * @param condition
     * @return
     */
    @Override
    public Page<User> search(UserConditionDto condition) {
        QueryWrapper<User> query = this.buildQueryWrapper(condition);
        Page<User> page = new Page<>(condition.getPageNum(), condition.getPageSize());
        return this.page(page, query);
    }
    /**
     * 构造 queryWrapper
     *
     * @param condition
     * @return
     */
    private QueryWrapper<User> buildQueryWrapper(UserConditionDto condition) {
        Assert.notNull(condition, CommonErrorMsgEnum.PARAM_IS_NULL.toString());
        QueryWrapper<User> query = new QueryWrapper<>();
        //name 模糊匹配
        if (StringUtils.hasText(condition.getName())) {
            query.like("name", condition.getName());
        }
        if (StringUtils.hasText(condition.getEmail())) {
            query.like("email", condition.getEmail());
        }
        //id 精确查找
        if (null != condition.getId() && condition.getId() > 0) {
            query.eq("id", condition.getId());
        }
        //时间范围
        if (null != condition.getStartTime()) {
            if (null != condition.getEndTime()) {
                query.in("create_time", condition.getStartTime(), condition.getEndTime());
            } else {
                LocalDateTime now = LocalDateTime.now();
                query.in("create_time", condition.getStartTime(), now);
            }
        } else {
            if (null != condition.getEndTime()) {
                query.ge("create_time", condition.getEndTime());
            }
        }
        //默认时间倒序
        query.orderByDesc("create_time");
        return query;
    }
}




    /**
     * 构造查询包装器,lambda 链式查询,不用手写字段名称,通过数据库实体映射
     *
     * @param param
     * @return
     */
    private LambdaQueryWrapper<TagInfo> buildQueryWrapper(TagInfoParam param) {
        LambdaQueryWrapper<TagInfo> query = new LambdaQueryWrapper<>();
        if (null == param) {
            return query;
        }
        query.like(StringUtils.isNotEmpty(param.getTagCode()), TagInfo::getTagCode, param.getTagCode())
                .like(StringUtils.isNotEmpty(param.getTagName()), TagInfo::getTagName, param.getTagName())
                .like(StringUtils.isNotEmpty(param.getTagSimpleName()), TagInfo::getTagSimpleName, param.getTagSimpleName())
                .eq(null != param.getTagId(), TagInfo::getId, param.getTagId()).eq(TagInfo::getIsDeleted, 0);
        return query;
    }



Mapper层注解语法

  • script
  • where
  • foreach
  • choose-when-otherwise(if-else ;switch-case-default)

package com.ramble.mybatisplus.repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ramble.mybatisplus.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Set;
@Mapper
public interface UserMapper extends BaseMapper<User> {
    @Select({
            "<script>",
            " select * from user ",
            "<where>",
            "<if test=\" user.id !=null and user.id !=0 \" >",
            "   and id=#{user.id}",
            "</if>",
            "</where>",
            "</script>"
    })
    User findUserById(@Param("user") User user);
    @Select({
            "<script>",
            " select * from user ",
            "<where>",
            "   <foreach collection='ids' item='item' open=' id in (' close=')' separator=','>",
            "       #{item}",
            "   </foreach>",
            "</where>",
            "</script>"
    })
    List<User> findUserByIds(@Param("ids") Set<Long> ids);
    @Select({
            "<script>",
            " select * from user ",
            "<where>",
            "<choose>",
            "   <when  test=\" user.name !=null and user.name !='' \" >",
            "       and name like CONCAT('%' , #{user.name} , '%')",
            "   </when>",
            "   <otherwise>",
            "       and name =#{currentUserName} ",
            "   </otherwise>",
            "</choose>",
            "</where>",
            "</script>"
    })
    List<User> findUser(@Param("user") User user, @Param("currentUserName") String currentUserName);
}


https://gitee.com/naylor_personal/ramble-spring-cloud/tree/master/mybatisplus

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK