MyBatis-Plus 通用接口 Service 与 Mapper 全面实战指南

MyBatis-Plus之内置接口&Service接口&Mapper接口 Service CRUD 接口说明:通用 Service CRUD 封装接口,进一步封装 CRUD 采用get 查询单行remove 删除list 查询集合page 分页前缀命名方式区分Mapper层避免混淆,泛型T为任意实体对象建议如果存在自定义通用 Service 方法的可能,请创建自己的继承提供的基类对象Wrapper为。 阅读详情

以下是对 MyBatis-Plus 通用 Service 层接口(IService<T>) 和 通用 Mapper 接口(BaseMapper<T>) 的全面、实战级使用示例,涵盖所有常见、实用的持久化操作,每个示例都带有详细中文注释,可直接用于实际项目开发。


✅ MyBatis-Plus 通用接口 —— Service 与 Mapper 全面实战指南

💡 为什么使用通用接口?

  • ✅ 无需手写 SQL:单表 CRUD 开箱即用
  • ✅ 链式调用 + Lambda 条件构造器:安全高效
  • ✅ 内置分页、批量操作、逻辑删除、乐观锁支持
  • ✅ 减少样板代码,提升开发效率

📌 一、准备工作

1. 实体类 User.java

@Data
@TableName("t_user")
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    private Integer status; // 0-禁用, 1-启用
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

2. Mapper 接口(继承 BaseMapper)

public interface UserMapper extends BaseMapper<User> {
    // 可自定义扩展方法(如多表关联查询)
}

3. Service 接口(继承 IService)

public interface IUserService extends IService<User> {
    // 可自定义业务方法
}

4. Service 实现类(继承 ServiceImpl)

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    // 实现自定义方法
}

📌 二、通用 Mapper 接口(BaseMapper)常用方法示例

BaseMapper 提供了 30+ 个单表操作方法,以下是最常用、最具实战价值的示例:


1. 插入操作

// 插入单条记录(自动填充 createTime/updateTime/version 等)
User user = new User();
user.setName("张三").setAge(20).setEmail("zhangsan@example.com");
int rows = userMapper.insert(user); // 返回影响行数

System.out.println("插入成功,主键ID:" + user.getId()); // 主键自动回填

2. 根据主键查询

// 根据 ID 查询(逻辑删除字段自动过滤)
User user = userMapper.selectById(1L);

// 根据多个 ID 批量查询
List<Long> ids = Arrays.asList(1L, 2L, 3L);
List<User> users = userMapper.selectBatchIds(ids);

3. 根据条件查询(Wrapper)

// 查询 name = '张三' 的用户
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
    .eq(User::getName, "张三");

User user = userMapper.selectOne(wrapper); // 查询单条(超过1条会报错)

// 查询多条
List<User> userList = userMapper.selectList(wrapper);

// 查询总数
Long count = userMapper.selectCount(wrapper);

4. 分页查询

// 构造分页对象(当前页1,每页10条)
Page<User> page = new Page<>(1, 10);

// 构造查询条件
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
    .eq(User::getStatus, 1)
    .orderByDesc(User::getCreateTime);

// 执行分页查询
IPage<User> result = userMapper.selectPage(page, wrapper);

System.out.println("总记录数:" + result.getTotal());
System.out.println("当前页数据:" + result.getRecords());

5. 更新操作

// 根据主键更新(只更新非空字段)
User user = new User();
user.setId(1L);
user.setName("张三丰"); // 只更新 name 字段
user.setAge(null);      // 不更新 age(因为为 null)

int rows = userMapper.updateById(user); // UPDATE ... SET name=? WHERE id=?

// 根据条件更新(使用 UpdateWrapper)
LambdaUpdateWrapper<User> updateWrapper = Wrappers.lambdaUpdate(User.class)
    .set(User::getStatus, 0)           // 设置 status = 0
    .eq(User::getAge, 60);             // 条件:age = 60

int rows2 = userMapper.update(null, updateWrapper); // UPDATE ... SET status=0 WHERE age=60

6. 删除操作

