当前位置: 首页 > news >正文

MyBatis如何实现分页

文章目录

    • MyBatis分页方式对比
    • 使用数据库厂商提供的分页查询语句
    • 通过自定义 SQL 实现分页逻辑
      • 1. 使用 RowBounds 实现分页
      • 2. 使用 PageHelper 实现分页
    • 数组分页
    • 使用 MyBatis-Plus 进行分页
    • MyBatis物理分页和逻辑分页
    • MyBatis 手写一个 拦截器分页

在 MyBatis 中实现分页通常有两种方式:使用数据库厂商提供的分页查询语句(如 MySQL 的 LIMIT)或者通过自定义 SQL 来实现分页逻辑等

MyBatis分页方式对比

MyBatis提供了多种分页方式,每种方式都有其特定的应用场景和优缺点。以下是对MyBatis中几种常见分页方式的对比:

  1. 基于RowBounds的分页(逻辑分页):
    ○ 原理:执行完整的SQL查询,将结果集全部加载到内存中,然后根据RowBounds指定的偏移量和限制数进行分页处理。
    ○ 优点:减少IO次数,对于频繁访问且数据量较小的情况较为适合。
    ○ 缺点:当数据量非常大时,容易造成内存溢出,性能下降。
  2. 基于数据库的分页(物理分页):
    ○ 原理:在SQL查询语句中使用LIMIT和OFFSET关键字来实现分页,直接在数据库层面进行分页处理。
    ○ 优点:适用于大数据量的情况,避免了内存溢出的风险,性能较好。
    ○ 缺点:需要数据库支持LIMIT和OFFSET语法,不同数据库厂商的语法可能有所不同。
  3. 基于插件的分页:
    ○ 原理:MyBatis提供了插件机制,通过自定义插件来拦截SQL语句的执行,并在查询结果返回之前添加分页逻辑。
    ○ 优点:插件封装了分页的具体实现细节,使用起来简单方便,适用于多种分页需求。
    ○ 缺点:可能需要一定的开发成本来编写和维护插件。
  4. 数组分页:
    ○ 原理:首先查询出全部数据,然后在Java代码的List中截取需要的部分。
    ○ 优点:实现简单。
    ○ 缺点:当数据量很大时,会消耗大量内存,并可能导致性能问题。
    综上所述,选择哪种分页方式取决于具体的应用场景和数据量大小。对于小数据量或频繁访问的场景,逻辑分页(如RowBounds)可能是一个不错的选择。而对于大数据量或需要高效分页的场景,物理分页(如基于数据库的分页)或基于插件的分页可能更为合适。在实际应用中,还需要考虑数据库类型、系统性能、开发成本等因素来做出决策。

使用数据库厂商提供的分页查询语句

许多数据库厂商都提供了用于分页的特定语法,如 MySQL 的 LIMIT、Oracle 的 ROWNUM、SQL Server 的 OFFSET FETCH 等。你可以直接在 SQL 查询语句中使用这些语法来实现分页,然后将分页参数传递给 MyBatis 的方法即可。
示例(MySQL):

<select id="getUserList" resultType="User">SELECT * FROM usersLIMIT #{offset}, #{pageSize}
</select>
List<User> getUserList(@Param("offset") int offset, @Param("pageSize") int pageSize);

通过自定义 SQL 实现分页逻辑

如果你使用的数据库不支持特定的分页语法,或者想要更多灵活性,你可以通过自定义 SQL 实现分页逻辑。通常,你需要通过 RowBounds 或 PageHelper 来实现分页。

1. 使用 RowBounds 实现分页

