自我来看Mybatis在项目长远发展更胜一筹.能写sql就写sql.有的人会讲能快速完成项目的技术达到目的即可.有人说外国不都用JPA,网上的资料不都说高手用JPA吗? 也有人会讲现在分布式不都单表查询查库拼装吗?这种思想太急功近利,我的观点是在个人提升和项目长远发展上提出的Mybatis更胜一筹.原因如下:
JPA是SpringBoot官方基于Hibernate的封装.对于开发人员来讲,免去写sql,具备特定语法查询.也具备在应用层建立约束关系和对象创建表. 但问题也很明显,后期维护sql优化不方便.看不到sql语句,而且增删改也会先查询后修改浪费性能. 虽然动态查询有Specification ,但可读性不高.对于联表查询还是得原生sql,而且原生查询不支持对象返回.必须要自定义配置.分步查询基本不能用Hash结果关联.
MybatisPlus很方便,但代码冗余多,对于联表查询也是痛点.
但Mybatis 虽然离不开sql,但是对于系统长远发展非常友好.查询灵活,原生sql都能查,代码sql相分离.大幅提高代码可读性和可维护性.存在的映射关系更是可以返回一切类型.MyBatis在分步查询方面我认为完爆JPA和MybatisPlus.因为联表查询我们都可以分解为分步查询.但分步查询需要结果之间进行数据关联.而Mybatis支持MapKey注解自定义key的字段.这意味着上一张表的唯一属性可以作为key与另一张表形成关联.是很方便的.
Spring Data JPA | |
---|---|
作用: | 面向对象的ORM全自动化框架,简化持久化操作的开发工作:让开发者从繁琐的JDBC和SQL代码中解脱出来,直接面向对象持久化操作. |
特点: | 跨数据库换源方便 |
底层基于hibernate实现JPA实现 | |
MySql中新建数据库,命名为springbootjpa,不用建表,运行项目后会自动生成表。 | |
复杂sql支持原生语句 | |
具备多表关联操作.配置好关联关系,自动处理关联操作 | |
缺点: | 没有实现独立的增删改操作,必须先查询 |
复杂原生sql与代码耦合度高 | |
Id 雪花算法需要自己开发 | |
需要自己处理count查询 |
MyBatisPlus | |
---|---|
作用: | 面向对象的ORM全自动化框架,简化持久化操作的开发工作:让开发者从繁琐的JDBC和SQL代码中解脱出来,直接面向对象持久化操作. |
特点: | 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 |
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 | |
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器 | |
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件 | |
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence) | |
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作 | |
支持自定义全局通用操作:支持全局通用方法注入 | |
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎 | |
内置分页插件:基于 MyBatis 物理分页 | |
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库 | |
内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询 | |
MySql中新建数据库,命名为springbootjpa,不用建表,运行项目后会自动生成表. | |
缺点: | 项目引入第三方插件包,未来升级有一定的兼容性问题. |
社区技术迭代行快,从而会导致有效部分技术文档得不到及时更新. |
总结: hibernate性能不如MyBatisPlus.但深刻体现面向对象编程的思想无需关注表结构和实体对象的关系.在小项目上hibernate更加方便.而对于复杂业务MyBatisPlus就更胜一筹;
详见hibernate与MyBatisPlus的优劣
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.6.3version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.6.3version>
<type>pomtype>
dependency>
<dependency>
<groupId>org.springframework.datagroupId>
<artifactId>spring-data-bomartifactId>
<version>2022.0.1version>
<scope>importscope>
<type>pomtype>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
<scope>testscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.26version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.2.11version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
yml
server:
port: 8080
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
username: root
password: root
jpa:
# 默认检测
database: mysql
# 默认检测 数据库名称
database-platform: test
# 是否在启动时候初始化架构 generate hibernate.auto二选一
# generate-ddl: true
# 表生成策略 默认none
# update 如果没有表就自动创建,有就检查更新
# create 创建
hibernate:
ddl-auto: update
# physical-strategy 默认直接映射
# SpringPhysicalNamingStrategy 驼峰命名映射为大写变下划线
# naming:
# physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
# properties 提供hibernate更多的原生配置
properties:
hibernate:
# 配置方言:选择数据库类型 查看Dialect类的所有接口实现.
dialect: org.hibernate.dialect.MySQL8Dialect
# 控制台显示sql
format_sql: true
# 允许在日志中记录sql语句 默认false
show-sql: true
主启动类
@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.vector.dao")
@EnableTransactionManagement
public class HibernateApplication {
public static void main(String[] args) {
SpringApplication.run(HibernateApplication.class);
}
}
dao
@Repository
public interface CustomerDao extends PagingAndSortingRepository<Customer,Long> {
}
单元测试
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class SpringDataJpaTest {
@Resource
CustomerDao repository;
@Test
public void testR() {
Optional<Customer> byId = repository.findById(1L);
System.out.println(byId.get());
}
@Test
public void testC() {
Customer customer = new Customer();
customer.setCustId(3L);
customer.setCustName("王五");
repository.save(customer);
}
@Test
public void testD() {
Customer customer = new Customer();
customer.setCustId(3L);
customer.setCustName("李四");
repository.delete(customer);
}
@Test
public void testE(){
log.info("查询所有数据: {}",repository.findAll());
}
}
MyBatisPlus官方文档
MyBatisPlus逆向工程
pom
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>最新版本version>
dependency>
yml
## MyBatis配置
#mybatis:
# # 搜索指定包别名
# typeAliasesPackage: com.vector.**.domain
# # 配置mapper的扫描,找到所有的mapper.xml映射文件
# mapperLocations: classpath*:mapper/**/*Mapper.xml
# # 加载全局的配置文件
# configLocation: classpath:mybatis/mybatis-config.xml
# MyBatis-plus配置
mybatis-plus:
type-aliases-package: com.vector.**.pojo
# mapper-locations: classpath*全包依赖扫描; classpath自己的mapper
mapper-locations: classpath*:mapper/**/*Mapper.xml
# 统一设定自增主键
global-config:
db-config:
id-type: auto
logic-delete-value: 1
logic-not-delete-value: 0
main
@SpringBootApplication
@MapperScan("com.vector.**.dao")
@EnableTransactionManagement
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
dao
@Mapper
public interface CategoryMapper extends BaseMapper<Article> {
}