// 根据主键删除(逻辑删除:UPDATE SET deleted=1)
int rows = userMapper.deleteById(1L);

// 根据多个主键批量删除(逻辑删除)
List<Long> ids = Arrays.asList(1L, 2L, 3L);
int rows2 = userMapper.deleteBatchIds(ids);

// 根据条件删除(物理删除!慎用!)
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
    .lt(User::getAge, 18); // 删除年龄小于18的用户

int rows3 = userMapper.delete(wrapper); // 物理删除!

⚠️ 注意:若配置了逻辑删除(@TableLogic),deleteById 等方法会转为更新 deleted 字段,而非物理删除。


7. 自定义 SELECT 字段(避免查大字段)

// 只查询 id, name, age 字段
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
    .select(User::getId, User::getName, User::getAge)
    .eq(User::getStatus, 1);

List<User> users = userMapper.selectList(wrapper);

📌 三、通用 Service 接口(IService)常用方法示例

IService 在 BaseMapper 基础上封装了更丰富的业务方法,更适合在 Service 层调用。


1. 插入操作(支持批量)

// 插入单条
// 假设有一个 User 实体对象
User user = new User();
user.setName("John Doe");
user.setEmail("john.doe@example.com");
// INSERT INTO user (name, email) VALUES ('John Doe', 'john.doe@example.com')
boolean success = userService.save(user); // 返回 boolean

// 批量插入(性能优化版,避免循环 insert)
// 假设有一组 User 实体对象
List<User> users = Arrays.asList(
        new User("Alice", "alice@example.com"),
        new User("Bob", "bob@example.com"),
        new User("Charlie", "charlie@example.com")
);
// 使用默认批次大小进行批量插入
INSERT INTO user (name, email) VALUES
('Alice', 'alice@example.com'),
('Bob', 'bob@example.com'),
('Charlie', 'charlie@example.com')
boolean result = userService.saveBatch(users); // 调用 saveBatch 方法,默认批次大小

1. saveOrUpdate 操作(支持批量)

// 根据实体对象的主键 ID 进行判断,存在则更新记录,否则插入记录。

// 假设有一个 User 实体对象,其中 id 是 TableId 注解的属性
User user = new User();
user.setId(1);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
boolean result = userService.saveOrUpdate(user); // 调用 saveOrUpdate 方法
// 生成的 SQL(假设 id 为 1 的记录已存在):
UPDATE user SET name = 'John Doe', email = 'john.doe@example.com' WHERE id = 1
// 生成的 SQL(假设 id 为 1 的记录不存在):
INSERT INTO user (id, name, email) VALUES (1, 'John Doe', 'john.doe@example.com')


// 假设有一组 User 实体对象,每个对象都有 id 属性
List<User> users = Arrays.asList(
        new User(1, "Alice", "alice@example.com"),
        new User(2, "Bob", "bob@example.com"),
        new User(3, "Charlie", "charlie@example.com")
);
// 使用默认批次大小进行批量修改插入
boolean result = userService.saveOrUpdateBatch(users); // 调用 saveOrUpdateBatch 方法,默认批次大小
// 生成的 SQL(假设 id 为 1 和 2 的记录已存在,id 为 3 的记录不存在):
UPDATE user SET name = 'Alice', email = 'alice@example.com' WHERE id = 1
UPDATE user SET name = 'Bob', email = 'bob@example.com' WHERE id = 2
INSERT INTO user (id, name, email) VALUES (3, 'Charlie', 'charlie@example.com')


2. 更新操作(支持条件更新 + 批量)

// 根据主键更新(支持自动填充 + 乐观锁)
User user = new User();
user.setId(1);
user.setEmail("updated.email@example.com");
// UPDATE user SET email = 'updated.email@example.com' WHERE id = 1
boolean success = userService.updateById(user); // 自动处理版本校验

