Giter VIP home page Giter VIP logo

copycat's Introduction

Mybatis-Plus

新项目地址:

mybatis-plus-ext

https://github.com/photowey/mybatis-plus-ext

  • 发布 v1.0.0
  • 开发 v1.1.0

单表查询扩展(Copycat)

基于 Mybatis-Plus , 通过自定义条件注解,实现自动包装 QueryWrapper 查询对象

v1.0.0

  • 实现了对 Mybatis-plus 单表查询的扩展

v1.1.0

  • 升级 Mybatis-Plus 版本
  • 升级 Spring 版本
  • 优化包引用
    • mybatis-plus-core
    • mybatis-plus-extension
    • spring-core
    • slf4j-api
  • 优化 OrderBy 注解
    • 新增 一个 OrderBy 处理类型 {@link com.photowey.copycat.criteria.enums.HandleOrderByEnum}
      来区分是静态的排序, 还是根据前端传入的字段动态排序
      {@link com.photowey.copycat.service.UserServiceTest#testQueryByCriteriaOrderByStatic}
  • 时间查询(@TimeStamp)
    • 支持 {@link java.time.LocalDateTime}
    • 依然默认采用 {@link java.util.Date}

v1.2.0

  • 时间查询(@TimeStamp)
    • 支持 {@link java.time.LocalDate}
    • 支持 {@link java.time.LocalTime}
    • 支持 {@link java.time.ZonedDateTime}
    • 依然默认采用 {@link java.util.Date}

v1.3.0

  • 增加 ShutdownHook 手动释放 Processor 缓存
    • 添加 {@link com.photowey.copycat.criteria.hook.CopycatShutdownHook}

v1.3.1

  • 合并-PR
  • 增加 License 文件头
  • 更新 test 模块

v1.3.2

  • 新增 Select 注解(静态属性)
  • 新增 DynacmicSelect 注解

一、需求描述

  • 1.1.使用QueryWrapper对较少条件进行查询,如下:
List<User> userList=userMapper.selectList(
        new QueryWrapper<User>()
        .lambda()
        .ge(User::getAge,18)
        );
  • 1.2.往往在真实情况下,前端一般有很多的查询条件传入后台,此时不得不手动的去包装我们的查询条件,如下:
List<User> userList = this.userService.list(
    new QueryWrapper<User>()
            .lambda()
            .ge(User::getAge, 18)
            .likeLeft(User::getName, "ext")
            .eq(User::getEmail, "[email protected]")
            ...
);

二、轻量级 引用

<properties>
    <mybatis-plus.version>3.4.0</mybatis-plus.version>
    <spring-core.version>5.2.8.RELEASE</spring-core.version>
    <slf4j-log.version>1.7.25</slf4j-log.version>
</properties>

<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-core</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-extension</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>

<!-- spring-core -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring-core.version}</version>
</dependency>

<!-- log -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j-log.version}</version>
</dependency>

三、实现原理

3.1.基于自定义注解通过反射来实现

四、查询使用

4.1.自定义查询对象(XxxQuery)

继承 内置的 AbstractQuery

/**
 * XxxQuery
 *
 * @author WcJun
 * @date 2019/05/13
 * {@link com.photowey.copycat.criteria.query.AbstractQuery}
 */
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class XxxQuery extends AbstractQuery<User> implements Serializable {

    private static final long serialVersionUID = -4887537311252782223L;

    /**
     * 用户标识
     * 自动给 QueryWrapper 添加如下的语句:
     * queryWrapper.eq(null != value, columnName, value);
     */
    @Eq(alias = "id")
    private Long userId;
}

4.2.内置抽象的 AbstractQuery

{@link com.photowey.copycat.criteria.query.AbstractQuery}

AbstractQuery

/**
 * 抽象查询对象
 *
 * @author WcJun
 * @date 2019/05/12
 */
public abstract class AbstractQuery<T> extends PaginationQuery {

    // WRAPPER

    /**
     * 通过注解自动包装查询 Wrapper
     *
     * @return
     * @see {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    public QueryWrapper<T> autoWrapper() {
        return CriteriaAnnotationProcessorAdvisor.advise(this, new QueryWrapper<T>());
    }

    // PAGE

    /**
     * 如果需要分页的话
     * 获取分页对象
     *
     * @return IPage
     * @see {@link com.baomidou.mybatisplus.core.metadata.IPage}
     */
    public IPage populatePage() {
        return new Page(this.pageNo, this.pageSize);
    }
}

4.3.分页参数(PaginationQuery)

{@link com.photowey.copycat.criteria.query.PaginationQuery}

/**
 * 分页参数
 *
 * @author WcJun
 * @date 2019/05/12
 */
public abstract class PaginationQuery {

