精华内容
下载资源
问答
  • Mybatis-Plus和Mybatis的区别

    万次阅读 多人点赞 2019-04-01 11:09:50
    Mybatis-Plus是一个Mybatis的增强工具,它在Mybatis的基础上做了增强,却不做改变。我们在使用Mybatis-Plus之后既可以使用Mybatis-Plus的特有功能,又能够正常使用Mybatis的原生功能。Mybatis-Plus(以下简称MP)是为...

    原文:https://blog.csdn.net/qq_34508530/article/details/88943858
    在这里插入图片描述
    在这里插入图片描述
    .
    .
    .
    .
    .
    .

    区别一

    如果Mybatis Plus是扳手,那Mybatis Generator就是生产扳手的工厂。
    通俗来讲——
    MyBatis:一种操作数据库的框架,提供一种Mapper类,支持让你用java代码进行增删改查的数据库操作,省去了每次都要手写sql语句的麻烦。但是!有一个前提,你得先在xml中写好sql语句,是不是很麻烦?于是有下面的↓
    Mybatis Generator:自动为Mybatis生成简单的增删改查sql语句的工具,省去一大票时间,两者配合使用,开发速度快到飞起。至于标题说的↓
    Mybatis Plus:国人团队苞米豆在Mybatis的基础上开发的框架,在Mybatis基础上扩展了许多功能,荣获了2018最受欢迎国产开源软件第5名,当然也有配套的↓
    Mybatis Plus Generator:同样为苞米豆开发,比Mybatis Generator更加强大,支持功能更多,自动生成Entity、Mapper、Service、Controller等
    总结:
    数据库框架:Mybatis Plus > Mybatis
    代码生成器:Mybatis Plus Generator > Mybatis Generator

    .
    .
    .
    .
    .

    区别二

    Mybatis-Plus是一个Mybatis的增强工具,它在Mybatis的基础上做了增强,却不做改变。我们在使用Mybatis-Plus之后既可以使用Mybatis-Plus的特有功能,又能够正常使用Mybatis的原生功能。Mybatis-Plus(以下简称MP)是为简化开发、提高开发效率而生,但它也提供了一些很有意思的插件,比如SQL性能监控、乐观锁、执行分析等。

    Mybatis虽然已经给我们提供了很大的方便,但它还是有不足之处,实际上没有什么东西是完美的,MP的存在就是为了稍稍弥补Mybatis的不足。在我们使用Mybatis时会发现,每当要写一个业务逻辑的时候都要在DAO层写一个方法,再对应一个SQL,即使是简单的条件查询、即使仅仅改变了一个条件都要在DAO层新增一个方法,针对这个问题,MP就提供了一个很好的解决方案,之后我会进行介绍。另外,MP的代码生成器也是一个很有意思的东西,它可以让我们避免许多重复性的工作,下面我将介绍如何在你的项目中集成MP。
    .
    .
    .
    .
    .

    一、 集成步骤↓:(首先,你要有个spring项目)

    集成依赖,pom中加入依赖即可,不多说:
    Java代码 收藏代码

    <!-- mybatis mybatis-plus mybatis-spring mvc -->  
    <dependency>  
        <groupId>com.baomidou</groupId>  
        <artifactId>mybatis-plus</artifactId>  
        <version>${mybatis-plus.version}</version>  
    </dependency>  
    <dependency>  
        <groupId>org.apache.velocity</groupId>  
        <artifactId>velocity-engine-core</artifactId>  
        <version>2.0</version>  
    </dependency>  
    

    说明:笔者使用的版本为:mybatis-plus.version=2.1-gamma,上边的代码中有两个依赖,第一个是mybatis-plus核心依赖,第二个是使用代码生成器时需要的模板引擎依赖,若果你不打算使用代码生成器,此处可不引入。
    注意:mybatis-plus的核心jar包中已集成了mybatis和mybatis-spring,所以为避免冲突,请勿再次引用这两个jar包。

    .
    .
    .

    二、 在spring中配置MP:

    <bean id="sqlSessionFactory"  
        class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">  
        <!-- 配置数据源 -->  
        <property name="dataSource" ref="dataSource" />  
        <!-- 自动扫描 Xml 文件位置 -->  
        <property name="mapperLocations" value="classpath*:com/ds/orm/mapper/**/*.xml" />  
        <!-- 配置 Mybatis 配置文件(可无) -->  
        <property name="configLocation" value="classpath:mybatis-config.xml" />  
        <!-- 配置包别名,支持通配符 * 或者 ; 分割 -->  
        <property name="typeAliasesPackage" value="com.ds.orm.model" />  
        <!-- 枚举属性配置扫描,支持通配符 * 或者 ; 分割 -->  
        <!-- <property name="typeEnumsPackage" value="com.baomidou.springmvc.entity.*.enums"   
            /> -->  
        <!-- 以上配置和传统 Mybatis 一致 -->  
      
        <!-- MP 全局配置注入 -->  
        <property name="globalConfig" ref="globalConfig" />  
    </bean>  
    
    <bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">  
        <!-- 主键策略配置 -->  
        <!-- 可选参数 AUTO->`0`("数据库ID自增") INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局唯一ID")   
            UUID->`3`("全局唯一ID") -->  
        <property name="idType" value="2" />  
        <!-- 数据库类型配置 -->  
        <!-- 可选参数(默认mysql) MYSQL->`mysql` ORACLE->`oracle` DB2->`db2` H2->`h2`   
            HSQL->`hsql` SQLITE->`sqlite` POSTGRE->`postgresql` SQLSERVER2005->`sqlserver2005`   
            SQLSERVER->`sqlserver` -->  
        <property name="dbType" value="mysql" />  
        <!-- 全局表为下划线命名设置 true -->  
        <property name="dbColumnUnderline" value="true" />  
        <property name="sqlInjector">  
            <bean class="com.baomidou.mybatisplus.mapper.AutoSqlInjector" />  
        </property>  
    </bean>  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <description>DAO接口所在包名,Spring会自动查找其下的类</description>  
        <property name="basePackage" value="com.ds.orm.mapper" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />  
    </bean>  
    <!-- 乐观锁插件 -->  
    <bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor" />  
      
    <!-- xml mapper热加载 sqlSessionFactory:session工厂 mapperLocations:mapper匹配路径   
        enabled:是否开启动态加载 默认:false delaySeconds:项目启动延迟加载时间 单位:秒 默认:10s sleepSeconds:刷新时间间隔   
        单位:秒 默认:20s -->  
    <bean class="com.baomidou.mybatisplus.spring.MybatisMapperRefresh">  
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />  
        <constructor-arg name="mapperLocations"  
            value="classpath*:com/ds/orm/mapper/*/*.xml" />  
        <constructor-arg name="delaySeconds" value="10" />  
        <constructor-arg name="sleepSeconds" value="20" />  
        <constructor-arg name="enabled" value="true" />  
    </bean>  
      
    <!-- 事务 -->  
    <bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>  
    <tx:annotation-driven transaction-manager="transactionManager"  
        proxy-target-class="true" />  
        
     注意:只要做如上配置就可以正常使用mybatis了,不要重复配置。MP的配置和mybatis一样,都是配置一个sqlSessionFactory,只是现在所配置的类在原本的SqlSessionFactoryBean基础上做了增强。插件等配置请按需取舍。
    插件配置,按需求配置就可以,此处把可以配置的插件都列了出来,具体的请看代码注释:
    
    <configuration>  
        <settings>  
            <setting name="logImpl" value="SLF4J" />  
            <!-- 字段为空时仍调用model的set方法或map的put方法 -->  
            <setting name="callSettersOnNulls" value="true" />  
        </settings>  
        <plugins>  
            <!-- | 分页插件配置 | 插件提供二种方言选择:1、默认方言 2、自定义方言实现类,两者均未配置则抛出异常! | overflowCurrent   
                溢出总页数,设置第一页 默认false | optimizeType Count优化方式 ( 版本 2.0.9 改为使用 jsqlparser 不需要配置   
                ) | -->  
            <!-- 注意!! 如果要支持二级缓存分页使用类 CachePaginationInterceptor 默认、建议如下!! -->  
            <plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor">  
                <property name="dialectType" value="mysql" />  
                <!--<property name="sqlParser" ref="自定义解析类、可以没有" />  
                <property name="localPage" value="默认 false 改为 true 开启了 pageHeper 支持、可以没有" />  
                <property name="dialectClazz" value="自定义方言类、可以没有" /> -->  
            </plugin>  
      
            <!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->  
            <plugin interceptor="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">  
                <property name="maxTime" value="2000" />  
                <!--SQL是否格式化 默认false -->  
                <property name="format" value="true" />  
            </plugin>  
      
            <!-- SQL 执行分析拦截器 stopProceed 发现全表执行 delete update 是否停止运行 该插件只用于开发环境,不建议生产环境使用。。。 -->  
            <plugin interceptor="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">  
                <property name="stopProceed" value="false" />  
            </plugin>  
        </plugins>  
    </configuration>  
    

    注意:执行分析拦截器和性能分析推荐只在开发时调试程序使用,为保证程序性能和稳定性,建议在生产环境中注释掉这两个插件。
    数据源:(此处使用druid)

    <!-- 配置数据源 -->  
    <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  
        <!--     <property name="driverClassName" value="${jdbc.driverClassName}" /> -->  
        <property name="url" value="${jdbc.url}" />   
        <property name="username" value="${jdbc.username}" />   
        <property name="password" value="${jdbc.password}" />   
        <property name="initialSize" value="${jdbc.initialSize}" />   
        <property name="minIdle" value="${jdbc.minIdle}" />   
        <property name="maxActive" value="${jdbc.maxActive}" />   
        <property name="maxWait" value="${jdbc.maxWait}" />   
        <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />   
        <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />   
        <property name="validationQuery" value="${jdbc.validationQuery}" />   
        <property name="testWhileIdle" value="${jdbc.testWhileIdle}" />   
        <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />   
        <property name="testOnReturn" value="${jdbc.testOnReturn}" />   
        <property name="removeAbandoned" value="${jdbc.removeAbandoned}" />   
        <property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />   
        <!--     <property name="logAbandoned" value="${jdbc.logAbandoned}" /> -->  
        <property name="filters" value="${jdbc.filters}" />  
        <!-- 关闭abanded连接时输出错误日志 -->  
        <property name="logAbandoned" value="true" />  
        <property name="proxyFilters">  
            <list>  
                <ref bean="log-filter"/>  
            </list>  
        </property>  
      
        <!-- 监控数据库 -->  
        <!-- <property name="filters" value="stat" /> -->  
        <!--     <property name="filters" value="mergeStat" />-->  
    </bean>  
    

    到此,MP已经集成进我们的项目中了,下面将介绍它是如何简化我们的开发的。
    .
    .
    .

    **

    三、 简单的CURD操作↓:

    **
    假设我们有一张user表,且已经建立好了一个与此表对应的实体类User,我们来介绍对user的简单增删改查操作。
    建立DAO层接口。我们在使用普通的mybatis时会建立一个DAO层接口,并对应一个xml用来写SQL。在这里我们同样要建立一个DAO层接口,但是若无必要,我们甚至不需要建立xml,就可以进行资源的CURD操作了,我们只需要让我们建立的DAO继承MP提供的BaseMapper<?>即可:

    public interface UserMapper extends BaseMapper { }
    然后在我们需要做数据CURD时,像下边这样就好了:
    Java代码 收藏代码
    // 初始化 影响行数
    int result = 0;
    // 初始化 User 对象
    User user = new User();

    // 插入 User (插入成功会自动回写主键到实体类)
    user.setName(“Tom”);
    result = userMapper.insert(user);

    // 更新 User
    user.setAge(18);
    result = userMapper.updateById(user);//user要设置id哦,具体的在下边我会详细介绍

    // 查询 User
    User exampleUser = userMapper.selectById(user.getId());

    // 查询姓名为‘张三’的所有用户记录
    List userList = userMapper.selectList(
    new EntityWrapper().eq(“name”, “张三”)
    );

    // 删除 User
    result = userMapper.deleteById(user.getId());

    方便吧?如果只使用mybatis可是要写4个SQL和4个方法喔,当然了,仅仅上边这几个方法还远远满足不了我们的需求,请往下看:

    .
    .

    **

    多条件分页查询:

    **
    // 分页查询 10 条姓名为‘张三’、性别为男,且年龄在18至50之间的用户记录

    List<User> userList = userMapper.selectPage(  
            new Page<User>(1, 10),  
            new EntityWrapper<User>().eq("name", "张三")  
                    .eq("sex", 0)  
                    .between("age", "18", "50")  
    );  
    

    /**等价于SELECT *
    *FROM sys_user
    *WHERE (name=‘张三’ AND sex=0 AND age BETWEEN ‘18’ AND ‘50’)
    *LIMIT 0,10
    */
    .
    .
    .
    下边这个,多条件构造器。其实对于条件过于复杂的查询,笔者还是建议使用原生mybatis的方式实现,易于维护且逻辑清晰,如果所有的数据操作都强行使用MP,就失去了MP简化开发的意义了。所以在使用时请按实际情况取舍,在这里还是先介绍一下。

    public Page<T> selectPage(Page<T> page, EntityWrapper<T> entityWrapper) {  
      if (null != entityWrapper) {  
          entityWrapper.orderBy(page.getOrderByField(), page.isAsc());//排序  
      }  
      page.setRecords(baseMapper.selectPage(page, entityWrapper));//将查询结果放入page中  
      return page;  
    }  
    

    ** 条件构造一(上边方法的entityWrapper参数):**

    public void testTSQL11() {  
        /* 
         * 实体带查询使用方法  输出看结果 
         */  
        EntityWrapper<User> ew = new EntityWrapper<User>();  
        ew.setEntity(new User(1));  
        ew.where("user_name={0}", "'zhangsan'").and("id=1")  
                .orNew("user_status={0}", "0").or("status=1")  
                .notLike("user_nickname", "notvalue")  
                .andNew("new=xx").like("hhh", "ddd")  
                .andNew("pwd=11").isNotNull("n1,n2").isNull("n3")  
                .groupBy("x1").groupBy("x2,x3")  
                .having("x1=11").having("x3=433")  
                .orderBy("dd").orderBy("d1,d2");  
        System.out.println(ew.getSqlSegment());  
    }  
    

    .
    .
    .
    ** 条件构造二(同上):**

    int buyCount = selectCount(Condition.create()
    .setSqlSelect(“sum(quantity)”)
    .isNull(“order_id”)
    .eq(“user_id”, 1)
    .eq(“type”, 1)
    .in(“status”, new Integer[]{0, 1})
    .eq(“product_id”, 1)
    .between(“created_time”, startDate, currentDate)
    .eq(“weal”, 1));
    自定义条件使用entityWrapper:

    List selectMyPage(RowBounds rowBounds, @Param(“ew”) Wrapper wrapper);

    SELECT * FROM user ${ew.sqlSegment} *注意:此处不用担心SQL注入,MP已对ew做了字符串转义处理。 其实在使用MP做数据CURD时,还有另外一个方法,AR(ActiveRecord ),很简单,让我们的实体类继承MP提供Model<?>就好了,这和我们常用的方法可能会有些不同,下边简单说一下吧:*

    .
    .
    .
    .
    //实体类
    @TableName(“sys_user”) // 注解指定表名
    public class User extends Model {

    … // fields

    … // getter and setter

    .
    .

    / 指定主键 /*
    @Override
    protected Serializable pkVal() { //一定要指定主键哦
    return this.id;
    }
    }
    .
    .
    .
    下边就是CURD操作了:

    // 初始化 成功标识
    boolean result = false;
    // 初始化 User
    User user = new User();

    // 保存 User
    user.setName(“Tom”);
    result = user.insert();

    // 更新 User
    user.setAge(18);
    result = user.updateById();

    // 查询 User
    User exampleUser = t1.selectById();

    // 查询姓名为‘张三’的所有用户记录
    List userList1 = user.selectList(
    new EntityWrapper().eq(“name”, “张三”)
    );

    // 删除 User
    result = t2.deleteById();

    // 分页查询 10 条姓名为‘张三’、性别为男,且年龄在18至50之间的用户记录
    List userList = user.selectPage(
    new Page(1, 10),
    new EntityWrapper().eq(“name”, “张三”)
    .eq(“sex”, 0)
    .between(“age”, “18”, “50”)
    ).getRecords();
    就是这样了,可能你会说MP封装的有些过分了,这样做会分散数据逻辑到不同的层面中,难以管理,使代码难以理解。其实确实是这样,这就需要你在使用的时候注意一下了,在简化开发的同时也要保证你的代码层次清晰,做一个战略上的设计或者做一个取舍与平衡。
    .
    .
    .
    .
    .
    .

    **

    其实上边介绍的功能也不是MP的全部啦,下边介绍一下MP最有意思的模块——代码生成器。

    **

    步骤↓:
    如上边所说,使用代码生成器一定要引入velocity-engine-core(模板引擎)这个依赖。
    准备工作:
    选择主键策略,就是在上边最开始时候我介绍MP配置时其中的这项配置,如果你不记得了,请上翻!MP提供了如下几个主键策略: 值 描述
    IdType.AUTO ----------数据库ID自增
    IdType.INPUT ----------用户输入ID
    IdType.ID_WORKER---------- 全局唯一ID,内容为空自动填充(默认配置)
    IdType.UUID ----------全局唯一ID,内容为空自动填充
    MP默认使用的是ID_WORKER,这是MP在Sequence的基础上进行部分优化,用于产生全局唯一ID。

    表及字段命名策略选择,同上,还是在那个配置中。下边这段复制至MP官方文档:
    在MP中,我们建议数据库表名采用下划线命名方式,而表字段名采用驼峰命名方式。

    这么做的原因是为了避免在对应实体类时产生的性能损耗,这样字段不用做映射就能直接和实体类对应。当然如果项目里不用考虑这点性能损耗,那么你采用下滑线也是没问题的,只需要在生成代码时配置dbColumnUnderline属性就可以。

    建表(命名规则依照刚才你所配置的,这会影响生成的代码的类名、字段名是否正确)。
    执行下边的main方法,生成代码:

    import java.util.HashMap;  
    import java.util.Map;  
      
    import com.baomidou.mybatisplus.generator.AutoGenerator;  
    import com.baomidou.mybatisplus.generator.InjectionConfig;  
    import com.baomidou.mybatisplus.generator.config.DataSourceConfig;  
    import com.baomidou.mybatisplus.generator.config.GlobalConfig;  
    import com.baomidou.mybatisplus.generator.config.PackageConfig;  
    import com.baomidou.mybatisplus.generator.config.StrategyConfig;  
    import com.baomidou.mybatisplus.generator.config.rules.DbType;  
    import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;  
      
    /** 
     * <p> 
     * 代码生成器演示 
     * </p> 
     */  
    public class MpGenerator {  
      
        /** 
         * <p> 
         * MySQL 生成演示 
         * </p> 
         */  
        public static void main(String[] args) {  
            AutoGenerator mpg = new AutoGenerator();  
      
            // 全局配置  
            GlobalConfig gc = new GlobalConfig();  
            gc.setOutputDir("D://");  
            gc.setFileOverride(true);  
            gc.setActiveRecord(true);// 不需要ActiveRecord特性的请改为false  
            gc.setEnableCache(false);// XML 二级缓存  
            gc.setBaseResultMap(true);// XML ResultMap  
            gc.setBaseColumnList(false);// XML columList  
        // .setKotlin(true) 是否生成 kotlin 代码  
            gc.setAuthor("Yanghu");  
      
            // 自定义文件命名,注意 %s 会自动填充表实体属性!  
            // gc.setMapperName("%sDao");  
            // gc.setXmlName("%sDao");  
            // gc.setServiceName("MP%sService");  
            // gc.setServiceImplName("%sServiceDiy");  
            // gc.setControllerName("%sAction");  
            mpg.setGlobalConfig(gc);  
      
            // 数据源配置  
            DataSourceConfig dsc = new DataSourceConfig();  
            dsc.setDbType(DbType.MYSQL);  
            dsc.setTypeConvert(new MySqlTypeConvert(){  
                // 自定义数据库表字段类型转换【可选】  
                @Override  
                public DbColumnType processTypeConvert(String fieldType) {  
                    System.out.println("转换类型:" + fieldType);  
            // 注意!!processTypeConvert 存在默认类型转换,如果不是你要的效果请自定义返回、非如下直接返回。  
                    return super.processTypeConvert(fieldType);  
                }  
            });  
            dsc.setDriverName("com.mysql.jdbc.Driver");  
            dsc.setUsername("root");  
            dsc.setPassword("521");  
            dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mybatis-plus?characterEncoding=utf8");  
            mpg.setDataSource(dsc);  
      
            // 策略配置  
            StrategyConfig strategy = new StrategyConfig();  
        // strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意  
            strategy.setTablePrefix(new String[] { "tlog_", "tsys_" });// 此处可以修改为您的表前缀  
            strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略  
            // strategy.setInclude(new String[] { "user" }); // 需要生成的表  
            // strategy.setExclude(new String[]{"test"}); // 排除生成的表  
            // 自定义实体父类  
            // strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");  
            // 自定义实体,公共字段  
            // strategy.setSuperEntityColumns(new String[] { "test_id", "age" });  
            // 自定义 mapper 父类  
            // strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");  
            // 自定义 service 父类  
            // strategy.setSuperServiceClass("com.baomidou.demo.TestService");  
            // 自定义 service 实现类父类  
            // strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");  
            // 自定义 controller 父类  
            // strategy.setSuperControllerClass("com.baomidou.demo.TestController");  
            // 【实体】是否生成字段常量(默认 false)  
            // public static final String ID = "test_id";  
            // strategy.setEntityColumnConstant(true);  
            // 【实体】是否为构建者模型(默认 false)  
            // public User setName(String name) {this.name = name; return this;}  
            // strategy.setEntityBuilderModel(true);  
            mpg.setStrategy(strategy);  
      
            // 包配置  
            PackageConfig pc = new PackageConfig();  
            pc.setParent("com.baomidou");  
            pc.setModuleName("test");  
            mpg.setPackageInfo(pc);  
      
            // 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】  
            InjectionConfig cfg = new InjectionConfig() {  
                @Override  
                public void initMap() {  
                    Map<String, Object> map = new HashMap<String, Object>();  
                    map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");  
                    this.setMap(map);  
                }  
            };  
      
            // 自定义 xxList.jsp 生成  
            List<FileOutConfig> focList = new ArrayList<FileOutConfig>();  
            focList.add(new FileOutConfig("/template/list.jsp.vm") {  
                @Override  
                public String outputFile(TableInfo tableInfo) {  
                    // 自定义输入文件名称  
                    return "D://my_" + tableInfo.getEntityName() + ".jsp";  
                }  
            });  
            cfg.setFileOutConfigList(focList);  
            mpg.setCfg(cfg);  
      
        // 调整 xml 生成目录演示  
             focList.add(new FileOutConfig("/templates/mapper.xml.vm") {  
                @Override  
                public String outputFile(TableInfo tableInfo) {  
                    return "/develop/code/xml/" + tableInfo.getEntityName() + ".xml";  
                }  
            });  
            cfg.setFileOutConfigList(focList);  
            mpg.setCfg(cfg);  
      
            // 关闭默认 xml 生成,调整生成 至 根目录  
            TemplateConfig tc = new TemplateConfig();  
            tc.setXml(null);  
            mpg.setTemplate(tc);  
      
            // 自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改,  
            // 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置,也可以自定义模板名称  
            // TemplateConfig tc = new TemplateConfig();  
            // tc.setController("...");  
            // tc.setEntity("...");  
            // tc.setMapper("...");  
            // tc.setXml("...");  
            // tc.setService("...");  
            // tc.setServiceImpl("...");  
        // 如上任何一个模块如果设置 空 OR Null 将不生成该模块。  
            // mpg.setTemplate(tc);  
      
            // 执行生成  
            mpg.execute();  
      
            // 打印注入设置【可无】  
            System.err.println(mpg.getCfg().getMap().get("abc"));  
        }  
      
    }  
    

    说明:中间的内容请自行修改,注释很清晰。
    成功生成代码,将生成的代码拷贝到你的项目中就可以了,这个东西节省了我们大量的时间和精力!

    **
    .
    .
    .
    .
    .
    .

    以下是注解说明,摘自官方文档: 注解说明**

    表名注解 @TableName

    com.baomidou.mybatisplus.annotations.TableName
    值 描述
    value ---------- 表名( 默认空 )
    resultMap ---------- xml 字段映射 resultMap ID

    主键注解 @TableId

    com.baomidou.mybatisplus.annotations.TableId
    值 描述
    value ---------- 字段值(驼峰命名方式,该值可无)
    type ----------主键 ID 策略类型( 默认 INPUT ,全局开启的是 ID_WORKER )
    暂不支持组合主键

    字段注解 @TableField

    com.baomidou.mybatisplus.annotations.TableField
    值 描述
    value ----------字段值(驼峰命名方式,该值可无)
    el ---------- 详看注释说明
    exist ----------是否为数据库表字段( 默认 true 存在,false 不存在 )
    strategy ---------- 字段验证 ( 默认 非 null 判断,查看 com.baomidou.mybatisplus.enums.FieldStrategy )
    .
    fill ----------字段填充标记 ( FieldFill, 配合自动填充使用 )
    字段填充策略 FieldFill
    值 描述
    DEFAULT ----------默认不处理
    INSERT ----------插入填充字段
    UPDATE ----------更新填充字段
    INSERT_UPDATE ----------插入和更新填充字段

    序列主键策略 注解 @KeySequence

    com.baomidou.mybatisplus.annotations.KeySequence
    值 描述
    value ----------序列名
    clazz ----------id的类型
    乐观锁标记注解 ----------@Version

    com.baomidou.mybatisplus.annotations.Version
    排除非表字段、查看文档常见问题部分!

    总结:MP的宗旨是简化开发,但是它在提供方便的同时却容易造成代码层次混乱,我们可能会把大量数据逻辑写到service层甚至contoller层中,使代码难以阅读。凡事过犹不及,在使用MP时一定要做分析,不要将所有数据操作都交给MP去实现。毕竟MP只是mybatis的增强工具,它并没有侵入mybatis的原生功能,在使用MP的增强功能的同时,原生mybatis的功能依然是可以正常使用的

    展开全文
  • Mybatis-Plus 使用操作_1

    万次阅读 2020-10-17 20:25:52
    代码生成器 pom 文件 <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --> <dependency> <groupId>...mybatis-plus-boot-starter</artifac

    代码生成器

    pom 文件

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.4.0</version>
            </dependency>
    
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>3.4.0</version>
            </dependency>
            <!-- 模板引擎 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>2.0</version>
            </dependency>
    
    

    代码

    package 
    com.ak.admin;
    
    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.generator.AutoGenerator;
    import com.baomidou.mybatisplus.generator.config.*;
    import com.baomidou.mybatisplus.generator.config.po.TableFill;
    import com.baomidou.mybatisplus.generator.config.rules.DateType;
    import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
    import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.util.ArrayList;
    
    @SpringBootTest
    public class MyTest {
    
    
        public static void main(String[] args) {
            // 代码生成器
            AutoGenerator mpg = new AutoGenerator();
    
            // 全局配置
            GlobalConfig gc = new GlobalConfig();
            String projectPath = System.getProperty("user.dir");
            gc.setOutputDir(projectPath + "/src/main/java");
            gc.setAuthor("joker");
            gc.setOpen(false);
            gc.setIdType(IdType.ASSIGN_UUID);
            gc.setDateType(DateType.ONLY_DATE);
            gc.setSwagger2(true);
            mpg.setGlobalConfig(gc);
    
            // 数据源配置
            DataSourceConfig dsc = new DataSourceConfig();
            dsc.setUrl("jdbc:mysql://rm-uf682626j42h0nn6ljo.mysql.rds.aliyuncs.com:3306/taobao?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC");
            // dsc.setSchemaName("public");
            dsc.setDriverName("com.mysql.cj.jdbc.Driver");
            dsc.setUsername("joker");
            dsc.setPassword("1654697013wanWAN");
            mpg.setDataSource(dsc);
    
            // 包配置
            PackageConfig pc = new PackageConfig();
            pc.setModuleName("admin");
            pc.setParent("com.ak");
            pc.setMapper("mapper");
            pc.setService("service");
            pc.setEntity("entity");
            pc.setServiceImpl("serviceImpl");
            mpg.setPackageInfo(pc);
    //
    //        // 自定义配置
    //        InjectionConfig cfg = new InjectionConfig() {
    //            @Override
    //            public void initMap() {
    //                // to do nothing
    //            }
    //        };
    //
    //        // 如果模板引擎是 freemarker
    //        String templatePath = "/templates/mapper.xml.ftl";
    //        // 如果模板引擎是 velocity
    //        // String templatePath = "/templates/mapper.xml.vm";
    //
    //        // 自定义输出配置
    //        List<FileOutConfig> focList = new ArrayList<>();
    //        // 自定义配置会被优先输出
    //        focList.add(new FileOutConfig(templatePath) {
    //            @Override
    //            public String outputFile(TableInfo tableInfo) {
    //                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
    //                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
    //                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
    //            }
    //        });
    //
    //        cfg.setFileOutConfigList(focList);
    //        mpg.setCfg(cfg);
    //
    //        // 配置模板
    //        TemplateConfig templateConfig = new TemplateConfig();
    //
    //        // 配置自定义输出模板
    //        //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
    //        // templateConfig.setEntity("templates/entity2.java");
    //        // templateConfig.setService();
    //        // templateConfig.setController();
    //
    //        templateConfig.setXml(null);
    //        mpg.setTemplate(templateConfig);
    
            // 策略配置
            StrategyConfig strategy = new StrategyConfig();
            strategy.setNaming(NamingStrategy.underline_to_camel);
            strategy.setColumnNaming(NamingStrategy.underline_to_camel);
         //   strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
            strategy.setEntityLombokModel(true);
            strategy.setRestControllerStyle(true);
            // 公共父类
          //  strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
            // 写于父类中的公共字段
          //  strategy.setSuperEntityColumns("id");
            strategy.setInclude("comment","goods","orderitem","orders","person","shoppingcart","store");
            strategy.setLogicDeleteFieldName("status");
            TableFill gmt_create=new TableFill("gmt_create", FieldFill.INSERT);
            TableFill gmt_modifty=new TableFill("gmt_modifty", FieldFill.INSERT_UPDATE);
    
            strategy.setControllerMappingHyphenStyle(true);
          //  strategy.setTablePrefix(pc.getModuleName() + "_");
            ArrayList<TableFill> objectArrayList=new ArrayList<>();
            objectArrayList.add(gmt_create);
            objectArrayList.add(gmt_modifty);
            strategy.setTableFillList(objectArrayList);
            strategy.setVersionFieldName("version");
            mpg.setStrategy(strategy);
         //   mpg.setTemplateEngine(new FreemarkerTemplateEngine());
            mpg.execute();
        }
    
    }
    
    展开全文
  • Springboot集成MyBatis-Plus的使用

    万次阅读 2020-06-15 14:11:25
    MyBatis-Plus介绍 Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-...

    MyBatis-Plus介绍

    Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网。那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA。

    官网地址:https://mp.baomidou.com/guide/quick-start.html

    Springboot集成MyBatis-Plus

    pom.xml

            <!-- 实现对 MyBatis Plus 的自动化配置 -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.2.0</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.48</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>

    application.properties

    # DataSource Config
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false
    spring.datasource.username=root
    spring.datasource.password=000000
    # mybatis-plus 配置内容
    # ID 主键自增
    mybatis-plus.global-config.db-config.id-type=auto
    mybatis-plus.mapper-locations=classpath*:mapper/*.xml
    mybatis-plus.type-aliases-package=com.test.sbmp.domain
    # Logger Config
    logging.level.com.tes

    User

    import lombok.Data;
    
    @Data
    public class User {
    
    	private Integer id;
    	private String username;
    	private String password;
    
    }
    

    UserMapper

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.test.sbmp.domain.User;
    
    
    public interface UserMapper extends BaseMapper<User> {
    
    }

    UserMapper.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.test.sbmp.mapper.UserMapper">
    
        <select id="selectUserById" resultType="com.test.sbmp.domain.User">
         select * from user where id = #{id}
        </select>
    
        <select id="selectUsers" resultType="com.test.sbmp.domain.User">
         select * from user
       </select>
    
        <insert id="addUser" parameterType="com.test.sbmp.domain.User">
           insert into user(username,password) values(#{username},#{password})
       </insert>
    
    </mapper>
    

    UserService

    import com.baomidou.mybatisplus.extension.service.IService;
    import com.test.sbmp.domain.User;
    
    public interface UserService extends IService<User> {
    
    }
    

    UserServiceImpl

    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.test.sbmp.domain.User;
    import com.test.sbmp.mapper.UserMapper;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    
    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    	@Resource
    	private UserMapper userMapper;
    
    	public boolean save(User user) {
    		int count = userMapper.insert(user);
    		return count > 0 ? true : false;
    	}
    
    
    	public User selectUserById(Integer id) {
    		User user = userMapper.selectById(id);
    		return user;
    	}
    	
    }
    

    UserController

    import com.test.sbmp.domain.User;
    import com.test.sbmp.service.UserServiceImpl;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    @RestController
    public class UserController {
    
    	@Resource
    	private UserServiceImpl userService;
    
    	@GetMapping("/users/{id}")
    	public User selectUserById(@PathVariable("id") Integer id) {
    		User user = userService.selectUserById(id);
    		System.out.println(user.getId() + ":" + user.getUsername());
    		return user;
    	}
    
    }

    测试

    http://localhost:8080/users/4

    {
    "id": 4,
    "username": "wangnian",
    "password": "wang"
    }

     

    展开全文
  • MyBatis-Plus | 最简单的查询操作教程(Lambda)

    万次阅读 多人点赞 2018-09-12 00:36:52
    上一篇:MyBatis-Plus | 最优雅最简洁地完成数据库操作 是对MyBatis-Plus的功能进行简单介绍,虽然是介绍,也让我们领略到他的优雅与强大。你是不是已经被吸引了?别着急,上一节,我们算是参观了MyBatis的风景,...

    引言

    上一篇:MyBatis-Plus | 最优雅最简洁地完成数据库操作

    是对MyBatis-Plus的功能进行简单介绍,虽然是介绍,也让我们领略到他的优雅与强大。你是不是已经被吸引了?别着急,上一节,我们算是参观了MyBatis的风景,这一节,我将带你领略他独特的魅力。

    Lambda

    官方表示,3.x支持Lambda表达式,那应该怎么使用呢?我们来看个例子:

    QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda().eq(Student::getName, "冯文议");
    List<Student> studentList = list(queryWrapper);
    for (Student student : studentList)
        Console.info(student);
    

    看一下测试结果(为了看好,我们转成json):

    {
        "id":1035789714459471874,
        "name":"冯文议",
        "age":26,
        "info":"无畏造英雄",
        "isDelete":false,
        "createTime":"Sep 1, 2018 3:21:26 PM",
        "updateTime":"Sep 1, 2018 3:21:26 PM",
        "gender":"MALE",
        "idcardId":1035789714388168706,
        "cityId":1035762001753501698
    }
    

    如果你使用了我的配置,你也能看到相应的SQL

    ==>  Preparing: SELECT id,name,age,info,is_delete,create_time,update_time,gender,idcard_id,city_id FROM t_student WHERE name = ? 
    ==> Parameters: 冯文议(String)
    <==    Columns: id, name, age, info, is_delete, create_time, update_time, gender, idcard_id, city_id
    <==        Row: 1035789714459471874, 冯文议, 26, <<BLOB>>, 0, 2018-09-01 15:21:26.0, 2018-09-01 15:21:26.0, 1, 1035789714388168706, 1035762001753501698
    <==      Total: 1
    

    分页查询

    感觉哈,分页查询是他们框架的起因,那我们先说分页查询。直接看代码:

    第一步:在 Application 中配置

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
    

    第二步:写分页代码(为了你能够看得清楚,我截图给你):

    分页代码

    看结果(json):

    {
        "records":[
            {
                "id":1035788325322752001,
                "name":"1",
                "age":1,
                "info":"1",
                "isDelete":false,
                "createTime":"Sep 1, 2018 3:15:55 PM",
                "updateTime":"Sep 1, 2018 3:15:55 PM",
                "gender":"MALE",
                "idcardId":1035788325276614657,
                "cityId":1035788325201117185
            },
            {
                "id":1035789714459471874,
                "name":"冯文议",
                "age":26,
                "info":"无畏造英雄",
                "isDelete":false,
                "createTime":"Sep 1, 2018 3:21:26 PM",
                "updateTime":"Sep 1, 2018 3:21:26 PM",
                "gender":"MALE",
                "idcardId":1035789714388168706,
                "cityId":1035762001753501698
            }
        ],
        "total":2,
        "size":2,
        "current":1,
        "optimizeCountSql":true
    }
    

    不要问我前端应该怎么写,表示我也不会写。

    条件查询

    终于要进入这里了,是不是很激动啊。别急,客官,抽根烟先,我们慢慢来。

    【1】多eq

    QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda()
            .eq(Student::getName, "冯文议")
            .eq(Student::getAge, 26);
    List<Student> studentList = list(queryWrapper);
    for (Student student : studentList)
        Console.info(new Gson().toJson(student));
    

    对于这部分的测试,我想结果是毫无因为,那么你应该关注什么呢?没错,SQL,所以,我们直接看SQL。当然,结果也是可以看到的。

    ==>  Preparing: SELECT id,name,age,info,is_delete,create_time,update_time,gender,idcard_id,city_id FROM t_student WHERE name = ? AND age = ? 
    ==> Parameters: 冯文议(String), 26(Integer)
    <==    Columns: id, name, age, info, is_delete, create_time, update_time, gender, idcard_id, city_id
    <==        Row: 1035789714459471874, 冯文议, 26, <<BLOB>>, 0, 2018-09-01 15:21:26.0, 2018-09-01 15:21:26.0, 1, 1035789714388168706, 1035762001753501698
    <==      Total: 1
    

    我们还可以这样写:

    QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda()
            .and(obj ->
                    obj.eq(Student::getName, "冯文议")
                        .eq(Student::getAge, 26));
    
    List<Student> studentList = list(queryWrapper);
    for (Student student : studentList)
        Console.info(new Gson().toJson(student));
    

    【2】or

    第一种:

    QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda()
            .or(obj1 -> obj1.eq(Student::getName, "冯文议"))
            .or(obj2 -> obj2.eq(Student::getName, "1"));
    List<Student> studentList = list(queryWrapper);
    for (Student student : studentList)
        Console.info(new Gson().toJson(student));
    

    sql:

    SELECT * FROM t_student WHERE ( name = ? ) OR ( name = ? ) 
    

    第二种:

    QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda()
            .eq(Student::getName, "冯文议")
            .or()
            .eq(Student::getName, "1");
    List<Student> studentList = list(queryWrapper);
    for (Student student : studentList)
        Console.info(new Gson().toJson(student));
    

    SQL:

    SELECT * FROM t_student WHERE name = ? OR name = ? 
    

    这样的话,我们就可以拼接各种条件了。那么问题来了:到底有哪些关键字呢?性能如何呢?

    条件构造器

    条件参数说明

    查询方式 说明
    setSqlSelect 设置 SELECT 查询字段
    where WHERE 语句,拼接 + WHERE 条件
    and AND 语句,拼接 + AND 字段=值
    andNew AND 语句,拼接 + AND (字段=值)
    or OR 语句,拼接 + OR 字段=值
    orNew OR 语句,拼接 + OR (字段=值)
    eq 等于=
    allEq 基于 map 内容等于=
    ne 不等于<>
    gt 大于>
    ge 大于等于>=
    lt 小于<
    le 小于等于<=
    like 模糊查询 LIKE
    notLike 模糊查询 NOT LIKE
    in IN 查询
    notIn NOT IN 查询
    isNull NULL 值查询
    isNotNull IS NOT NULL
    groupBy 分组 GROUP BY
    having HAVING 关键词
    orderBy 排序 ORDER BY
    orderAsc ASC 排序 ORDER BY
    orderDesc DESC 排序 ORDER BY
    exists EXISTS 条件语句
    notExists NOT EXISTS 条件语句
    between BETWEEN 条件语句
    notBetween NOT BETWEEN 条件语句
    addFilter 自由拼接 SQL
    last 拼接在最后,例如:last(“LIMIT 1”)

    注意! xxNew 都是另起 ( ... ) 括号包裹。

    自定义sql

    如果官方提供的满足不了你的需求,或者你的需求很复杂,导致你不知道如何使用条件构造器,那应该怎么办呢?

    很简单。

    第一步:找到 Dao,写一个数据库操作接口

    public interface StudentDao extends BaseMapper<Student> {
        
        List<Student> selectAll();
        
    }
    

    第二步:在xml文件中写sql

    <!--List<Student> selectAll();-->
    <select id="selectAll" resultMap="BaseResultMap">
        select * from t_student
    </select>
    

    这样我们就可以使用了:

    @Resource
    StudentDao studentDao;
    
    List<Student> studentList = studentDao.selectAll();
    for (Student student : studentList)
        Console.info(new Gson().toJson(student));
    

    测试:

    自定义sql测试

    封装我们自己的Service

    前面我们就说了,我是很不喜欢MP的查询接口的,我们就把他弄成我们喜欢的吧,我这里借鉴 JPA接口了,哈哈

    interface:

    /**
     * 查询所有数据
     * @return List<Student>
     */
    List<Student> findAll();
    
    /**
     * 查询部分数据
     * @return List<Student>
     */
    List<Student> findList();
    
    /**
     * 查询一条数据
     * @return Student
     */
    Student findOne();
    
    /**
     * 根据主键ID查询数据
     * @param id 主键ID,为null,返回null
     * @return Student
     */
    Student findById(Long id);
    

    impl:

    @Override
    public List<Student> findAll() {
        return list(null);
    }
    
    @Override
    public List<Student> findList() {
        return list(null);
    }
    
    @Override
    public Student findOne() {
        return getOne(null);
    }
    
    @Override
    public Student findById(Long id) {
        ExceptionUtil.notNull(id, "id must not null.");
        return getById(id);
    }
    

    我们来试一下:

    封装service接口

    哇!!!

    是不是很爽!!!

    资料

    [1] MyBatis-Plus测试示例

    [2] 官网测试例子:WrapperTest.java

    展开全文
  • mybatis-plus配置控制台打印完整带参数SQL语句

    万次阅读 多人点赞 2019-05-28 16:18:53
    问题背景 通常我们开发的时候,需要联合控制台和Navicat/PLSQL等工具进行语句的拼接检查,如果只是输出了一堆?...#mybatis-plus配置控制台打印完整带参数SQL语句 mybatis-plus: configuration: log-impl: org...
  • mybatis-plus

    2018-08-15 15:37:26
    mybatis-plus安装到20171.2的idea完全没问题,这个下载下来,然后打开idea找到File -- Settings -- plugins -- install plugin from disk选择下载的jar包就可以,然后重启,就可以了。非常简单
  • 项目中有使用mybatis-plus的逻辑删除插件,在项目初始化时有加载此插件,由于近期mybatis-plus版本升级从3.0-gama升级到3.2.0版本,在原本的逻辑删除处出现报错: Caused by: java.lang.AbstractMethodError: ...
  • MyBatis-Plus

    千次阅读 2020-09-27 19:22:54
    文章目录MyBatis-Plus1.1 MyBatis-Plus简介1.2 使用流程1.3 具体流程1.4CRUD操作1.5代码生成器 MyBatis-Plus 1.1 MyBatis-Plus简介 官网:https://mybatis.plus/ 作者:苞米豆 在Mybatis基础上只增强,不改变。 ...
  • 一、项目结构 二、pom.xml 依赖添加 (这里我是加在krystal_dao的pom.xml里面,单个项目,直接加在pom.xml,多模块根据自己项目情况添加) &lt;dependency&...mybatis-plus&lt;/arti...
  • mybatis-plus 高级特性-动态表名

    万次阅读 2020-12-16 18:59:52
    背景 在分表的背景下,有时候查询数据的时候需要跨表查询,那此时就需要MP在解析的时候,能够很好的自适应表格名称 实现 MP中是通过PaginationInterceptor(分页插件)完成动态...mybatis-plus-boot-starter<...
  • Mybatis-plus

    2019-07-22 19:31:00
    MyBatis-Plus:(简称 MP)是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 (1)Mybatis-Plus并没有提供单独的jar包,而是通过Maven(或者gradle)来管理jar依赖。本...
  • 你应该知道的这些Mybatis-Plus使用技巧

    万次阅读 多人点赞 2020-08-19 10:17:07
    最近在用 Mybatis-Plus,嗯,真香!!!今天就来说说 Mybatis-Plus 的那些使用技巧 1、条件查询(QueryWrapper) QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("age",...
  • MyBatis-Plus样品 本工程为MyBatis-Plus的官方示例,项目结构如下: mybatis-plus-sample-quickstart:快速开始示例 mybatis-plus-sample-quickstart-springmvc:快速开始示例(Spring MVC版本) mybatis-plus-...
  • mybatis-plus配置找不到Mapper接口路径的坑

    万次阅读 多人点赞 2019-06-28 23:39:29
    mybatis-plus今天遇到一个问题,就是mybatis 没有读取到mapper.xml 文件。 特此记录一下,问题如下: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): ...
  • Mybatis-Plus

    2017-09-22 12:33:04
    Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 我们的愿景是成为Mybatis最好的搭档,就像 Contra Game 中的1P、2P,基友搭配,效率翻...
  • 2、通过继承mapper接口操作数据,mapper接口操作数据有多种方式,如 tk.mybatis、mybatis-plus,本文使用mybatis-plus 3、通过注解方式操作数据,例如使用 @SelectProvider注解动态拼装sql查询数据,适用于复杂的sql...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,779
精华内容 9,911
关键字:

mybatis-plus