// 假设有一组 User 实体对象,批量更新
List<User> users = Arrays.asList(
        new User(1, null, "new.email1@example.com"),
        new User(2, null, "new.email2@example.com")
);
// UPDATE user SET email = 'new.email1@example.com' WHERE id = 1
// UPDATE user SET email = 'new.email2@example.com' WHERE id = 2
boolean result = userService.updateBatchById(users); // 调用 updateBatchById 方法,默认批次大小
// 调用 updateBatchById 方法,指定批次大小
// -- 第一批次
UPDATE user SET email = 'new.email1@example.com' WHERE id = 1
// -- 第二批次
UPDATE user SET email = 'new.email2@example.com' WHERE id = 2
boolean result = userService.updateBatchById(users, 1); 

// 条件更新,只设置条件,不使用 set 设置更新字段
LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate(User.class)
    .eq(User::getStatus, 0)
    .lt(User::getAge, 18);
// UPDATE user SET name = 'Updated Name' WHERE age < 18
boolean updateSuccess = userService.update(user, wrapper);

// 批量更新(根据实体列表,每个实体按主键更新)
List<User> updateList = Arrays.asList(
    new User().setId(1L).setName("张三").setAge(20),
    new User().setId(2L).setName("李四").setAge(25)
);

boolean batchUpdate = userService.updateBatchById(updateList); // 按主键批量更新

3. 查询操作(增强版)

// 查询单个
// 根据指定条件查询符合条件的记录,参考 https://baomidou.com/guides/data-interface/#get
// 假设要查询 ID 为 1 的用户     SELECT * FROM user WHERE id = 1
User user = userService.getById(1); // 调用 getById 方法
if (user != null) {
    System.out.println("User found: " + user);
} else {
    System.out.println("User not found.");
}
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
// SELECT * FROM user WHERE name = '张三'
User user = userService.getOne(
    Wrappers.lambdaQuery(User.class).eq(User::getName, "张三"),
    false // 是否抛异常(true=超过1条抛异常,false=取第一条)
);


// 查询列表,参考 https://baomidou.com/guides/data-interface/#list
// 查询所有用户   SELECT * FROM user
List<User> users = userService.list(); // 调用 list 方法
for (User user : users) {
    System.out.println("User: " + user);
}
// 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25 并且 status = 1
// SELECT * FROM user WHERE age > 25 AND status = 1
List<User> users = userService.list(
    Wrappers.lambdaQuery(User.class).gt(User::getAge, 25).eq(User::getStatus, 1)
);
// 假设有一组 ID 列表,批量查询用户
// SELECT * FROM user WHERE id IN (1, 2, 3)
List<Integer> ids = Arrays.asList(1, 2, 3);
Collection<User> users = userService.listByIds(ids); // 调用 listByIds 方法


// 自 3.4.3.2 开始,返回值从 int 修改为 long
// 查询总数,参考 https://baomidou.com/guides/data-interface/#count
// 查询用户表中的总记录数
// SELECT COUNT(*) FROM user
Long totalUsers = userService.count(); // 调用 count 方法
// 根据 Wrapper 条件,查询总记录数
// SELECT COUNT(*) FROM user WHERE age >= 18
Long count = userService.count(
        Wrappers.lambdaQuery(User.class).ge(User::getAge, 18)
);

4. 分页查询(推荐在 Service 层使用)

// 构造分页对象
// 假设要进行无条件的分页查询,每页显示10条记录,查询第1页
IPage<User> page = new Page<>(1, 10);
// SELECT * FROM user LIMIT 10 OFFSET 0
IPage<User> userPage = userService.page(page); // 调用 page 方法

// 构造条件
// 假设有一个 LambdaQueryWrapper 对象,设置查询条件为 age > 25,进行有条件的分页查询
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
    .gt(User::getAge, 25)
    .eq(User::getStatus, 1);

// 执行分页(返回 IPage,含 records, total, pages 等)
// SELECT * FROM user WHERE age > 25 and status = 1 LIMIT 10 OFFSET 0
IPage<User> result = userService.page(page, wrapper);
List<User> userList = result.getRecords();
long total = result.getTotal();