    /**
     * 当前页(从自然页 1 开始)
     */
    protected Integer pageNo = 1;
    /**
     * 每页展示数量 默认 20
     */
    protected Integer pageSize = 20;

    // ================================================

    public Integer getPageNo() {

        if (null != pageNo && pageNo < 1) {
            return 1;
        }

        return null == pageNo ? 1 : pageNo;
    }

    public Integer getPageSize() {

        if (null != pageSize && pageSize < 1) {
            return 1;
        }

        return null == pageSize ? 10 : pageSize;
    }

    public void setPageNo(Integer pageNo) {
        this.pageNo = pageNo;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
}

五、测试

5.1.测试等于(@Eq)

/**
 * 测试 @Eq
 * {@link com.photowey.copycat.criteria.annotaion.Eq}
 */
@Test
public void testQueryByEq() {
    UserQuery userQuery = new UserQuery().setUserId(1L);
    User user = this.userService.getOne(userQuery.autoWrapper());
    Assert.assertEquals("查询错误", "Jone", user.getName());
}

5.2.测试时间(@Timestamp)

一些场景下,前端时间传值,可能是采用的是时间戳 - 因此 就有了 @Timestamp 的使用场景

/**
 * 测试 Timestamp
 * {@link com.photowey.copycat.criteria.annotaion.Timestamp}
 * {@link java.time.LocalDateTime}
 * ==>  Preparing: SELECT id,name,age,email,birth_day FROM user WHERE (age >= ? AND birth_day > ?) ORDER BY age DESC
 * ==> Parameters: 20(Integer), 2019-05-11T10:00(LocalDateTime)
 *
 * @since 1.1.0
 */
@Test
public void testQueryByTimestampGe() throws ParseException {
    String birthDayStr = "2019-05-12 10:00:00";
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date birthDay = format.parse(birthDayStr);
    // 模拟前端传参
    UserQuery userQuery = new UserQuery().setAge(20).setBirthDayGe(birthDay);
    
    List<User> users = this.userService.list(userQuery.autoWrapper());
    Assert.assertEquals(3, users.size());
    users.forEach(System.out::println);
}

/**
 * 测试 Timestamp
 * {@link com.photowey.copycat.criteria.annotaion.Timestamp}
 * {@link java.time.LocalDate}
 * ==>  Preparing: SELECT id,name,age,email,birth_day FROM user WHERE (age >= ? AND birth_day > ?) ORDER BY age DESC
 * ==> Parameters: 20(Integer), 2019-05-11(LocalDate)
 *
 * @since 1.2.0
 */
@Test
public void testQueryByCriteriaTimestampByLocalDate() {
    UserQuery userQuery = new UserQuery().setAge(20).setBirthDayTimestampLocalDate(1557540000000L);
    List<User> users = this.userService.list(userQuery.autoWrapper());
    users.forEach(System.out::println);
}

/**
 * 测试 Timestamp
 * {@link com.photowey.copycat.criteria.annotaion.Timestamp}
 * {@link java.time.LocalTime}
 * ==>  Preparing: SELECT id,name,age,email,birth_day FROM user WHERE (age >= ? AND birth_day > ?) ORDER BY age DESC
 * ==> Parameters: 20(Integer), 10:00(LocalTime)
 *
 * @since 1.2.0
 */
@Test
public void testQueryByCriteriaTimestampByLocalTime() {
    UserQuery userQuery = new UserQuery().setAge(20).setBirthDayTimestampLocalTime(1557540000000L);
    List<User> users = this.userService.list(userQuery.autoWrapper());
    users.forEach(System.out::println);
}

/**
 * 测试 Timestamp
 * {@link com.photowey.copycat.criteria.annotaion.Timestamp}
 * {@link java.time.ZonedDateTime}
 * ==>  Preparing: SELECT id,name,age,email,birth_day FROM user WHERE (age >= ? AND birth_day > ?) ORDER BY age DESC
 * ==> Parameters: 20(Integer), 2019-05-11T10:00+08:00[Asia/Shanghai](ZonedDateTime)
 *
 * @since 1.2.0
 */
@Test
public void testQueryByCriteriaTimestampByZonedDateTime() {
    UserQuery userQuery = new UserQuery().setAge(20).setBirthDayTimestampZonedDateTime(1557540000000L);
    List<User> users = this.userService.list(userQuery.autoWrapper());
    users.forEach(System.out::println);
}

具体见 : 测试类(UserServiceTest) {@link com.photowey.copycat.service.UserServiceTest}

欢迎 发送PR

copycat's People

Contributors

dependabot[bot] avatar photowey avatar wxibm333 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

copycat's Issues

分页解析问题

使用了.autoWrapper()之后进行的分页查询,解析出来的sql会是select count(1) from (select ........ from a where 1=1) 相当于走了个子查询,这个有啥办法可以处理吗?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.