MyBatis-Plus(基于Spring)

news/2025/1/12 11:52:59/

目录

初始配置

基本CRUD

常用注解

条件构造器和常用接口

QueryWrapper

UpdateWrapper

condition

LambdaQueryWrapper

LambdaUpdateWrapper

插件

分页插件

xml自定义分页

 乐观锁

通用枚举

MyBatisX:


初始配置

1) 添加依赖:

<packaging>jar</packaging><properties><spring.version>5.3.1</spring.version></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><!-- 连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><!-- junit测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.27</version></dependency><!-- 日志 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.30</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!-- lombok用来简化实体类 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.16</version></dependency><!--MyBatis-Plus的核心依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.4.3.4</version></dependency></dependencies>

2) 创建MyBatis的核心配置文件

在resources下创建mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>

3) 创建Spring的配置文件

创建Spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"><!-- 引入jdbc.properties --><context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder><!-- 配置Druid数据源 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"></property><property name="url" value="${jdbc.url}"></property><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean><!--开启扫描--><context:component-scan base-package="com.gr.mybatisplus"></context:component-scan><!--配置mapper接口的扫描配置由mybatis-spring提供,可以将指定包下所有的mapper接口创建动态代理并将这些动态代理作为IOC容器的bean管理--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.gr.mybatisplus.mapper"></property></bean><!-- 此处使用的是MybatisSqlSessionFactoryBean --><bean  class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"><property name="configLocation" value="classpath:mybatis-config.xml"></property><property name="dataSource" ref="dataSource"></property><property name="typeAliasesPackage" value="com.gr.mybatisplus.pojo"></property><!-- 设置MyBatis-Plus的全局配置 --><property name="globalConfig" ref="globalConfig"></property></bean><bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig"><property name="dbConfig"><bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"><!-- 设置实体类所对应的表的前缀 --><property name="tablePrefix" value="t_"></property></bean></property></bean>
</beans>

4) 添加日志功能

在resources下创建logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false"><!--定义日志文件的存储地址 logs为当前项目的logs目录 还可以设置为../logs --><property name="LOG_HOME" value="logs" /><!--控制台日志, 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}- %msg%n</pattern></encoder></appender><!--myibatis log configure--><logger name="com.apache.ibatis" level="TRACE"/><logger name="java.sql.Connection" level="DEBUG"/><logger name="java.sql.Statement" level="DEBUG"/><logger name="java.sql.PreparedStatement" level="DEBUG"/><!-- 日志输出级别 --><root level="DEBUG"><appender-ref ref="STDOUT" /></root>
</configuration>

基本CRUD

BaseMapper

MyBatis-Plus中的基本CRUD在内置的BaseMapper中都已得到了实现,我们可以直接使用