// 或者使用自定义分页方法(更灵活)
public IPage<User> searchUsers(String name, Integer status, Integer current, Integer size) {
    IPage<User> page = new Page<>(current, size);
    LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
        .like(StringUtils.isNotBlank(name), User::getName, name)
        .eq(status != null, User::getStatus, status)
        .orderByDesc(User::getCreateTime);

    return this.page(page, wrapper);
}

5. 删除操作(安全封装)

// 根据主键删除(逻辑删除)
boolean deleted = userService.removeById(1L);

// 根据多个主键删除(逻辑删除)
List<Long> ids = Arrays.asList(1L, 2L, 3L);
boolean batchDeleted = userService.removeByIds(ids);

// 根据条件删除
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
    .isNull(User::getEmail); // 删除没有邮箱的用户

boolean conditionDeleted = userService.remove(wrapper);

✅ 推荐:在 Service 层统一处理删除逻辑,避免 Controller 直接调用 Mapper。


6. 链式调用(LambdaQueryChainWrapper / LambdaUpdateChainWrapper)

// 查询链式调用(等价于 Wrapper,但更流畅)
List<User> users = userService.lambdaQuery()
    .eq(User::getStatus, 1)
    .ge(User::getAge, 18)
    .orderByDesc(User::getCreateTime)
    .list();

// 更新链式调用
boolean updated = userService.lambdaUpdate()
    .set(User::getStatus, 0)
    .lt(User::getAge, 18)
    .update();

7. 批量操作(性能优化)

// 批量插入(推荐用于 > 100 条数据)
List<User> bigList = generateBigUserList(); // 假设有1000条
boolean saved = userService.saveBatch(bigList, 1000); // 分批提交,每批1000条

// 批量更新(按主键)
boolean updated = userService.updateBatchById(bigList, 500); // 每批500条

// 批量删除(按主键)
boolean deleted = userService.removeByIds(idList, 200); // 每批200条

✅ saveBatch / updateBatchById / removeByIds 第二个参数是批次大小,避免一次性提交过多导致内存溢出或事务超时。


📌 四、Service 层自定义方法封装示例(实战推荐)

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    /**
     * 根据用户名模糊查询 + 分页
     */
    @Override
    public IPage<User> searchByName(String name, Page<User> page) {
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
            .like(StringUtils.isNotBlank(name), User::getName, name)
            .eq(User::getStatus, 1)
            .orderByDesc(User::getCreateTime);

        return this.page(page, wrapper);
    }

    /**
     * 启用多个用户(批量更新状态)
     */
    @Override
    public boolean enableUsers(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) return true;

        LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate(User.class)
            .set(User::getStatus, 1)
            .in(User::getId, ids);

        return this.update(null, wrapper);
    }

    /**
     * 安全更新用户信息(带乐观锁)
     */
    @Override
    public boolean updateUserSafely(Long id, String name, Integer version) {
        User user = new User();
        user.setId(id);
        user.setName(name);
        user.setVersion(version); // 设置当前版本号

        return this.updateById(user); // 自动处理版本校验
    }

    /**
     * 统计各年龄段用户数量
     */
    @Override
    public List<Map<String, Object>> countByAgeGroup() {
        return this.listMaps(
            Wrappers.lambdaQuery(User.class)
                .select("CASE WHEN age < 18 THEN '未成年' " +
                        "WHEN age BETWEEN 18 AND 60 THEN '成年' " +
                        "ELSE '老年' END as age_group, COUNT(*) as count")
                .groupBy("age_group")
        );
    }
}

📌 五、Controller 层调用示例(完整流程)

@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private IUserService userService;

    /**
     * 分页查询用户
     */
    @GetMapping("/page")
    public Result<IPage<User>> getUserPage(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String name) {

        Page<User> page = new Page<>(current, size);
        IPage<User> result = userService.searchByName(name, page);

        return Result.success(result);
    }

    /**
     * 新增用户
     */
    @PostMapping
    public Result<String> addUser(@RequestBody User user) {
        boolean saved = userService.save(user);
        return saved ? Result.success("新增成功") : Result.error("新增失败");
    }

    /**
     * 批量启用用户
     */
    @PutMapping("/enable")
    public Result<String> enableUsers(@RequestBody List<Long> ids) {
        boolean success = userService.enableUsers(ids);
        return success ? Result.success("启用成功") : Result.error("启用失败");
    }

    /**
     * 删除用户(逻辑删除)
     */
    @DeleteMapping("/{id}")
    public Result<String> deleteUser(@PathVariable Long id) {
        boolean deleted = userService.removeById(id);
        return deleted ? Result.success("删除成功") : Result.error("删除失败");
    }
}

