当前位置: 首页 > 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;等待的线程会被唤醒并继…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...