原理:通过RowBounds实现分页和通过数组方式分页原理差不多,都是一次获取所有符合条件的数据,然后在内存中对大数据进行操作,实现分页效果。只是数组分页需要我们自己去实现分页逻辑,这里更加简化而已。
存在问题:一次性从数据库获取的数据可能会很多,对内存的消耗很大,可能导师性能变差,甚至引发内存溢出。
适用场景:在数据量很大的情况下,建议还是适用拦截器实现分页效果。RowBounds建议在数据量相对较小的情况下使用。
RowBounds分页是Mybatis提供的一种分页方式,其原理主要是在执行SQL查询后,将返回的所有结果集加载到内存中,然后在内存中根据指定的偏移量(offset)和限制数(limit)进行分页处理。
具体来说,当我们在Mybatis的Mapper接口中调用查询方法时,可以传入一个RowBounds对象作为参数。这个RowBounds对象包含了分页所需的信息,比如当前页码、每页显示的记录数等。在执行查询时,Mybatis会首先执行完整的SQL查询语句,获取到所有满足条件的结果集。然后,Mybatis会根据RowBounds对象中指定的偏移量和限制数,在内存中对这些结果集进行截取,从而得到当前页需要展示的数据。
需要注意的是,RowBounds分页方式是一种逻辑分页,即在内存中进行分页处理。当数据量非常大时,这种方式可能会导致内存溢出的问题。因此,对于大数据量的分页需求,建议使用物理分页方式,即在SQL查询语句中添加LIMIT和OFFSET子句,直接在数据库层面进行分页处理。
此外,Mybatis还提供了另一种分页插件PageHelper,它使用拦截器的方式实现了物理分页。PageHelper插件会在Mybatis执行SQL查询之前,自动根据传入的分页参数改写SQL语句,添加LIMIT和OFFSET子句,从而实现物理分页。这种方式可以更有效地处理大数据量的分页需求,避免内存溢出的问题。
List getUserList(RowBounds rowBounds);
RowBounds rowBounds = new RowBounds(offset, pageSize);
List users = sqlSession.selectList(“getUserList”, rowBounds);

2. 使用 PageHelper 实现分页

PageHelper的分页原理主要基于MyBatis的插件机制。具体来说,PageHelper内部实现了一个PageInterceptor拦截器,这个拦截器会在MyBatis执行SQL查询之前进行拦截。
当我们在代码中调用PageHelper的startPage方法时,它会在当前线程上下文中设置一个ThreadLocal变量,用于保存分页的参数,如当前页码、每页显示的数量等。
随后,当MyBatis执行SQL查询时,PageInterceptor拦截器会拦截到这一操作。拦截器会从ThreadLocal中获取到分页参数,并根据这些参数来改写原始的SQL语句,添加LIMIT和OFFSET子句,以实现分页查询。
改写后的SQL语句会被发送到数据库执行,数据库返回的结果集就是根据分页参数查询得到的结果。
最后,PageInterceptor拦截器会将ThreadLocal中的分页参数清除,避免对后续操作产生影响。
通过这种方式,PageHelper实现了对MyBatis查询结果的分页处理,而无需修改原有的SQL语句、Mapper接口和XML文件,因此具有无侵入性和易用性。同时,由于分页操作是在数据库层面进行的,因此也具有较高的性能。
需要注意的是,PageHelper使用了ThreadLocal来保存分页参数,因此分页参数是与线程绑定的,这意味着不同的线程之间不会共享分页参数,从而保证了分页的准确性和独立性。
总的来说,PageHelper通过拦截MyBatis的SQL查询操作,并在查询语句中添加LIMIT和OFFSET子句,实现了对查询结果的分页处理,从而简化了分页操作的实现过程,提高了开发效率。
PageHelper 是一个 MyBatis 的分页插件,可以简化分页操作。
首先,在 MyBatis 的配置文件中配置 PageHelper 插件:

<plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="helperDialect" value="mysql"/></plugin>
</plugins>
然后,在需要分页的查询方法中添加分页参数:
List<User> getUserList(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.getUserList(pageNum, pageSize);
这两种方式都可以实现分页查询,你可以根据实际需求选择合适的方式。

数组分页

使用数组进行分页通常意味着在数据库中获取所有数据,然后在应用程序中对数据进行分割和展示。这种方法在数据量较小且不频繁变化时比较适用,但在数据量较大时可能会影响性能。下面是一个简单的 Java 代码示例,演示如何使用数组进行分页:

import java.util.ArrayList;
import java.util.List;public class PaginationWithArrayExample {// 模拟从数据库中获取数据的方法,返回所有数据public List<String> fetchDataFromDatabase() {// 这里假设从数据库中获取了一些数据,实际情况根据需求修改List<String> dataList = new ArrayList<>();for (int i = 1; i <= 100; i++) {dataList.add("Data " + i);}return dataList;}// 根据页码和每页显示数量,从数据集中获取指定页的数据public List<String> getDataForPage(List<String> dataList, int pageNumber, int pageSize) {int startIndex = (pageNumber - 1) * pageSize;int endIndex = Math.min(startIndex + pageSize, dataList.size());if (startIndex >= endIndex) {return new ArrayList<>(); // 如果起始索引大于等于结束索引,返回空列表}return dataList.subList(startIndex, endIndex);}// 示例用法public static void main(String[] args) {PaginationWithArrayExample example = new PaginationWithArrayExample();List<String> dataList = example.fetchDataFromDatabase(); // 模拟从数据库中获取数据int pageNumber = 2; // 第2页int pageSize = 10; // 每页显示10条数据List<String> pageData = example.getDataForPage(dataList, pageNumber, pageSize);// 输出当前页的数据System.out.println("Page " + pageNumber + " data:");for (String data : pageData) {System.out.println(data);}}
}

在这个示例中,fetchDataFromDatabase 方法模拟从数据库中获取数据,返回一个包含了所有数据的列表。然后,getDataForPage 方法根据传入的页码和每页显示数量,从数据集中获取指定页的数据,返回一个包含了当前页数据的子列表。在示例的 main 方法中,演示了如何使用这两个方法来获取指定页的数据,并将其打印输出。

使用 MyBatis-Plus 进行分页

MyBatis-Plus进行分页的原理主要依赖于其内置的分页插件和Page对象。
首先,MyBatis-Plus提供了分页插件,该插件会在MyBatis执行SQL查询之前进行拦截。当使用MyBatis-Plus进行分页查询时,分页插件会自动识别分页相关的参数,并对原始的SQL语句进行改写,添加LIMIT和OFFSET子句,以实现物理分页。
其次,MyBatis-Plus中的Page对象用于表示分页信息。这个对象包含了当前页码、每页记录数、总记录数等信息。在进行分页查询时,可以通过传递Page对象给MyBatis-Plus的查询方法,来告诉MyBatis-Plus需要进行分页查询以及分页的具体参数。
当MyBatis-Plus执行分页查询时,它会根据Page对象中的信息生成对应的分页SQL语句,并通过数据库执行这个语句。数据库会根据LIMIT和OFFSET子句返回指定范围的结果集。
最后,MyBatis-Plus将查询结果封装到Page对象中,并返回给调用者。这个Page对象不仅包含了实际的查询结果列表,还包含了分页相关的信息,如总记录数、总页数等。这使得分页操作更加方便,同时也提高了代码的可维护性。
需要注意的是,MyBatis-Plus的分页实现是基于物理分页的,即直接在数据库层面进行分页处理,而不是在内存中处理。这种方式在处理大数据量时性能较好,避免了内存溢出的风险。
总结来说,MyBatis-Plus进行分页的原理是通过分页插件和Page对象来实现物理分页,通过在SQL语句中添加LIMIT和OFFSET子句来获取指定范围的结果集,并将结果封装到Page对象中返回给调用者。
MyBatis-Plus 是 MyBatis 的增强工具包,提供了很多便捷的功能,其中包括了分页功能。MyBatis-Plus 的分页功能可以轻松地实现物理分页,让分页操作变得更加简单。
首先,你需要在项目中引入 MyBatis-Plus 的依赖。在 Maven 项目中,你可以在 pom.xml 文件中添加如下依赖:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>latest_version</version>
</dependency>

接下来,假设你有一个 UserMapper 接口,用于操作用户信息。你可以在该接口中直接定义分页查询的方法,无需额外编写 XML 映射文件。

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;public interface UserMapper extends BaseMapper<User> {Page<User> selectUserPage(Page<User> page);
}

在该方法中,我们使用了 MyBatis-Plus 提供的 Page 类来实现分页。Page 类继承自 MyBatis 的 RowBounds 类,它除了包含分页信息外,还包含了分页查询返回的数据列表。
然后,你可以在 Service 层中调用这个方法来进行分页查询:

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public Page<User> getUserPage(int pageNum, int pageSize) {Page<User> page = new Page<>(pageNum, pageSize);return userMapper.selectUserPage(page);}
}