📌 六、注意事项与最佳实践

✅ 最佳实践:

  1. 优先使用 Service 层方法(如 save, updateById, page),而非直接调用 Mapper。
  2. 批量操作指定批次大小,避免 OOM 或长事务。
  3. 更新操作优先使用 updateById(entity),以便触发乐观锁和自动填充。
  4. 查询时使用 .select(字段) 避免查大字段(如 text/blob)。
  5. 动态条件使用条件函数:.eq(condition, column, value)。
  6. 分页查询在 Service 层封装,便于统一处理权限、租户等逻辑。

⚠️ 注意事项:

  1. selectOne 超过1条会抛异常,不确定唯一性时用 list().get(0) 或 getOne(wrapper, false)。
  2. 逻辑删除后 selectById 查不到数据,需使用 selectOne(new QueryWrapper().eq("id", id).last("OR deleted=1")) 查询已删除数据。
  3. saveBatch 默认批次大小是 1000,大数据量建议手动指定。
  4. update(null, wrapper) 不触发自动填充和乐观锁,优先使用 update(entity, wrapper)。
  5. 复杂查询(多表关联、子查询)建议写 XML 或 @Select 注解,保持 Wrapper 用于单表。

✅ 七、总结对比表

操作类型Mapper 方法Service 方法推荐使用场景
插入单条insert(entity)save(entity)通用
批量插入循环调用 insertsaveBatch(list, batchSize)数据量 > 100
更新(按主键)updateById(entity)updateById(entity)触发填充/乐观锁
更新(按条件)update(null, wrapper)update(null, wrapper)批量更新状态等
查询单条selectById(id)getById(id)通用
查询列表selectList(wrapper)list(wrapper)通用
分页查询selectPage(page, wrapper)page(page, wrapper)推荐在 Service 层使用
删除(逻辑)deleteById(id)removeById(id)通用
批量删除deleteBatchIds(ids)removeByIds(ids, batchSize)数据量大时指定批次

📌 官方文档参考:

  • BaseMapper: https://baomidou.com/pages/49cc81/
  • IService: https://baomidou.com/pages/49cc81/#iservice-crud-封装

通过以上详尽示例,你可以在实际项目中高效、规范地使用 MyBatis-Plus 的通用 Mapper 和 Service 接口,大幅提升开发效率与代码质量!

💡 提示:结合 BaseEntity + LambdaQueryWrapper + IService,可实现 90% 以上单表操作零 SQL 开发!复杂场景再补充 XML 或自定义 SQL。

根据mybatis-plus生成器自动生成:Entity、Mapper、Mapper XML、Service、Controller AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。 某天我发现了这种方式,使用这种方式去创建项目练习项目真是太方便啦。 官方使用介绍:https://mp.baomidou.com/guide/generator.html#%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B 下面是我根 阅读详情

相关推荐

从零编写linux0.11 - 第二章 内核初始化

编程环境:Ubuntu Kylin 16.04 代码仓库:https://gitee.com/AprilSloan/linux0.11-project linux0.11源码下载(不能直接编译,需进行修改) 1.添加内核 进入内核后也不是马上进入main函数,上一章只是暂时设置gdt,此外还要设置idt和其他的一些初始化操作,这些内容也要使用汇编进行编写,此处采用AT&T格式的汇编。 以下为head.s的内容,为了简单起见,内容还是一个死循环。 .globl startup_32 startup_3

皓空Fly的博客 1262

MyBatis-Plus【通用Mapper篇】

