编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

传统手动实现 UserService 和 基于 ServiceImpl 的简化写法的区别

wxchong 2025-01-05 20:36:02 开源技术 80 ℃ 0 评论


用户服务实现类


用户服务接口
package com.example.demo.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.demo.entity.User;

import java.util.List;

public interface UserService {

    // 根据名称分页查询用户
    IPage<User> getUsersByName(String name, int page, int size);

    // 创建新用户
    User createUser(User user);

    // 根据ID删除用户
    boolean deleteUser(Long id);

    // 更新用户信息
    User updateUser(User user);

    // 根据ID查找用户
    User findById(Long id);

    // 获取所有用户
    List<User> findAllUsers();
}


用户服务实现类
package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public IPage<User> getUsersByName(String name, int page, int size) {
        // 创建分页对象
        Page<User> pageable = new Page<>(page, size);
        // 按名称查询并分页
        return userMapper.selectPage(pageable, new QueryWrapper<User>().like("name", name));
    }

    @Override
    public User createUser(User user) {
        // 插入新用户
        userMapper.insert(user);
        return user;
    }

    @Override
    public boolean deleteUser(Long id) {
        // 根据ID删除用户
        return userMapper.deleteById(id) > 0;
    }

    @Override
    public User updateUser(User user) {
        // 更新用户信息
        userMapper.updateById(user);
        return user;
    }

    @Override
    public User findById(Long id) {
        // 根据ID查找用户
        return userMapper.selectById(id);
    }

    @Override
    public List<User> findAllUsers() {
        // 查询所有用户
        return userMapper.selectList(null);
    }
}


 UserService public class UserService extends ServiceImpl<UserMapper, User>

的区别

这两种写法的主要区别在于 服务实现的方式使用的框架/库,尤其是与 MyBatis-Plus(MP)有关。我们分别来看它们的区别:

1.传统的手动实现 UserService 接口的方式 (UserService.java 和 UserServiceImpl.java)

UserService.java(接口):

这个接口定义了对用户的基本操作,包括增删改查(CRUD)操作。它遵循了接口-实现的设计模式,使得服务层可以更加灵活地管理不同的实现类。

UserServiceImpl.java(实现类):

在这个实现类中,UserService 接口的所有方法都被手动实现。这些方法调用了 UserMapper 来执行数据库操作(基于 MyBatis)。通过 @Service 注解,它注册为 Spring 管理的 Bean,可以注入到其他类中使用。

这种写法的主要优点是:

  • 灵活性高:你可以自定义服务层的行为,比如添加复杂的业务逻辑、日志处理、权限校验等。
  • 扩展性好:可以随时改变实现,比如使用不同的数据库、使用其他的服务来实现不同的业务逻辑。

但是缺点是,你需要手动编写 UserService 的实现类,每个方法都需要显式地编写代码,可能会导致代码量增加。

2.基于 ServiceImpl 的简化写法 (UserService 扩展自 ServiceImpl)

UserService 类继承 ServiceImpl:

java

复制代码

public class UserService extends ServiceImpl<UserMapper, User> { // 不需要自己写增删改查的实现 }

这种写法依赖于 MyBatis-Plus(MP)的 ServiceImpl 类,它提供了默认的增删改查(CRUD)实现,因此不需要我们手动编写这些常见的操作。ServiceImpl 类本身已经实现了很多基础的操作,像 selectById、insert、deleteById 等方法,可以直接使用。

优点:

  • 简化代码:通过继承 ServiceImpl,你不需要编写常见的增删改查方法,减少了重复代码。
  • 易于实现:只需要扩展 ServiceImpl,并指定 UserMapper 和 User 类型,MyBatis-Plus 会自动提供增删改查的实现。

缺点:

  • 灵活性较低:如果你需要在服务层做额外的操作,比如复杂的业务逻辑、事务控制等,那么这时 ServiceImpl 的默认实现可能就不适用了,你可能需要手动覆写方法,或者自己处理事务和逻辑。
  • 适用场景有限:这种方式适合于基本的 CRUD 操作,如果业务逻辑复杂,则可能不适用。

总结对比:

特性

UserService + UserServiceImpl 方式

UserService 继承 ServiceImpl 方式

灵活性

高,可以自由添加复杂逻辑

低,适合简单的增删改查操作

代码量

需要手动实现所有方法,代码量较多

简化了代码,不需要手动实现增删改查方法

使用框架

传统的 Spring 和 MyBatis

依赖于 MyBatis-Plus 提供的 ServiceImpl

适用场景

适合需要自定义复杂逻辑的场景

适合基本的 CRUD 操作

扩展性

高,可以根据需要灵活扩展

低,基本只能进行简单的扩展

适用场景:

  • UserService + UserServiceImpl:如果你的业务逻辑复杂,需要自定义增删改查,或者需要处理复杂的事务和校验等情况,这种方式会更加适合。
  • 继承 ServiceImpl:如果只是进行简单的增删改查操作,并且不需要太多复杂的业务逻辑,可以使用这种方式,能大大减少代码量,快速实现。

总结来说,第二种方式(继承 ServiceImpl)是 MyBatis-Plus 的推荐做法,适用于简单的 CRUD 操作,而第一种方式则提供了更多的灵活性,适用于复杂的业务需求。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表