在这个示例中,我们创建了一个新的 Page 对象,并传入了当前页码和每页显示数量。然后调用 selectUserPage 方法进行分页查询,并将结果返回。
最后,在 Controller 层中调用 Service 方法并将结果返回给前端即可完成分页查询的操作。

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/users")public Page<User> getUserPage(@RequestParam(defaultValue = "1") int pageNum,@RequestParam(defaultValue = "10") int pageSize) {return userService.getUserPage(pageNum, pageSize);}
}

通过 MyBatis-Plus,你可以很方便地实现分页查询,而无需编写繁琐的 SQL 语句或者额外的 XML 映射文件。

MyBatis物理分页和逻辑分页

MyBatis中的物理分页和逻辑分页是两种不同的分页方式,它们在实现方式和性能上有显著的区别。
物理分页:
物理分页是在数据库层面上实现的分页,它依赖于数据库自身提供的分页功能。在MyBatis中,物理分页通常是通过在SQL语句中添加LIMIT和OFFSET子句来实现的。这种方式在查询数据库时,数据库会根据指定的偏移量和限制数直接返回分页后的结果,而不需要加载全部数据到内存中。因此,物理分页在处理大数据量时性能较好,避免了内存溢出的风险。然而,需要注意的是,不同的数据库可能具有不同的分页语法,因此在使用物理分页时需要考虑到数据库方言的问题。
逻辑分页:
逻辑分页则是在应用层面上实现的分页,它依赖于查询结果集。逻辑分页首先会查询出全部的数据,然后将这些数据加载到内存中,再根据分页要求筛选出合适的数据进行分页。这种方式在数据量较小时可能比较方便,但在处理大数据量时,会消耗大量的内存,并可能导致性能问题。因此,逻辑分页通常适用于数据量较小或对数据实时性要求不高的场景。
在实际应用中,选择物理分页还是逻辑分页需要根据具体的需求和场景来决定。对于大数据量或对数据性能要求较高的场景,建议使用物理分页以提高性能和避免内存溢出。而对于数据量较小或对数据实时性要求不高的场景,可以选择逻辑分页以简化实现过程。
此外,MyBatis还提供了分页插件如PageHelper来简化分页操作的实现。这些插件内部实现了物理分页的逻辑,使得开发者可以更方便地进行分页操作,而无需手动编写复杂的分页SQL语句。然而,在使用分页插件时,仍然需要注意插件的性能和兼容性等问题。

MyBatis 手写一个 拦截器分页

MyBatis 拦截器可以用于在 SQL 执行前后进行一些额外的处理,例如实现分页功能。下面我会给出一个简单的示例,包含了 DAO 层和业务层的代码。