MP-通用Mapper 一、通用Mapper二、使用方式1、源码分析:one:Insert 插入方法:two:Delete 删除方法:three:Update 修改方法:four: Select 查询方法 一、通用Mapper 在MyBatis-Plus里面,可以实现对数据库的CRUD操作,官方对通用Mapper的解释如下说明: 通用 CRUD 封装BaseMapper (opens new window)接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注

mmklo的博客 1万+

泛微E9与金蝶云星空单点登录集成实战指南

本文详细介绍了泛微E9与金蝶云星空单点登录(SSO)集成的实战指南,包括前期准备、核心代码实现、常见问题排查及安全加固建议。通过集成,企业可实现一次登录全网通行,显著提升工作效率和安全性。文章特别强调了签名生成机制和跳转URL构造的关键技巧,帮助开发者避免常见错误。

weixin_30689307的博客 534

mybatisPlus中 Mapper层以及Service层的方法 整理分类 以及代码实操

是一个基于MyBatis的增强工具,旨在简化开发、提高效率。它提供了通用的mapper和service,可以在不编写任何SQL语句的情况下,快速实现对单表的CRUD、批量、逻辑删除、分页等操作。

m0_58462450的博客 6056

双目相机立体匹配算法概述(含Python代码)

立体匹配任务是计算机视觉中的一个重要问题,旨在从一对具有相同场景的图像中估计每个像素的视差(disparity)。本文对现有的传统算法和深度学习算法进行了综述,以便于各位选择合适的立体匹配算法用于深度估计或三维建模。

m0_59257547的博客 8291

谷粒商城学习笔记-15-数据库初始化

这一节的主要内容是把创建对应的数据库和数据库表。

epitomizelu的专栏 1438

MyBatis-Plus【通用Service篇】

MP-通用Service一、何为通用Service二、如何使用1、编写一个接口Service,继承IService接口2、编写一个实现类去实现接口并继承ServiceImpl类三、核心方法介绍1、Save 新增方法2、SaveOrUpdate 新增或修改方法3、Remove删除方法4、Update修改方法5、查询操作 一、何为通用Service 官方给出的解释: 通用 Service CRUD 封装IService (opens new window)接口,进一步封装 CRUD 采用 get 查询单行

mmklo的博客 1万+

华为OD机试真题 新系统 9月16号 【统计特殊数字】

华为OD新系统机试真题【统计特殊数字】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【统计特殊数字】。

qq_45776114的博客 763

Mybatis-plus的Service

Service 1、通用Service接口 可以看官网的CRUD接口 https://baomidou.com/pages/49cc81/ 在example包下创建接口service.UserService package com.example.service.service; import com.baomidou.mybatisplus.extension.service.IService; import com.example.pojo.User; public interface UserS

qq_56299755的博客 4385

《电磁兼容设计》专栏说明

本专栏自2024年1月起开始更新,仅设此一个电磁兼容相关知识专栏,并将一直持续更新下去,无期限

linkking27的博客 791

【人工智能】Warp 终端完整汉化方案(2026最新)

截至2026年5月,,仅完成了中文、日文、韩文等东亚语言的字符渲染支持,设置面板中无官方语言切换选项,相关中文UI功能需求仍在官方GitHub开源仓库的需求迭代队列中。

奶爸的编程之路,也就一周冷个三天 3100

【MyBatis Plus】Service && Mapper内置接口讲解

该博文主要写给那些刚学习使用mybatis-plus的同志,不知道mybatis-plus有那些内置的方法的,有了这篇文章大概对mybatis-plus所提供的方法有一定的认知和理解,相信在项目的运用中可以更加的得心应手!!

万维网连五洲,二进制写尽天下事,喜欢结识新伙伴寻找志同道合的朋友,欢迎一起探讨学习 3374

QNX系统中的密码哈希格式——数据安全深度分析

