一、MyBatis和MyBatis Plus的区别
MyBatis的优势:
- 灵活性和可定制性高:MyBatis允许开发者手动编写原生SQL语句,可以满足复杂的查询需求,并且支持动态SQL语句的构建。
- SQL的可控性强:通过XML或注解的方式配置SQL语句,开发者可以更加直观地理解和管理SQL语句。
- 易于集成和使用:MyBatis与Java应用程序的集成相对简单,而且学习曲线相对较低。
MyBatis的劣势:
- 编写大量重复的CRUD操作代码:在传统的MyBatis中,需要手动编写大量的增删改查(CRUD)操作的SQL语句,工作量较大且容易出错。
- 不够便捷:相对于一些其他ORM框架,MyBatis的操作相对繁琐,需要手动处理一些细节。
MyBatis Plus的优势:
- 便捷的操作和增强功能:MyBatis Plus封装了很多常用的数据库操作方法,如增删改查,使得开发者能够更快速地完成基本的数据库操作,减少了重复劳动。
- 自动生成SQL语句:MyBatis Plus提供了代码生成器,可以根据实体类自动生成对应的SQL语句,简化了SQL语句的编写工作。
- 条件构造器和分页功能:MyBatis Plus提供了条件构造器和分页插件,使得查询条件的构建和分页操作更加便捷。
MyBatis Plus的劣势:
- 灵活性相对较低:由于MyBatis Plus已经封装了很多常用的数据库操作,如果遇到一些特殊的复杂查询需求,可能需要手动编写原生SQL语句或使用高级特性来实现。
综上所述,MyBatis具有灵活性和可定制性高的优势,适合处理复杂的查询需求;而MyBatis Plus则提供了更多的便捷操作和增强功能,适合处理常规的增删改查操作。选择哪个框架取决于项目的需求和开发团队的偏好。
二、MyBatis使用示例
当使用MyBatis在实际的Spring Boot项目中,以下是一个更加符合真实项目的示例:
添加相关依赖:
在项目的pom.xml文件中添加MyBatis的依赖:
<dependencies>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>VERSION</version>
</dependency>
<!-- 数据库驱动 -->
<!-- 其他依赖 -->
</dependencies>
创建数据库表对应的实体类:
创建一个实体类,例如Product,并使用注解或XML配置映射关系。假设产品表对应的数据库表为products
:
@Data
public class Product {
private Long id;
private String name;
private BigDecimal price;
// 其他属性和getter/setter方法
}
编写Mapper接口和XML文件:
编写Mapper接口,定义数据库操作方法,例如ProductMapper:
@Mapper
public interface ProductMapper {
void insert(Product product);
void update(Product product);
void delete(Long id);
Product getById(Long id);
List<Product> getAll();
}
同时,创建对应的XML文件ProductMapper.xml,配置SQL语句:
<mapper namespace="com.example.mapper.ProductMapper">
<insert id="insert" parameterType="com.example.entity.Product">
INSERT INTO products (name, price) VALUES (#{name}, #{price})
</insert>
<update id="update" parameterType="com.example.entity.Product">
UPDATE products SET name=#{name}, price=#{price} WHERE id=#{id}
</update>
<delete id="delete" parameterType="java.lang.Long">
DELETE FROM products WHERE id=#{id}
</delete>
<select id="getById" parameterType="java.lang.Long" resultType="com.example.entity.Product">
SELECT id, name, price FROM products WHERE id=#{id}
</select>
<select id="getAll" resultType="com.example.entity.Product">
SELECT id, name, price FROM products
</select>
</mapper>
在Service或Controller中调用Mapper接口:
在Service层或Controller层调用Mapper接口中的方法,完成数据的增删改查操作:
@Service
public class ProductService {
@Autowired
private ProductMapper productMapper;
public void createProduct(Product product) {
productMapper.insert(product);
}
public void updateProduct(Product product) {
productMapper.update(product);
}
public void deleteProduct(Long id) {
productMapper.delete(id);
}
public Product getProductById(Long id) {
return productMapper.getById(id);
}
public List<Product> getAllProducts() {
return productMapper.getAll();
}
}
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping
public ResponseEntity<String> createProduct(@RequestBody Product product) {
productService.createProduct(product);
return ResponseEntity.ok("Product created successfully");
}
@PutMapping("/{id}")
public ResponseEntity<String> updateProduct(@PathVariable Long id, @RequestBody Product product) {
Product existingProduct = productService.getProductById(id);
if (existingProduct == null) {
return ResponseEntity.notFound().build();
}
product.setId(id);
productService.updateProduct(product);
return ResponseEntity.ok("Product updated successfully");
}
@DeleteMapping("/{id}")
public ResponseEntity<String> deleteProduct(@PathVariable Long id) {
Product existingProduct = productService.getProductById(id);
if (existingProduct == null) {
return ResponseEntity.notFound().build();
}
productService.deleteProduct(id);
return ResponseEntity.ok("Product deleted successfully");
}
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
Product product = productService.getProductById(id);
if (product == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(product);
}
@GetMapping
public ResponseEntity<List<Product>> getAllProducts() {
List<Product> products = productService.getAllProducts();
return ResponseEntity.ok(products);
}
}
三、MyBatis Plus使用示例
方式一、使用MyBatis Plus可以通过继承它提供的Mapper接口来简化增删改查操作
创建数据库表对应的实体类:
创建一个实体类,例如Product,并使用注解或XML配置映射关系。假设产品表对应的数据库表为products
:
@Data
@TableName("products")
public class Product {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private BigDecimal price;
// 其他属性和getter/setter方法
}
创建Mapper接口:
创建一个继承自MyBatis Plus的BaseMapper接口的接口,例如ProductMapper:
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
}
在Service或Controller中调用Mapper接口:
在Service层或Controller层直接注入ProductMapper,并调用其提供的方法完成数据的增删改查操作:
@Service
public class ProductService {
@Autowired
private ProductMapper productMapper;
public void createProduct(Product product) {
productMapper.insert(product);
}
public void updateProduct(Product product) {
productMapper.updateById(product);
}
public void deleteProduct(Long id) {
productMapper.deleteById(id);
}
public Product getProductById(Long id) {
return productMapper.selectById(id);
}
public List<Product> getAllProducts() {
return productMapper.selectList(null);
}
}
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping
public ResponseEntity<String> createProduct(@RequestBody Product product) {
productService.createProduct(product);
return ResponseEntity.ok("Product created successfully");
}
@PutMapping("/{id}")
public ResponseEntity<String> updateProduct(@PathVariable Long id, @RequestBody Product product) {
Product existingProduct = productService.getProductById(id);
if (existingProduct == null) {
return ResponseEntity.notFound().build();
}
product.setId(id);
productService.updateProduct(product);
return ResponseEntity.ok("Product updated successfully");
}
@DeleteMapping("/{id}")
public ResponseEntity<String> deleteProduct(@PathVariable Long id) {
Product existingProduct = productService.getProductById(id);
if (existingProduct == null) {
return ResponseEntity.notFound().build();
}
productService.deleteProduct(id);
return ResponseEntity.ok("Product deleted successfully");
}
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
Product product = productService.getProductById(id);
if (product == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(product);
}
@GetMapping
public ResponseEntity<List<Product>> getAllProducts() {
List<Product> products = productService.getAllProducts();
return ResponseEntity.ok(products);
}
}
这个示例展示了在一个Spring Boot项目中使用MyBatis Plus进行数据库操作的常见步骤,包括实体类定义、Mapper接口的创建以及在Service或Controller中调用Mapper接口。通过继承BaseMapper接口,可以直接使用MyBatis Plus提供的方法来完成增删改查操作,无需手动编写SQL语句。注意,具体的表名、字段名等需要根据实际情况进行修改。
方式二、通过继承Service类来实现单表数据的增删改查操作
创建数据库表对应的实体类:
创建一个实体类,例如Product,并使用注解或XML配置映射关系。假设产品表对应的数据库表为products
:
@Data
@TableName("products")
public class Product {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private BigDecimal price;
// 其他属性和getter/setter方法
}
创建Service类:
创建一个继承自MyBatis Plus提供的IService接口的接口,并选择使用MyBatis Plus提供的ServiceImpl作为其实现类。例如,创建一个ProductService接口和ProductServiceImpl实现类:
public interface ProductService extends IService<Product> {
}
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
}
在Controller中调用Service类:
在Controller层直接注入ProductService,并调用其提供的方法来处理业务逻辑:
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping
public ResponseEntity<String> createProduct(@RequestBody Product product) {
productService.save(product);
return ResponseEntity.ok("Product created successfully");
}
@PutMapping("/{id}")
public ResponseEntity<String> updateProduct(@PathVariable Long id, @RequestBody Product product) {
Product existingProduct = productService.getById(id);
if (existingProduct == null) {
return ResponseEntity.notFound().build();
}
product.setId(id);
productService.updateById(product);
return ResponseEntity.ok("Product updated successfully");
}
@DeleteMapping("/{id}")
public ResponseEntity<String> deleteProduct(@PathVariable Long id) {
Product existingProduct = productService.getById(id);
if (existingProduct == null) {
return ResponseEntity.notFound().build();
}
productService.removeById(id);
return ResponseEntity.ok("Product deleted successfully");
}
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
Product product = productService.getById(id);
if (product == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(product);
}
@GetMapping
public ResponseEntity<List<Product>> getAllProducts() {
List<Product> products = productService.list();
return ResponseEntity.ok(products);
}
}
在这个示例中,通过继承MyBatis Plus提供的IService接口和ServiceImpl类,Service层可以直接使用MyBatis Plus提供的方法来完成单表数据的增删改查操作。在Controller层中,注入ProductService,并调用其提供的方法来处理业务逻辑。
方式一和方式二的区别:
在MyBatis Plus中,通过Service层继承Service类和Mapper层继承BaseMapper接口,都可以实现单表数据的增删改查操作。它们之间的区别主要体现在以下几个方面:
抽象层级:
Service层继承Service类:Service层是对业务逻辑进行抽象和封装的层级,负责处理复杂的业务逻辑,事务管理等。
Mapper层继承BaseMapper接口:Mapper层是与数据库交互的接口层级,负责执行SQL语句和数据库操作。
接口方法:
Service层:继承Service类后,会自动获得Service类中定义的一组CRUD方法,如save、update、remove、getById、list等,同时还可以定义自己的业务方法。
Mapper层:继承BaseMapper接口后,会自动获得BaseMapper接口中定义的一组CRUD方法,如insert、updateById、deleteById、selectById、selectList等。
动态SQL支持:
Service层:Service层一般不直接处理SQL语句,而是通过调用Mapper层的方法来执行SQL语句,可以利用MyBatis Plus提供的条件构造器Wrapper来进行动态查询。
Mapper层:Mapper层直接使用注解或XML编写SQL语句,提供了更灵活的操作方式,可以根据实际需求自由定义SQL语句。
事务管理:
Service层:Service层可以通过使用@Transactional注解或编程式事务管理来管理事务,保证数据的一致性和完整性。
Mapper层:Mapper层通常不涉及事务管理,它的主要职责是执行SQL操作。
综上所述,Service层继承Service类适用于处理复杂的业务逻辑,并提供了一组CRUD方法以及自定义的业务方法。Mapper层继承BaseMapper接口适用于直接执行SQL操作和灵活的动态SQL构造,但不具备业务逻辑处理能力。根据项目的具体情况,可以选择合适的方式来进行单表数据的增删改查操作。
四、MyBatis和MyBatis Plus适用场景
MyBatis和MyBatis Plus都是优秀的持久层框架,适用于不同的场景。以下是它们各自适合使用的场景:
MyBatis适合的场景:
- 对SQL语句有较高的控制需求:MyBatis提供了灵活的XML或注解方式编写SQL语句,可以满足复杂的SQL需求,包括动态SQL、嵌套查询等。
- 对数据库访问、连接等细节有较高要求:MyBatis需要手动编写SQL语句,能够直接操作数据库,对于需要对数据库连接进行精细调整的项目,如性能优化,MyBatis更加灵活。
- 偏向于传统的ORM开发方式:MyBatis较为贴近SQL的开发方式,适合有SQL开发经验的开发人员。
MyBatis Plus适合的场景:
- 快速开发简单的增删改查功能:MyBatis Plus提供了一组CRUD方法,无需手动编写SQL语句,可以快捷地完成常见的增删改查操作。
- 简化业务开发:MyBatis Plus封装了很多常用的数据库操作,提供了便捷的API,减少了开发人员对底层SQL的关注,可以专注于业务逻辑的实现。
- 提高开发效率:MyBatis Plus提供了一些便捷的功能,如分页查询、条件构造器、代码生成等,可以节省开发人员的时间和精力。
总结来说,如果项目对SQL的灵活性要求较高,需要精细调整数据库连接等细节,或者开发人员有SQL开发经验,则可以选择MyBatis。如果项目只需进行简单的增删改查操作,追求快速开发和高效率,并且不强调对底层SQL的细节控制,可以选择MyBatis Plus。当然,这两个框架在实际使用中也可以结合起来,根据具体的项目需求进行选择与使用。
最近白嫖了一个chatgpt的学习网站,分享给大家:欢迎来到GPT (yantegpt.cn)