插入

    @Testpublic void testInsert(){//实现新增用户信息//INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )User user = new User();//user.setId(100L);user.setName("张三");user.setAge(23);user.setEmail("zhangsan@atguigu.com");int result = userMapper.insert(user);System.out.println("result:"+result);System.out.println("id:"+user.getId());}

删除

    @Testpublic void testDelete(){//通过id删除用户信息//DELETE FROM user WHERE id=?int result = userMapper.deleteById(1492767055210991617L);System.out.println("result:"+result);//根据map集合中所设置的条件删除用户信息//DELETE FROM user WHERE name = ? AND age = ?Map<String, Object> map = new HashMap<>();map.put("name", "张三");map.put("age", 23);int result = userMapper.deleteByMap(map);System.out.println("result:"+result);//通过多个id实现批量删除//DELETE FROM user WHERE id IN ( ? , ? , ? )List<Long> list = Arrays.asList(1L, 2L, 3L);int result = userMapper.deleteBatchIds(list);System.out.println("result:"+result);}

修改

    @Testpublic void testUpdate(){//修改用户信息//UPDATE user SET name=?, email=? WHERE id=?User user = new User();user.setId(4L);user.setName("李四");user.setEmail("lisi@atguigu.com");int result = userMapper.updateById(user);System.out.println("result:"+result);}

查询

     @Testpublic void testSelect(){//通过id查询用户信息//SELECT id,name,age,email FROM user WHERE id=?User user = userMapper.selectById(1L);System.out.println(user);//根据多个id查询多个用户信息//SELECT id,name,age,email FROM user WHERE id IN ( ? , ? , ? )List<Long> list = Arrays.asList(1L, 2L, 3L);List<User> users = userMapper.selectBatchIds(list);users.forEach(System.out::println);//根据map集合中的条件查询用户信息//SELECT id,name,age,email FROM user WHERE name = ? AND age = ?Map<String, Object> map = new HashMap<>();map.put("name", "Jack");map.put("age", 20);List<User> users = userMapper.selectByMap(map);users.forEach(System.out::println);//查询所有数据//SELECT id,name,age,email FROM userList<User> users = userMapper.selectList(null);users.forEach(System.out::println);/*Map<String, Object> map = userMapper.selectMapById(1L);System.out.println(map);*/}

通用Service

a>IService 

 MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑 详情查看源码IService和ServiceImpl

b>创建Service接口和实现类

//UserService继承IService模板提供的基础功能
public interface UserService extends IService<User> {}
/**
* ServiceImpl实现了IService,提供了IService中基础功能的实现
* 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}

c>扫描组件

在applicationContext.xml中添加扫描组件的配置,扫描业务层组件,用于测试

d>测试查询记录数

e>测试批量插入

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MyBatisPlusServiceTest {@Autowiredprivate UserService userService;@Testpublic void testGetCount(){long count = userService.count();System.out.println("啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊:"+count);}@Testpublic void testInsertMore(){List<User> list = new ArrayList<>();for (int i = 1; i < 10; i++) {User user = new User();user.setName("aaa"+i);user.setAge(22+i);list.add(user);}boolean b = userService.saveBatch(list);System.out.println("aaaa啊啊啊啊啊啊啊啊:"+b);}
}

常用注解

常用注解实例: 

//设置实体类所对应的表名
//@TableName("t_user")
public class User {//将属性所对应的字段指定为主键//@TableId注解的value属性用于指定主键的字段//@TableId注解的type属性设置主键生成策略//@TableId(value = "uid", type = IdType.AUTO)@TableId("uid")private Long id;//指定属性所对应的字段名@TableField("user_name")private String name;private Integer age;private String email;private SexEnum sex;@TableLogicprivate Integer isDeleted;
}

1、@TableName

在实体类类型上添加@TableName("t_user"),标识实体类对应的表,即可成功执行SQL语句

通过GlobalConfig全局配置  修改spring核心配置文件:

    <!-- 此处使用的是MybatisSqlSessionFactoryBean --><bean  class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"><property name="configLocation" value="classpath:mybatis-config.xml"></property><property name="dataSource" ref="dataSource"></property><property name="typeAliasesPackage" value="com.gr.mybatisplus.pojo"></property><!-- 设置MyBatis-Plus的全局配置 --><property name="globalConfig" ref="globalConfig"></property></bean><bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig"><property name="dbConfig"><bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"><!-- 设置实体类所对应的表的前缀 --><property name="tablePrefix" value="t_"></property></bean></property></bean>

2、@TableId

在实体类中uid属性上通过@TableId将其标识为主键,即可成功执行SQL语句

相当于配置@TableId的type属性的全局主键策略:   bean标签globalConfig中的bean标签内添加如下信息

<!-- 设置全局主键策略 -->
<property name="idType" value="AUTO"></property>

3、@TableField

若实体类中的属性使用的是驼峰命名风格,而表中的字段使用的是下划线命名风格,此时MyBatis-Plus会自动将下划线命名风格转化为驼峰命名风格

例如实体类属性name,表中字段username 此时需要在实体类属性上使@TableField("username")设置属性所对应的字段名

 4、@TableLogic

逻辑删除

物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据

逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库 中仍旧能看到此条数据记录

使用场景:可以进行数据恢复

实现逻辑删除

step1:数据库中创建逻辑删除状态列,设置默认值为0

step2:实体类中添加逻辑删除属性 

常用注解实例: 

//设置实体类所对应的表名
//@TableName("t_user")
public class User {//将属性所对应的字段指定为主键//@TableId注解的value属性用于指定主键的字段//@TableId注解的type属性设置主键生成策略//@TableId(value = "uid", type = IdType.AUTO)@TableId("uid")private Long id;//指定属性所对应的字段名@TableField("user_name")private String name;private Integer age;private String email;private SexEnum sex;@TableLogicprivate Integer isDeleted;
}

条件构造器和常用接口

接口类:

Wrapper : 条件构造抽象类,最顶端父类

        AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件

                QueryWrapper : 查询条件封装

                UpdateWrapper : Update 条件封装

                AbstractLambdaWrapper : 使用Lambda 语法

                        LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper

                        LambdaUpdateWrapper : Lambda 更新封装Wrapper

QueryWrapper

    //a>例1:组装查询条件@Testpublic void test01(){//查询用户名包含a,年龄在20到30之间,邮箱信息不为null的用户信息//SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (user_name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("user_name", "a").between("age", 20, 30).isNotNull("email");List<User> list = userMapper.selectList(queryWrapper);list.forEach(System.out::println);}  
    //b>例2:组装排序条件@Testpublic void test02(){//查询用户信息,按照年龄的降序排序,若年龄相同,则按照id升序排序//SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 ORDER BY age DESC,uid ASCQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.orderByDesc("age").orderByAsc("uid");List<User> list = userMapper.selectList(queryWrapper);list.forEach(System.out::println);}   
   //c>例3:组装删除条件@Testpublic void test03(){//删除邮箱地址为null的用户信息//UPDATE t_user SET is_deleted=1 WHERE is_deleted=0 AND (email IS NULL)QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.isNull("email");int result = userMapper.delete(queryWrapper);System.out.println("result:"+result);}
    //d>例4:条件的优先级@Testpublic void test04(){//将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改//UPDATE t_user SET user_name=?, email=? WHERE is_deleted=0 AND (age > ? AND user_name LIKE ? OR email IS NULL)QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 20).like("user_name", "a").or().isNull("email");User user = new User();user.setName("小明");user.setEmail("test@atguigu.com");int result = userMapper.update(user, queryWrapper);System.out.println("result:"+result);}@Testpublic void test05(){//将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改//lambda中的条件优先执行//UPDATE t_user SET user_name=?, email=? WHERE is_deleted=0 AND (user_name LIKE ? AND (age > ? OR email IS NULL))QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("user_name", "a").and(i->i.gt("age",20).or().isNull("email"));User user = new User();user.setName("小红");user.setEmail("test@atguigu.com");int result = userMapper.update(user, queryWrapper);System.out.println("result:"+result);}
   //e>例5:组装select子句@Testpublic void test06(){//查询用户的用户名、年龄、邮箱信息//SELECT user_name,age,email FROM t_user WHERE is_deleted=0QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("user_name", "age", "email");List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);maps.forEach(System.out::println);}   
    //f>例6:实现子查询@Testpublic void test07(){//查询id小于等于100的用户信息//SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (uid IN (select uid from t_user where uid <= 100))QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.inSql("uid", "select uid from t_user where uid <= 100");List<User> list = userMapper.selectList(queryWrapper);list.forEach(System.out::println);}

UpdateWrapper

    @Testpublic void test08(){//将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.like("user_name", "a").and(i -> i.gt("age", 20).or().isNull("email"));.set("user_name", "小黑").set("email","abc@atguigu.com");int result = userMapper.update(null, updateWrapper);System.out.println("result:"+result);}

condition

    @Testpublic void test10(){String username = "a";Integer ageBegin = null;Integer ageEnd = 30;QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like(StringUtils.isNotBlank(username), "user_name", username).ge(ageBegin != null, "age", ageBegin).le(ageEnd != null, "age", ageEnd);List<User> list = userMapper.selectList(queryWrapper);list.forEach(System.out::println);}

LambdaQueryWrapper

    @Testpublic void test11(){//SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (user_name LIKE ? AND age <= ?)String username = "a";Integer ageBegin = null;Integer ageEnd = 30;LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.like(StringUtils.isNotBlank(username), User::getName, username).ge(ageBegin != null, User::getAge, ageBegin).le(ageEnd != null, User::getAge, ageEnd);List<User> list = userMapper.selectList(queryWrapper);list.forEach(System.out::println);}

LambdaUpdateWrapper

    @Testpublic void test12(){//将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();updateWrapper.like(User::getName, "a").and(i -> i.gt(User::getAge, 20).or().isNull(User::getEmail));.set(User::getName, "小黑").set(User::getEmail,"abc@atguigu.com");int result = userMapper.update(null, updateWrapper);System.out.println("result:"+result);}

插件

分页插件

添加配置

<bean>class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"><property name="configLocation" value="classpath:mybatis-config.xml"></property><property name="dataSource" ref="dataSource"></property><property name="typeAliasesPackage" value="com.atguigu.mp.pojo"></property><property name="globalConfig" ref="globalConfig"></property><!--配置插件--><property name="plugins"><array><ref bean="mybatisPlusInterceptor"></ref></array></property>
</bean>
<!--配置MyBatis-Plus插件-->
<bean id="mybatisPlusInterceptor"class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor"><property name="interceptors"><list><ref bean="paginationInnerInterceptor"></ref></list></property>
</bean>
<!--配置MyBatis-Plus分页插件的bean-->
<bean id="paginationInnerInterceptor"class="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor">
<!--设置数据库类型-->
<property name="dbType" value="MYSQL"></property>

测试

@Test
public void testPage(){//设置分页参数Page<User> page = new Page<>(1, 5);userMapper.selectPage(page, null);//获取分页数据List<User> list = page.getRecords();list.forEach(System.out::println);System.out.println("当前页:"+page.getCurrent());System.out.println("每页显示的条数:"+page.getSize());System.out.println("总记录数:"+page.getTotal());System.out.println("总页数:"+page.getPages());System.out.println("是否有上一页:"+page.hasPrevious());System.out.println("是否有下一页:"+page.hasNext());
}

结果

User(id=1, name=Jone, age=18, email=test1@baomidou.com, isDeleted=0) User(id=2, name=Jack, age=20, email=test2@baomidou.com, isDeleted=0) User(id=3, name=Tom, age=28, email=test3@baomidou.com, isDeleted=0) User(id=4, name=Sandy, age=21, email=test4@baomidou.com, isDeleted=0) User(id=5, name=Billie, age=24, email=test5@ba omidou.com, isDeleted=0) 当前页:1 每页显示的条数:5 总记录数:17 总页数:4 是否有上一 页:false 是否有下一页:true 

xml自定义分页

UserMapper中定义接口方法

/**
* 根据年龄查询用户列表,分页显示
* @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位
* @param age 年龄
* @return
*/
IPage<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integerage);

UserMapper.xml中编写SQL

<!--SQL片段,记录基础字段-->
<sql id="BaseColumns">id,username,age,email</sql>
<!--IPage<User> selectPageVo(Page<User> page, Integer age);-->
<select id="selectPageVo" resultType="User">SELECT <include refid="BaseColumns"></include> FROM t_user WHERE age > #{age}
</select>

测试

@Test
public void testSelectPageVo(){//设置分页参数Page<User> page = new Page<>(1, 5);userMapper.selectPageVo(page, 20);//获取分页数据List<User> list = page.getRecords();list.forEach(System.out::println);System.out.println("当前页:"+page.getCurrent());System.out.println("每页显示的条数:"+page.getSize());System.out.println("总记录数:"+page.getTotal());System.out.println("总页数:"+page.getPages());System.out.println("是否有上一页:"+page.hasPrevious());System.out.println("是否有下一页:"+page.hasNext());
}

结果:

User(id=3, name=Tom, age=28, email=test3@baomidou.com, isDeleted=null) User(id=4, name=Sandy, age=21, email=test4@baomidou.com, isDeleted=null) User(id=5, name=Billie, age=24, email=test5@baomidou.com, isDeleted=null) User(id=8, name=ybc1, age=21, email=null, isDeleted=null) User(id=9, name=ybc2, age=22, email=null, isDeleted=null) 当前 页:1 每页显示的条数:5 总记录数:12 总页数:3 是否有上一页:false 是否有下一页:true

 乐观锁

乐观锁实现流程

数据库中添加version字段

取出记录时,获取当前version

SELECT id,`name`,price,`version` FROM product WHERE id=1 

更新时,version + 1,如果where语句中的version版本不对,则更新失败

UPDATE product SET price=price+50, `version`=`version` + 1 WHERE id=1 AND `version`=1

Mybatis-Plus实现乐观锁

@Version实体类添加注解

@Data
public class Product {private Long id;private String name;private Integer price;@Versionprivate Integer version;
}

添加乐观锁插件配置

<!--配置MyBatis-Plus插件-->
<bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor"><property name="interceptors"><list><ref bean="paginationInnerInterceptor"></ref><ref bean="optimisticLockerInnerInterceptor"></ref></list></property>
</bean>
<!--配置乐观锁插件-->
<bean id="optimisticLockerInnerInterceptor"class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor"></bean>

通用枚举

表中的有些字段值是固定的,例如性别(男或女),此时我们可以使用MyBatis-Plus的通用枚举 来实现

数据库表添加字段sex

创建通用枚举类型

@Getter
public enum SexEnum {MALE(1, "男"),FEMALE(2, "女");@EnumValueprivate Integer sex;private String sexName;SexEnum(Integer sex, String sexName) {this.sex = sex;this.sexName = sexName;}
}

配置扫描通用枚举

<bean>class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"><property name="configLocation" value="classpath:mybatis-config.xml"></property><property name="dataSource" ref="dataSource"></property><property name="typeAliasesPackage" value="com.atguigu.mp.pojo"></property><!-- 设置MyBatis-Plus的全局配置 --><property name="globalConfig" ref="globalConfig"></property><!-- 配置扫描通用枚举 --><property name="typeEnumsPackage" value="com.atguigu.mp.enums"></property>
</bean>

测试

@Test
public void testSexEnum(){User user = new User();user.setName("Enum");user.setAge(20);//设置性别信息为枚举项,会将@EnumValue注解所标识的属性值存储到数据库user.setSex(SexEnum.MALE);//INSERT INTO t_user ( username, age, sex ) VALUES ( ?, ?, ? )//Parameters: Enum(String), 20(Integer), 1(Integer)userMapper.insert(user);
}

MyBatisX:

MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率 但是在真正开发过程中,MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL,多表 联查,我们就需要自己去编写代码和SQL语句,我们该如何快速的解决这个问题呢,这个时候可 以使用MyBatisX插件 MyBatisX一款基于 IDEA 的快速开发插件,为效率而生。

MyBatisX插件用法:https://baomidou.com/pages/ba5b24/ 


http://www.ppmy.cn/news/204489.html

相关文章

MyBatis-Plus(详解)

&#x1f341;博客主页&#xff1a;&#x1f449;不会压弯的小飞侠 ✨欢迎关注&#xff1a;&#x1f449;点赞&#x1f44d;收藏⭐留言✒ ✨系列专栏&#xff1a;&#x1f449;MyBatis-Plus专栏 ✨如果觉得博主的文章还不错的话&#xff0c;请三连支持一下博主。 &#x1f525;…

77-Mybatis-Plus详解

Mybatis-Plus详解 Mybatis-Plus概念&#xff1a; Mybatis-Plus介绍&#xff1a; 官⽹&#xff1a;https://mp.baomidou.com/ MyBatis-Plus&#xff08;简称 MP&#xff09;是⼀个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff08;即自然内置…

s-plus

http://www.stathome.cn/manual/s/10.html 图形 常用图形 S-PLUS有很强的图形功能&#xff0c;它可以用简单的函数调用迅速作出数据的各种图形&#xff0c;当你熟悉了S图形的技术之后也可以指定许多图形选项按自己的要求定制图形。它的另一个特色是同一个绘图函数对不同的数…

android 手机型号占有量,2021年安卓手机性能排行及手机品牌占有率

首先送上各品牌在最近30天来的品牌占有率&#xff1a;可见苹果依旧占据了半壁江山&#xff0c;其次是三星&#xff0c;虽然三星在国内依旧销声匿迹&#xff0c;但是在全球市场依然非常的强悍&#xff0c;不是三星太强&#xff0c;是对手太弱。接着是小米&#xff0c;华为&#…

android 手机处理器,安卓手机处理器性能排行 你的手机能排第几?

智能手机发展的过程也可以简单看做是移动处理器的发展历程。最早的智能手机搭载的芯片是单核的&#xff0c;主频也很低&#xff0c;而如今的处理器已经升级到了八核甚至是十核&#xff0c;主频正在向3GHz进发。近日鲁大师评测公布了今年第一季度安卓智能手机处理器的性能排行&a…

2018最新手机cpu排行

大家在购买手机的时候&#xff0c;或多或少都会考虑到手机性能。而手机所采用的处理器&#xff0c;则在一定程度上反映出手机性能的强弱。下面的2018年02月版手机CPU天梯图可以为您购买高性价比手机提供参考。 文章来源自新浪博客&#xff1a;2018最新手机cpu排行

android 手机 跑分榜,安兔兔跑分最新排行图 2020年4月Android手机性能榜

五一假期刚过&#xff0c;不知道各位朋友休息的如何&#xff1f;在假期后的*工作日&#xff0c;安兔兔根据后台统计到的数据&#xff0c;发布了2020年4月份Android手机性能榜单。和以往一样&#xff0c;本次榜单依然分为旗舰榜单和中端榜单。 本次数据统计的时间为2020年4月1日…

大模型训练和部署的关键技术

自2016年至今&#xff0c;模型大小每18个月增长40倍&#xff0c;自2019年到现在&#xff0c;更是每18个月增长340倍。 然而相比之下&#xff0c;硬件增长速度较慢&#xff0c;自2016年至今&#xff0c;GPU的性能增长每18个月1.7倍&#xff0c;模型大小和硬件增长的差距逐渐扩大…