综上所述,QNX系统中的Shadowed密码哈希格式提供了一种有效的数据安全机制,能够保护用户密码的安全性。通过将用户密码的哈希值存储在系统文件中,并结合哈希算法和盐值的使用,可以有效地防止明文密码泄露和密码破解。密码哈希是一种常用的安全技术,用于将用户密码转换为不可逆的哈希值,以保护用户的敏感信息。在QNX操作系统中,存在一种称为Shadowed密码哈希格式的机制,用于存储用户密码的安全散列值。当用户登录系统时,系统会将用户输入的密码与保存的哈希值进行比对,以验证密码的正确性。在上述代码中,首先使用。

UneDatabase的博客 251

关于mybatis-plus中Service和Mapper的分析

研究背景: 最近在写sql业务逻辑的时候,发现service也可以构建sql。然后查了一下,发现service比常用的mapper功能更多 开始分析: 在后端开发过程中,如果有用到mybatis-plus,会发现在其内部存在着两种数据库操作接口,Iservice和BaseMapper,如果只是用增删改查会发现两者的功能是一致的,就是方法名称有所不同。对此,首先看一下这两个类的继承关系。 先演示一下基本开发中的继承关系,手动创建的Service继承于ServiceImpl,并加载自己创建的Mapper @S

baiwenjiebwj的博客 5927

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain&#39;s apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath(&#39;DeepLearnToolbox&#39;));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand(&#39;state&#39;,0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W&#39;); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand(&#39;state&#39;,0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = &#39;sigm&#39;;%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, &#39;Too big error&#39;);```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand(&#39;state&#39;,0)sae = saesetup([784 100]);sae.ae{1}.activation_function = &#39;sigm&#39;;sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)&#39;)% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = &#39;sigm&#39;;nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, &#39;Too big error&#39;);```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x&#39;,28,28,60000))/255;test_x = double(reshape(test_x&#39;,28,28,10000))/255;train_y = double(train_y&#39;);test_y = double(test_y&#39;);%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you&#39;ll get around 1.2% errorrand(&#39;state&#39;,0)cnn.layers = { struct(&#39;type&#39;, &#39;i&#39;) %input layer struct(&#39;type&#39;, &#39;c&#39;, &#39;outputmaps&#39;, 6, &#39;kernelsize&#39;, 5) %convolution layer struct(&#39;type&#39;, &#39;s&#39;, &#39;scale&#39;, 2) %sub sampling layer struct(&#39;type&#39;, &#39;c&#39;, &#39;outputmaps&#39;, 12, &#39;kernelsize&#39;, 5) %convolution layer struct(&#39;type&#39;, &#39;s&#39;, &#39;scale&#39;, 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, &#39;Too big error&#39;);```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, &#39;Too big error&#39;);%% ex2 neural net with L2 weight decayrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex3 neural net with dropoutrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex4 neural net with sigmoid activation functionrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.activation_function = &#39;sigm&#39;; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex5 plotting functionalityrand(&#39;state&#39;,0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = &#39;softmax&#39;; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand(&#39;state&#39;,0)nn = nnsetup([784 20 10]); nn.output = &#39;softmax&#39;; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

MyBatis-Plus中的Service接口:全面解析与实战指南

首先,我们定义一个Service接口,继承自// 可以在这里定义自定义的业务方法 }// 可以在这里定义自定义的业务方法 }// 可以在这里定义自定义的业务方法 }// 可以在这里定义自定义的业务方法 }// 可以在这里定义自定义的业务方法 }IService;// 可以在这里定义自定义的业务方法接下来,我们定义一个Mapper接口,继承自// 可以在这里定义自定义的SQL方法 }// 可以在这里定义自定义的SQL方法 }// 可以在这里定义自定义的SQL方法 }

xycxycooo的博客 2283

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

MyBatis-Plus 之通用Service

MyBatis-Plus 之通用Service 首先创建一个数据库表,如下图所示: 然后创建一个Spring Boot项目,pom.xml和配置如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sche

kaven 2万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

MyBatis-Plus Service CRUD 接口 跟Mapper CRUD 接口区别

1.Service CRUD 接口 说明: 通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用get 查询单行remove 删除list 查询集合page 分页前缀命名方式区分Mapper层避免混淆, 泛型T为任意实体对象 建议如果存在自定义通用 Service 方法的可能,请创建自己的IBaseService继承Mybatis-Plus提供的基类 对象Wrapper为条件构造器 使用示例 //1.在自身的实现类中直接用Serv...