假设你有一个 UserDao 接口,其中定义了获取用户列表的方法:
public interface UserDao {List<User> getUserList();
}
接下来,我们创建一个拦截器来实现分页功能:
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;import java.util.Properties;@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class PaginationInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {Object[] args = invocation.getArgs();MappedStatement mappedStatement = (MappedStatement) args[0];Object parameter = args[1];RowBounds rowBounds = (RowBounds) args[2];// 判断是否需要进行分页if (rowBounds != RowBounds.DEFAULT) {BoundSql boundSql = mappedStatement.getBoundSql(parameter);String sql = boundSql.getSql();// 自己实现分页逻辑,这里简单起见,直接拼接 LIMITsql += " LIMIT " + rowBounds.getOffset() + ", " + rowBounds.getLimit();BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject());MappedStatement newMappedStatement = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql));args[0] = newMappedStatement;args[2] = RowBounds.DEFAULT;}return invocation.proceed();}private MappedStatement copyFromMappedStatement(MappedStatement ms, BoundSqlSqlSource newSqlSource) {MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());builder.resource(ms.getResource());builder.fetchSize(ms.getFetchSize());builder.statementType(ms.getStatementType());builder.keyGenerator(ms.getKeyGenerator());builder.keyProperty(ms.getKeyProperty());builder.timeout(ms.getTimeout());builder.parameterMap(ms.getParameterMap());builder.resultMaps(ms.getResultMaps());builder.cache(ms.getCache());builder.flushCacheRequired(ms.isFlushCacheRequired());builder.useCache(ms.isUseCache());return builder.build();}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {// 这里可以接收配置参数,但我们这里不需要配置参数}private static class BoundSqlSqlSource implements org.apache.ibatis.mapping.SqlSource {private final BoundSql boundSql;public BoundSqlSqlSource(BoundSql boundSql) {this.boundSql = boundSql;}@Overridepublic BoundSql getBoundSql(Object parameterObject) {return boundSql;}}
}然后,在你的 MyBatis 配置文件中配置该拦截器:<plugins><plugin interceptor="your.package.name.PaginationInterceptor"/>
</plugins>
最后,在业务代码中使用分页功能:
import org.apache.ibatis.session.RowBounds;public class UserService {private final UserDao userDao;public UserService(UserDao userDao) {this.userDao = userDao;}public List<User> getUsersByPage(int pageNum, int pageSize) {// 计算 offsetint offset = (pageNum - 1) * pageSize;// 使用 RowBounds 进行分页RowBounds rowBounds = new RowBounds(offset, pageSize);return userDao.getUserList(rowBounds);}
}

这样,当调用 getUsersByPage 方法时,会自动进行分页查询。

相关文章:

MyBatis如何实现分页

文章目录 MyBatis分页方式对比使用数据库厂商提供的分页查询语句通过自定义 SQL 实现分页逻辑1. 使用 RowBounds 实现分页2. 使用 PageHelper 实现分页 数组分页使用 MyBatis-Plus 进行分页MyBatis物理分页和逻辑分页MyBatis 手写一个 拦截器分页 在 MyBatis 中实现分页通常有两…...

在 Python 编程中,面向对象编程的核心概念包括哪些部分?

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 在 Python 编程中&#xff0c;面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;的核心概念主要包括类&#xff08;Class&#xff09;、对象&#xff08;Object&#x…...

elementui树形组件自定义高亮颜色

1、需求描述&#xff1a;点击按钮切换树形的章节&#xff0c;同时高亮 2、代码实现 1&#xff09;style样式添加 <style> .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {background-color: #81d3f8 !important; //高亮颜色colo…...

富格林:技巧抵抗曝光虚假套路

富格林悉知&#xff0c;黄金具备独特的优势吸引着众多投资者的目光&#xff0c;在现货黄金市场也被认为是一条潜力无限的盈利之道。但我们要明白风险与盈利是相辅相成的&#xff0c;因此在这复杂的市场中我们必须利用技巧来抵抗曝光的虚假套路。下面富格林将给大家分享一些正确…...

24年权威数学建模报名通知汇总(含妈妈杯、国赛、美赛、电工杯、数维杯、五一数模、深圳杯......)

1、MathorCup比赛 报名时间&#xff1a;2024年4月11日中午12点&#xff08;周四&#xff09; 比赛开始时间&#xff1a;2024年4月12日上午8时&#xff08;周五&#xff09; 比赛结束时间&#xff1a;2024年4月16日上午9时&#xff08;周二&#xff09; 报名费用&#xff1a…...

【C语言自定义类型之----结构体,联合体和枚举】

一.结构体 1.结构体类型的声明 srruct tag {nemer-list;//成员列表 }varible-list;//变量列表结构体在声明的时候&#xff0c;可以不完全声明。 例如&#xff1a;描述一个学生 struct stu {char name[20];//名字int age;//年龄char sex[20];//性别 };//分号不能省略2.结构体…...

[Java基础揉碎]StringBuffer类 StringBuild类

目录 StringBuffer类 介绍 继承图 String VS StringBuffer StringBuffer的构造器 String和StringBuffer的转换 StringBuffer类常见方法 测试题 StringBuild类 基本介绍 继承图 String、StringBuffer 和StringBuilder的比较 通过字符串拼接循环测试可以看到各自的性…...

Android Studio修改项目包名

1.第一步&#xff0c;项目结构是这样的&#xff0c;3个包名合在了一起&#xff0c;我们需要把每个包名单独展示出来 2.我们点击这个 取消选中后的包名结构是这样的&#xff0c;可以看到&#xff0c;包名的每个文件夹已经展示分开了&#xff0c;现在我们可以单独对每个包名文件夹…...

c++语言增强的地方

目录 1.对全局变量的检测能力 2.struct类型增强 3.c中所有变量和函数都必须有类型 4.c中新增的bool类型 5.三目运算符的加强 6.const的增强 7.对枚举的增强 1.对全局变量的检测能力 C语言中同时定义两个相同的全局变量编译器并不会报错&#xff0c;而c中就会报重定义错…...

评论发布完整篇(react版)

此篇文章阐述评论的最新、最热之间的tab标签切换&#xff08;包括当前所在tab标签的高亮显示问题&#xff09;&#xff1b;当前评论的删除&#xff1b;除此之外还延伸了用户的评论实时发布功能。其中最新tab标签所展示的内容是根据当前评论点赞数来进行排序&#xff0c;点赞数量…...

前端window.open的简单使用

JavaScript 中的 Window.open() 用法详解-CSDN博客 window.open("https://www.baidu.com/?tn49055317_12_hao_pg", _blank);...

基于开源软件构建存储解决方案的思考

近来看了一些IBM的存储产品的资料&#xff0c;有一些收获。 依据存储软件和搭配硬件&#xff0c;IBM存储产品的组合&#xff0c;大致分类如下&#xff1a; 自研存储软件&#xff0c;搭配自研专有硬件自研存储软件&#xff0c;搭配通用服务器硬件&#xff0c;比如IBM Storage S…...

【leetcode】动态规划::前缀和(二)

标题&#xff1a;【leetcode】前缀和&#xff08;二&#xff09; 水墨不写bug 正文开始&#xff1a; &#xff08;一&#xff09; 和为K的子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续…...

SpringBoot自动装配原理之@Import注解解析

文章目录 1. 概述2. 使用2.1 导入普通Bean2.2 导入配置类2.3 导入 ImportSelector 实现类2.4 导入 ImportBeanDefinitionRegistrar 实现类 3. 区别 1. 概述 当谈及现代Java开发领域中的框架选择时&#xff0c;SpringBoot无疑是无与伦比的热门之选。其简化了开发流程&#xff0…...

49 样式迁移【李沐动手学深度学习v2课程笔记】

1. 样式迁移&#xff08;Style Transfer) 计算机视觉的应用之一&#xff0c;将样式图片中的样式&#xff08;比如油画风格等&#xff09;迁移到内容图片&#xff08;比如实拍的图片&#xff09;上&#xff0c;得到合成图片 可以理解成为一个滤镜&#xff0c;但相对于滤镜来讲…...

Linux的学习之路:4、权限

一、Linux权限的概念 权限我们都熟悉&#xff0c;最常见的就是在看电视时需要vip这个就是权限&#xff0c;然后在Linux就是有两个权限&#xff0c;就是管理员也就是超级用户和普通的用户 命令&#xff1a;su [用户名] 功能&#xff1a;切换用户。 例如&#xff0c;要从root用户…...

自定义类型—结构体

目录 1 . 结构体类型的声明 1.1 结构的声明 1.2 结构体变量的创建与初始化 1.3 结构体的特殊声明 1.4 结构体的自引用 2. 结构体内存对齐 2.1 对齐规则 2.2 为什么存在内存对齐 2.3 修改默认对齐数 3. 结构体传参 4.结构体实现位段 4.1 位段的内存分配 4.3 位段的…...

【JavaWeb】Jsp基本教程

目录 JSP概述作用一个简单的案例&#xff1a;使用JSP页面输出当前日期 JSP处理过程JSP 生命周期编译阶段初始化阶段执行阶段销毁阶段案例 JSP页面的元素JSP指令JSP中的page指令Include指令示例 taglib指令 JSP中的小脚本与表达式JSP中的声明JSP中的注释HTML的注释JSP注释 JSP行…...

外包干了25天,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入杭州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...

C++(14): STL条件变量std::condition_variable

1. 简述 在C的标准模板库&#xff08;STL&#xff09;中&#xff0c;std::condition_variable是一个非常重要的同步原语&#xff0c;用于在多线程编程中实现线程间的条件同步。它允许一个或多个线程等待某个条件成立&#xff0c;当条件成立时&#xff0c;等待的线程会被唤醒并继…...

Harmony与Android项目结构对比

主要文件对应 Android文件HarmonyOS文件清单文件AndroidManifest.xmlmodule.json5Activity/Fragmententryability下的ts文件XML布局pages下的ets文件resresourcesModule下的build.gradleModule下的build-profile.json5gradlehvigor根目录下的build.gradle根目录下的build-profi…...

langchain 学习笔记-FunctionCalling三种方式

ChatGPT 基于海量的训练数据生成答案&#xff0c;所以它无法回答训练数据中没有的信息或搜索信息 。人们希望 ChatGPT 具有对话以外的各种功能&#xff0c;例如“我想管理我的待办事项列表”。 函数调用是对此类请求的响应。 通过使用函数调用&#xff0c;ChatGPT 现在可以在生…...

CNAS软件测试公司有什么好处?如何选择靠谱的软件测试公司?

CNAS认可是中国合格评定国家认可委员会的英文缩写&#xff0c;由国家认证认可监督管理委员会批准设立并授权的国家认可机构&#xff0c;统一负责对认证机构、实验室和检验机构等相关机构的认可工作。 在软件测试行业&#xff0c;CNAS认可具有重要意义。它标志着一个软件测试公…...

Cohere推出全新升级版RAG大型AI模型:支持中文,搭载1040亿参数,现开源其权重!

4月5日&#xff0c;知名类ChatGPT平台Cohere在其官方网站上发布了一款全新的模型——Command R。 据官方消息&#xff0c;Command R拥有1040亿个参数&#xff0c;并且支持包括英语、中文、法语、德语在内的10种语言。这一模型的显著特点之一在于其对内置的RAG&#xff08;检索增…...

搭建前后端的链接(java)

搭建前后端的链接(java) 一.前提 1.1 javaEE 搭建前后端的链接首先需要用到javaEE&#xff0c;也就是java企业版&#xff0c;也就是java后端(后端javaSE) 利用javaEE和前端交互&#xff0c;javaSE和数据库交互&#xff0c;javaSE和javaEE之间再进行交互就实现了前后端的交互…...

Java多路查找树(含面试大厂题和源码)

多路查找树&#xff08;Multiway Search Tree&#xff09;&#xff0c;也称为B树或B树&#xff0c;是一种自平衡的树形数据结构&#xff0c;用于存储大量数据&#xff0c;通常用于数据库和文件系统中。它允许在查找、插入和删除操作中保持数据的有序性&#xff0c;同时优化了磁…...

day6 | 哈希表 part-2 | 454 四数相加II 、383. 赎金信、15. 三数之和、18. 四数之和

今日任务 454 四数相加II (题目: . - 力扣&#xff08;LeetCode&#xff09;)383 赎金信 &#xff08;题目: . - 力扣&#xff08;LeetCode&#xff09;&#xff09; 454 四数相加II 题目&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给你四个整数数组 nums1、num…...

Redis常见数据类型(2)

目录 String字符串 常见命令 SET GET MGET MSET SETNX 计数命令 INCR INCRBY DECR DECRBY INCRFLOAT 其它命令 APPEND GETRANGE SETRANGE STRLEN String字符串 字符串是Redis最基础的数据类型, 关于字符串需要特别注意: (1)首先Redis中所有的键的类型都是字符…...

SparkBug解决:Type mismatch; found : org.apache.spark.sql.Column required: Double

def assginFlag(aizmuth:Double):Option[Int] {val interval 0.5val index (aizmuth / interval ).toIntif (index > 0 && index < 720 ) Some(index 1) else None} assginFlag方法中的条件判断条件 (index > 0 && index < 720) 返回的是一个布…...

MQ之————如何保证消息的可靠性

MQ之保证消息的可靠性 1.消费端消息可靠性保证&#xff1a; 1.1 消息确认&#xff08;Acknowledgements&#xff09;&#xff1a; 消费者在接收到消息后&#xff0c;默认情况下RabbitMQ会自动确认消息&#xff08;autoAcktrue&#xff09;。为保证消息可靠性&#xff0c;可以…...