Mybatis和Mybatis plus

一、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)

  • 9
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值