qq_35921925的博客 5533

MyBatis-Plus通用Service

MyBatis-Plus通用Service是对BaseMapper的增强封装,提供标准化的业务层CRUD操作,通用Service层通过封装重复逻辑,让开发者专注于核心业务开发。

2401_84284464的博客 1125

7.MyBatis-Plus 通用Service和通用Mapper之间的关系

MyBatis-Plus 通用Service和通用Mapper之间的关系 学了MyBatis-Plus之后发现通用Service和通用Mapper实现的功能好像都是一样的,但是其中的方法名又不同,因此想搞清楚他们之间的关系。 项目结构如下,主要关注department相关的部分 DepartmentMapper接口继承BaseMapper接口 DepartmentServiceImpl继承ServiceImpl对象并实现DepartmentService接口 首先摆出官网上对通用Service和通用Map

Snakewood的博客 5625

黑马点评:MyBatis-Plus Service 层继承与实现原理详解

摘要:在MyBatis-Plus框架中,UserServiceImpl同时继承ServiceImpl和实现IUserService接口。继承ServiceImpl可直接获得MyBatis-Plus提供的全套CRUD基础操作,避免重复编写;实现IUserService则定义了项目特有的业务方法规范,确保实现类必须提供这些方法。IUserService本身又继承IService接口,合并了通用CRUD和自定义业务方法。

yurenpai的博客 870

mybatis plus 使用函数_关于mybatis-plus中Service和Mapper的分析

关于mybatis-plus中Service和Mapper的分析在后端开发过程中,如果有用到mybatis-plus,肯定会发现在其内部存在着两种数据库操作接口,Iservice和BaseMapper,如果只是用增删改查会发现两者的功能是一致的,除了方法名称有所不同,其他的基本相似。对此,我颇为好奇,便打开两个接口的源码进行对比。先演示一下基本开发中的继承关系,手动创建的Service继承于Ser...

weixin_42514654的博客 2871

Mybatis-Plus的Mapper,Service

和。虽然它们都与数据库操作相关,但在 Spring/Spring Boot 的分层架构中,它们的却有着本质的区别。

weixin_63031917的博客 376

MyBatis-Plus与TK-Mapper代码生成器实战指南

ORM框架是Java后端开发中处理数据库操作的核心组件,通过对象关系映射技术简化了数据库交互。MyBatis-Plus作为MyBatis的增强工具,配合TK-Mapper的通用Mapper实现,可以大幅提升开发效率。代码自动生成技术通过解析数据库表结构,自动创建实体类、Mapper接口及XML映射文件,减少重复劳动。在Spring Boot项目中,通过配置MyBatis-Plus Generator和TK-Mapper插件,开发者可以快速生成基础CRUD代码,并支持Lombok注解、分页查询等高级功能。这种

cnracht8153的博客 344

mybatis-plus生成mapper扩展文件

阅读提示   具有mybatis基础,熟练使用mybatis-plus。 概述   我们都知道,mybatis-plus是一个mybatis的增强工具,为简化开发、提高效率而生,我们经常使用mybatis-plus生成controller、service、mapper等文件,对于简单的curd,可以直接使用mybatis-plus封装好的方法。   然而,我们经常有这样那样的需求,需要额外编写sq...

onion的博客 6019

MyBatis-Plus之通用service

说明:通用service用前缀命名方式区分Mapper层避免混淆,get:查询单行,remove:删除,list:查询集合,page:分页MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑IService: 二、创建自己的service接口和实现类 1.UserService接口 2.UserServiceImpl 三、测试类 1.查询总记录数 2.批量插入 插入的五条数据:name:szy0 szy1 szy2 szy3 szy4

2201_76081438的博客 1271
上一篇: 具有实际开发参考意义的 MyBatis-Plus BaseEntity 基类示例
下一篇: 符合企业级开发规范的 Spring Boot + MyBatis-Plus 标准 MVC 结构完整示例
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值