MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatis其实也是一个很好的ORM框架,可以有效的把数据库的操作转换为Java代码中的类操作,让开发人员不用过于关注sql语句的编写。MyBatis有个很好的优点,它把sql语句提取到xml中独立管理,且具备简单的逻辑功能,可以根据业务状况动态的通过xml生产出sql语句。
不过维护一个xml文件依旧非常的复杂,有的时候甚至不如维护sql文件,所以MyBatis-Plus 框架更加的简单,我觉得更像jpa一样,能通过类映射操作表就完全维护类文件,过于复杂的sql不能通过类文件映射,就干脆使用sql语句,抛弃xml文件。说到这里,其实我还是更喜欢jpa,不过MyBatis-Plus 提供那些配置也的确更丰富一些,比如缓存,用起来很简单。
所以我总结一下,对于主要业务是高并发查询的项目使用MyBatis-Plus,如果sql比较复杂或者写入较多的时候,就考虑使用MyBatis的xml文件做业务支撑,如果是大数据量入库的项目,建议还是用JDBCTemplate,比如我之前用的那种每秒几万条数据入库,既要处理死锁,又要做merge(数据存在执行update,不存在执行insert)操作的场景,可能最原始的更合适。
- 引入依赖库
<dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.10.1</version> </dependency> <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> <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.4.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.24</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
- 在application.yaml文件中添加数据源和MyBatis-Plus配置
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/mybatisplus?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&useLegacyDatetimeCode=false username: root password: 'root' initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: 'SELECT 1 FROM DUAL' testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 filters: 'stat,wall' connectionProperties: 'druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000' useGlobalDataSourceStat: true mybatis-plus: configuration: # MyBatis 配置 map-underscore-to-camel-case: true global-config: # 全局配置 db-config: # 数据库配置 id-type: auto
对于表中主键id,可以选择使用自增的int格式,一般来说自增的int足够支撑业务,面试的时候经常会问如果自增id用完了怎么办,其实实际生产环境中数据都是定期清理的,一般太久的数据就会清零,自增id也会清零;MyBatis默认使用雪花算法生成id,如果你不配置就会生成一个很大的int,雪花算法优点就是对于分布式系统如果想要各个微服务之间保证唯一id不重复是很慢的,一般要用redis进行控制,让redis维护一个自增int,因为redis是原子操作,所以只有一个服务能获取到incr的结果,但是缺点是增加的redis的维护成本,且网络操作性能肯定会有降低,所以雪花算法就是让各个微服务自己进行计算一个唯一id,算法简单来说就是时间戳+机器码+随机数,这样本地直接生成id效率更高。面试八股文的时候可能会问到雪花算法会不会重复,严格来说其实会重复,只是概率极小。
- 创建一个User类,映射到数据库中的表,注意MyBatis-Plus默认是不自动生成表的
package com.mj.mybatisplus.po; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serializable; /** * @TableName 将当前的实体类和数据库的表建立联系 * 注解参数:表名 */ @TableName("user") @Data public class User implements Serializable { /** * 主键属性 @TableId * * value 该属性对应的数据库表中的字段名 * type 主键自增的类型 AUTO 代表自动递增 */ @TableId(value = "id",type = IdType.AUTO) private Integer id; /** * 非主键属性 @TableField * @TableField("username") 参数为该属性对应的数据库表中的字段名 * */ @TableField("username") private String username; @TableField("password") private String password; // 不是数据库字段 @TableField(exist = false) private String address; }
- 创建一个mapper的interface,继承BaseMapper,这样就继承了框架给我们集成好的基本的CRUD功能。
package com.mj.mybatisplus.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.mj.mybatisplus.po.User; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper extends BaseMapper<User> { }
注意要添加@Mapper注解,这样才会被springboot纳入到依赖注入中。
- 随意创建一个api接口做个测试
package com.mj.mybatisplus.api; import com.mj.mybatisplus.mapper.UserMapper; import com.mj.mybatisplus.po.User; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.Date; @RestController @RequestMapping("/api") public class ApiController { @Resource private UserMapper userMapper; @RequestMapping(value = "/{id}", method = RequestMethod.GET) public String test(@PathVariable("id") String id) { User user = new User(); user.setUsername("zhangsan"); user.setPassword("123"); userMapper.insert(user); return String.valueOf(new Date()); } }
这里想到一个八股文,@Resource和@Autowired有什么区别?@Autowired是Springboot的,@Resource是java的。最大区别是Autowired注解支持属性注入、构造方法注入和 Setter 注入,而Resource注解只支持属性注入和 Setter 注入。