分页Demo

目录

一、分页对象封装

分页数据对象

分页查询实体类 

实体类用到的utils

ServiceException

 StringUtils

 SqlUtil

 BaseMapperPlus,>

 BeanCopyUtils

二、示例

controller

service

dao


一、分页对象封装

分页数据对象

import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.util.List;/*** 分页数据对象** @author chensir*/@Data
@NoArgsConstructor
public class TableDataInfo<T> implements Serializable {private static final long serialVersionUID = 1L;/*** 总记录数*/private long total;/*** 列表数据*/private List<T> rows;/*** 消息状态码*/private int code;/*** 消息内容*/private String msg;/*** 分页** @param list  列表数据* @param total 总记录数*/public TableDataInfo(List<T> list, long total) {this.rows = list;this.total = total;}public static <T> TableDataInfo<T> build(IPage<T> page) {TableDataInfo<T> rspData = new TableDataInfo<>();rspData.setCode(HttpStatus.HTTP_OK);rspData.setMsg("查询成功");rspData.setRows(page.getRecords());rspData.setTotal(page.getTotal());return rspData;}public static <T> TableDataInfo<T> build(List<T> list) {TableDataInfo<T> rspData = new TableDataInfo<>();rspData.setCode(HttpStatus.HTTP_OK);rspData.setMsg("查询成功");rspData.setRows(list);rspData.setTotal(list.size());return rspData;}public static <T> TableDataInfo<T> build() {TableDataInfo<T> rspData = new TableDataInfo<>();rspData.setCode(HttpStatus.HTTP_OK);rspData.setMsg("查询成功");return rspData;}}

分页查询实体类 

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ict.lux.exception.ServiceException;
import com.ict.lux.utils.StringUtils;
import com.ict.lux.utils.sql.SqlUtil;
import lombok.Data;import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;/*** 分页查询实体类** @author chensir*/@Data
public class PageQuery implements Serializable {private static final long serialVersionUID = 1L;/*** 分页大小*/private Integer pageSize;/*** 当前页数*/private Integer pageNum;/*** 排序列*/private String orderByColumn;/*** 排序的方向desc或者asc*/private String isAsc;/*** 当前记录起始索引 默认值*/public static final int DEFAULT_PAGE_NUM = 1;/*** 每页显示记录数 默认值 默认查全部*/public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;public <T> Page<T> build() {Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM);Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE);if (pageNum <= 0) {pageNum = DEFAULT_PAGE_NUM;}Page<T> page = new Page<>(pageNum, pageSize);List<OrderItem> orderItems = buildOrderItem();if (CollUtil.isNotEmpty(orderItems)) {page.addOrder(orderItems);}return page;}/*** 构建排序** 支持的用法如下:* {isAsc:"asc",orderByColumn:"id"} order by id asc* {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc* {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc* {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc*/private List<OrderItem> buildOrderItem() {if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) {return null;}String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);orderBy = StringUtils.toUnderScoreCase(orderBy);// 兼容前端排序类型isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"});String[] orderByArr = orderBy.split(StringUtils.SEPARATOR);String[] isAscArr = isAsc.split(StringUtils.SEPARATOR);if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) {throw new ServiceException("排序参数有误");}List<OrderItem> list = new ArrayList<>();// 每个字段各自排序for (int i = 0; i < orderByArr.length; i++) {String orderByStr = orderByArr[i];String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i];if ("asc".equals(isAscStr)) {list.add(OrderItem.asc(orderByStr));} else if ("desc".equals(isAscStr)) {list.add(OrderItem.desc(orderByStr));} else {throw new ServiceException("排序参数有误");}}return list;}}

 实体类用到的utils

ServiceException

/*** 业务异常** @author chensir*/
public final class ServiceException extends RuntimeException {private static final long serialVersionUID = 1L;/*** 错误码*/private Integer code;/*** 错误提示*/private String message;/*** 错误明细,内部调试错误* <p>* 和 {@link CommonResult#getDetailMessage()} 一致的设计*/private String detailMessage;/*** 空构造方法,避免反序列化问题*/public ServiceException() {}public ServiceException(String message) {this.message = message;}public ServiceException(String message, Integer code) {this.message = message;this.code = code;}public String getDetailMessage() {return detailMessage;}@Overridepublic String getMessage() {return message;}public Integer getCode() {return code;}public ServiceException setMessage(String message) {this.message = message;return this;}public ServiceException setDetailMessage(String detailMessage) {this.detailMessage = detailMessage;return this;}
}

 StringUtils

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.util.AntPathMatcher;import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;/*** 字符串工具类** @author chensir*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class StringUtils extends org.apache.commons.lang3.StringUtils {public static final String SEPARATOR = ",";/*** 获取参数不为空值** @param str defaultValue 要判断的value* @return value 返回值*/public static String blankToDefault(String str, String defaultValue) {return StrUtil.blankToDefault(str, defaultValue);}/*** * 判断一个字符串是否为空串** @param str String* @return true:为空 false:非空*/public static boolean isEmpty(String str) {return StrUtil.isEmpty(str);}/*** * 判断一个字符串是否为非空串** @param str String* @return true:非空串 false:空串*/public static boolean isNotEmpty(String str) {return !isEmpty(str);}/*** 去空格*/public static String trim(String str) {return StrUtil.trim(str);}/*** 截取字符串** @param str   字符串* @param start 开始* @return 结果*/public static String substring(final String str, int start) {return substring(str, start, str.length());}/*** 截取字符串** @param str   字符串* @param start 开始* @param end   结束* @return 结果*/public static String substring(final String str, int start, int end) {return StrUtil.sub(str, start, end);}/*** 格式化文本, {} 表示占位符<br>* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>* 例:<br>* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>* 转义{}: format("this is \\{} for {}", "a", "b") -> this is {} for a<br>* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>** @param template 文本模板,被替换的部分用 {} 表示* @param params   参数值* @return 格式化后的文本*/public static String format(String template, Object... params) {return StrUtil.format(template, params);}/*** 是否为http(s)://开头** @param link 链接* @return 结果*/public static boolean ishttp(String link) {return Validator.isUrl(link);}/*** 字符串转set** @param str 字符串* @param sep 分隔符* @return set集合*/public static Set<String> str2Set(String str, String sep) {return new HashSet<>(str2List(str, sep, true, false));}/*** 字符串转list** @param str         字符串* @param sep         分隔符* @param filterBlank 过滤纯空白* @param trim        去掉首尾空白* @return list集合*/public static List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) {List<String> list = new ArrayList<>();if (isEmpty(str)) {return list;}// 过滤空白字符串if (filterBlank && isBlank(str)) {return list;}String[] split = str.split(sep);for (String string : split) {if (filterBlank && isBlank(string)) {continue;}if (trim) {string = trim(string);}list.add(string);}return list;}/*** 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写** @param cs                  指定字符串* @param searchCharSequences 需要检查的字符串数组* @return 是否包含任意一个字符串*/public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) {return StrUtil.containsAnyIgnoreCase(cs, searchCharSequences);}/*** 驼峰转下划线命名*/public static String toUnderScoreCase(String str) {return StrUtil.toUnderlineCase(str);}/*** 是否包含字符串** @param str  验证字符串* @param strs 字符串组* @return 包含返回true*/public static boolean inStringIgnoreCase(String str, String... strs) {return StrUtil.equalsAnyIgnoreCase(str, strs);}/*** 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld** @param name 转换前的下划线大写方式命名的字符串* @return 转换后的驼峰式命名的字符串*/public static String convertToCamelCase(String name) {return StrUtil.upperFirst(StrUtil.toCamelCase(name));}/*** 驼峰式命名法 例如:user_name->userName*/public static String toCamelCase(String s) {return StrUtil.toCamelCase(s);}/*** 查找指定字符串是否匹配指定字符串列表中的任意一个字符串** @param str  指定字符串* @param strs 需要检查的字符串数组* @return 是否匹配*/public static boolean matches(String str, List<String> strs) {if (isEmpty(str) || CollUtil.isEmpty(strs)) {return false;}for (String pattern : strs) {if (isMatch(pattern, str)) {return true;}}return false;}/*** 判断url是否与规则配置:* ? 表示单个字符;* * 表示一层路径内的任意字符串,不可跨层级;* ** 表示任意层路径;** @param pattern 匹配规则* @param url     需要匹配的url*/public static boolean isMatch(String pattern, String url) {AntPathMatcher matcher = new AntPathMatcher();return matcher.match(pattern, url);}/*** 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。** @param num  数字对象* @param size 字符串指定长度* @return 返回数字的字符串格式,该字符串为指定长度。*/public static String padl(final Number num, final int size) {return padl(num.toString(), size, '0');}/*** 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。** @param s    原始字符串* @param size 字符串指定长度* @param c    用于补齐的字符* @return 返回指定长度的字符串,由原字符串左补齐或截取得到。*/public static String padl(final String s, final int size, final char c) {final StringBuilder sb = new StringBuilder(size);if (s != null) {final int len = s.length();if (s.length() <= size) {for (int i = size - len; i > 0; i--) {sb.append(c);}sb.append(s);} else {return s.substring(len - size, len);}} else {for (int i = size; i > 0; i--) {sb.append(c);}}return sb.toString();}/*** 切分字符串(分隔符默认逗号)** @param str 被切分的字符串* @return 分割后的数据列表*/public static List<String> splitList(String str) {return splitTo(str, Convert::toStr);}/*** 切分字符串** @param str       被切分的字符串* @param separator 分隔符* @return 分割后的数据列表*/public static List<String> splitList(String str, String separator) {return splitTo(str, separator, Convert::toStr);}/*** 切分字符串自定义转换(分隔符默认逗号)** @param str    被切分的字符串* @param mapper 自定义转换* @return 分割后的数据列表*/public static <T> List<T> splitTo(String str, Function<? super Object, T> mapper) {return splitTo(str, SEPARATOR, mapper);}/*** 切分字符串自定义转换** @param str       被切分的字符串* @param separator 分隔符* @param mapper    自定义转换* @return 分割后的数据列表*/public static <T> List<T> splitTo(String str, String separator, Function<? super Object, T> mapper) {if (isBlank(str)) {return new ArrayList<>(0);}return StrUtil.split(str, separator).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());}}

 SqlUtil

import com.ict.lux.exception.UtilException;
import com.ict.lux.utils.StringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;/*** sql操作工具类** @author chensir*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class SqlUtil {/*** 定义常用的 sql关键字*/public static final String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";/*** 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)*/public static final String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";/*** 检查字符,防止注入绕过*/public static String escapeOrderBySql(String value) {if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {throw new UtilException("参数不符合规范,不能进行查询");}return value;}/*** 验证 order by 语法是否符合规范*/public static boolean isValidOrderBySql(String value) {return value.matches(SQL_PATTERN);}/*** SQL关键字检查*/public static void filterKeyword(String value) {if (StringUtils.isEmpty(value)) {return;}String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");for (String sqlKeyword : sqlKeywords) {if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {throw new UtilException("参数存在SQL注入风险");}}}
}

 BaseMapperPlus<M, T, V>

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.plm.common.utils.BeanCopyUtils;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;/*** 自定义 Mapper 接口, 实现 自定义扩展** @param <M> mapper 泛型* @param <T> table 泛型* @param <V> vo 泛型* @author chensir* @since 2022-10-8*/
@SuppressWarnings("unchecked")
public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> {Log log = LogFactory.getLog(BaseMapperPlus.class);default Class<V> currentVoClass() {return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 2);}default Class<T> currentModelClass() {return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 1);}default Class<M> currentMapperClass() {return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 0);}default List<T> selectList() {return this.selectList(new QueryWrapper<>());}/*** 批量插入*/default boolean insertBatch(Collection<T> entityList) {return Db.saveBatch(entityList);}/*** 批量更新*/default boolean updateBatchById(Collection<T> entityList) {return Db.updateBatchById(entityList);}/*** 批量插入或更新*/default boolean insertOrUpdateBatch(Collection<T> entityList) {return Db.saveOrUpdateBatch(entityList);}/*** 批量插入(包含限制条数)*/default boolean insertBatch(Collection<T> entityList, int batchSize) {return Db.saveBatch(entityList, batchSize);}/*** 批量更新(包含限制条数)*/default boolean updateBatchById(Collection<T> entityList, int batchSize) {return Db.updateBatchById(entityList, batchSize);}/*** 批量插入或更新(包含限制条数)*/default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) {return Db.saveOrUpdateBatch(entityList, batchSize);}/*** 插入或更新(包含限制条数)*/default boolean insertOrUpdate(T entity) {return Db.saveOrUpdate(entity);}default V selectVoById(Serializable id) {return selectVoById(id, this.currentVoClass());}/*** 根据 ID 查询*/default <C> C selectVoById(Serializable id, Class<C> voClass) {T obj = this.selectById(id);if (ObjectUtil.isNull(obj)) {return null;}return BeanCopyUtils.copy(obj, voClass);}default List<V> selectVoBatchIds(Collection<? extends Serializable> idList) {return selectVoBatchIds(idList, this.currentVoClass());}/*** 查询(根据ID 批量查询)*/default <C> List<C> selectVoBatchIds(Collection<? extends Serializable> idList, Class<C> voClass) {List<T> list = this.selectBatchIds(idList);if (CollUtil.isEmpty(list)) {return CollUtil.newArrayList();}return BeanCopyUtils.copyList(list, voClass);}default List<V> selectVoByMap(Map<String, Object> map) {return selectVoByMap(map, this.currentVoClass());}/*** 查询(根据 columnMap 条件)*/default <C> List<C> selectVoByMap(Map<String, Object> map, Class<C> voClass) {List<T> list = this.selectByMap(map);if (CollUtil.isEmpty(list)) {return CollUtil.newArrayList();}return BeanCopyUtils.copyList(list, voClass);}default V selectVoOne(Wrapper<T> wrapper) {return selectVoOne(wrapper, this.currentVoClass());}/*** 根据 entity 条件,查询一条记录*/default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) {T obj = this.selectOne(wrapper);if (ObjectUtil.isNull(obj)) {return null;}return BeanCopyUtils.copy(obj, voClass);}default List<V> selectVoList(Wrapper<T> wrapper) {return selectVoList(wrapper, this.currentVoClass());}/*** 根据 entity 条件,查询全部记录*/default <C> List<C> selectVoList(Wrapper<T> wrapper, Class<C> voClass) {List<T> list = this.selectList(wrapper);if (CollUtil.isEmpty(list)) {return CollUtil.newArrayList();}return BeanCopyUtils.copyList(list, voClass);}default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) {return selectVoPage(page, wrapper, this.currentVoClass());}/*** 分页查询VO*/default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) {IPage<T> pageData = this.selectPage(page, wrapper);IPage<C> voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal());if (CollUtil.isEmpty(pageData.getRecords())) {return (P) voPage;}voPage.setRecords(BeanCopyUtils.copyList(pageData.getRecords(), voClass));return (P) voPage;}}

 BeanCopyUtils

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.SimpleCache;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.cglib.core.Converter;import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;/*** bean深拷贝工具(基于 cglib 性能优异)* <p>* 重点 cglib 不支持 拷贝到链式对象* 例如: 源对象 拷贝到 目标(链式对象)* 请区分好`浅拷贝`和`深拷贝`再做使用** @author chensir*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class BeanCopyUtils {/*** 单对象基于class创建拷贝** @param source 数据来源实体* @param desc   描述对象 转换后的对象* @return desc*/public static <T, V> V copy(T source, Class<V> desc) {if (ObjectUtil.isNull(source)) {return null;}if (ObjectUtil.isNull(desc)) {return null;}final V target = ReflectUtil.newInstanceIfPossible(desc);return copy(source, target);}/*** 单对象基于对象创建拷贝** @param source 数据来源实体* @param desc   转换后的对象* @return desc*/public static <T, V> V copy(T source, V desc) {if (ObjectUtil.isNull(source)) {return null;}if (ObjectUtil.isNull(desc)) {return null;}BeanCopier beanCopier = BeanCopierCache.INSTANCE.get(source.getClass(), desc.getClass(), null);beanCopier.copy(source, desc, null);return desc;}/*** 列表对象基于class创建拷贝** @param sourceList 数据来源实体列表* @param desc       描述对象 转换后的对象* @return desc*/public static <T, V> List<V> copyList(List<T> sourceList, Class<V> desc) {if (ObjectUtil.isNull(sourceList)) {return null;}if (CollUtil.isEmpty(sourceList)) {return CollUtil.newArrayList();}return StreamUtils.toList(sourceList, source -> {V target = ReflectUtil.newInstanceIfPossible(desc);copy(source, target);return target;});}/*** bean拷贝到map** @param bean 数据来源实体* @return map对象*/@SuppressWarnings("unchecked")public static <T> Map<String, Object> copyToMap(T bean) {if (ObjectUtil.isNull(bean)) {return null;}return BeanMap.create(bean);}/*** map拷贝到bean** @param map       数据来源* @param beanClass bean类* @return bean对象*/public static <T> T mapToBean(Map<String, Object> map, Class<T> beanClass) {if (MapUtil.isEmpty(map)) {return null;}if (ObjectUtil.isNull(beanClass)) {return null;}T bean = ReflectUtil.newInstanceIfPossible(beanClass);return mapToBean(map, bean);}/*** map拷贝到bean** @param map  数据来源* @param bean bean对象* @return bean对象*/public static <T> T mapToBean(Map<String, Object> map, T bean) {if (MapUtil.isEmpty(map)) {return null;}if (ObjectUtil.isNull(bean)) {return null;}BeanMap.create(bean).putAll(map);return bean;}/*** map拷贝到map** @param map   数据来源* @param clazz 返回的对象类型* @return map对象*/public static <T, V> Map<String, V> mapToMap(Map<String, T> map, Class<V> clazz) {if (MapUtil.isEmpty(map)) {return null;}if (ObjectUtil.isNull(clazz)) {return null;}Map<String, V> copyMap = new LinkedHashMap<>(map.size());map.forEach((k, v) -> copyMap.put(k, copy(v, clazz)));return copyMap;}/*** BeanCopier属性缓存<br>* 缓存用于防止多次反射造成的性能问题** @author Looly* @since 5.4.1*/public enum BeanCopierCache {/*** BeanCopier属性缓存单例*/INSTANCE;private final SimpleCache<String, BeanCopier> cache = new SimpleCache<>();/*** 获得类与转换器生成的key在{@link BeanCopier}的Map中对应的元素** @param srcClass    源Bean的类* @param targetClass 目标Bean的类* @param converter   转换器* @return Map中对应的BeanCopier*/public BeanCopier get(Class<?> srcClass, Class<?> targetClass, Converter converter) {final String key = genKey(srcClass, targetClass, converter);return cache.get(key, () -> BeanCopier.create(srcClass, targetClass, converter != null));}/*** 获得类与转换器生成的key** @param srcClass    源Bean的类* @param targetClass 目标Bean的类* @param converter   转换器* @return 属性名和Map映射的key*/private String genKey(Class<?> srcClass, Class<?> targetClass, Converter converter) {final StringBuilder key = StrUtil.builder().append(srcClass.getName()).append('#').append(targetClass.getName());if (null != converter) {key.append('#').append(converter.getClass().getName());}return key.toString();}}}

二、示例

controller

BaseController可忽略

 

service

 

dao

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/75854.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

适配器模式(Adapter)

适配器模式用于将一个接口转换成用户希望的另一个接口&#xff0c;适配器模式使接口不兼容的那些类可以一起工作&#xff0c;其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式&#xff0c;也可以作为对象结构型模式。 Adapter is a structural design pattern that…

Android Studio 关于BottomNavigationView 无法预览视图我的解决办法

一、前言&#xff1a;最近在尝试一步一步开发一个自己的软件&#xff0c;刚开始遇到的问题就是当我们引用 com.google.android.material.bottomnavigation.BottomNavigationView出现了无法预览视图的现象&#xff0c;我也在网上查了很多中解决方法&#xff0c;最后在执行了如下…

三个主流数据库(Oracle、MySQL和SQL Server)的“单表造数

oracle 1.创建表 CREATE TABLE "YZH2_ORACLE" ("VARCHAR2_COLUMN" VARCHAR2(20) NOT NULL ENABLE,"NUMBER_COLUMN" NUMBER,"DATE_COLUMN" DATE,"CLOB_COLUMN" CLOB,"BLOB_COLUMN" BLOB,"BINARY_DOUBLE_COLU…

数据结构 10-排序4 统计工龄 桶排序/计数排序(C语言)

给定公司名员工的工龄&#xff0c;要求按工龄增序输出每个工龄段有多少员工。 输入格式: 输入首先给出正整数&#xff08;≤&#xff09;&#xff0c;即员工总人数&#xff1b;随后给出个整数&#xff0c;即每个员工的工龄&#xff0c;范围在[0, 50]。 输出格式: 按工龄的递…

cad中的曲线区域是如何绘制的

cad中的曲线区域是如何绘制的 最近需要把cad中的设备锁在区域绘画出来&#xff0c;不同设备放在不同区域 组合工具命令PLPE 步骤&#xff1a; 1.先用pl绘制&#xff0c;把设备都是绘制在pl的曲线范围内 2.用pe命令&#xff0c;选择pl的区域进行曲线&#xff08;s&#xff…

“单片机定时器:灵活计时与创新功能的关键“

学会定时器的使用对单片机来说非常重要&#xff0c;因为它可以帮助实现各种时序电路。时序电路在工业和家用电器的控制中有广泛的应用。 举个例子&#xff0c;我们可以利用单片机实现一个具有按钮控制的楼道灯开关。当按钮按下一次后&#xff0c;灯会亮起并持续3分钟&#xff…

shell命令

#!/bin/bash read -p "请输入一个文件名&#xff1a;" fileName posexpr index $fileName \. typeexpr substr $fileName $((pos1)) 2if [ $type sh ] thenif [ -x $fileName ]thenbash $fileNameelsechmod ax $fileNamefi firead -p "请输入第一个文件名&…

LLVM笔记1

参考&#xff1a;https://www.bilibili.com/video/BV1D84y1y73v/?share_sourcecopy_web&vd_sourcefc187607fc6ec6bbd2c74a3d0d7484cf 文章目录 零、入门名词解释1. Compiler & Interpreter2. AOT静态编译和JIT动态解释的编译方式3. Pass4. Intermediate Representatio…

node.js的优点

提示&#xff1a;node.js的优点 文章目录 一、什么是node.js二、node.js的特性 一、什么是node.js 提示&#xff1a;什么是node.js? Node.js发布于2009年5月&#xff0c;由Ryan Dahl开发&#xff0c;是一个基于ChromeV8引擎的JavaScript运行环境&#xff0c;使用了一个事件驱…

python可以做哪些小工具,python可以做什么小游戏

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python可以做什么好玩的&#xff0c;python可以做什么小游戏&#xff0c;今天让我们一起来看看吧&#xff01; 最近有几个友友问我说有没有比较好玩的Python小项目来练手&#xff0c;于是我找了几个比较有意思的给他们&…

数学建模-爬虫系统学习

尚硅谷Python爬虫教程小白零基础速通&#xff08;含python基础爬虫案例&#xff09; 内容包括&#xff1a;Python基础、Urllib、解析&#xff08;xpath、jsonpath、beautiful&#xff09;、requests、selenium、Scrapy框架 python基础 进阶&#xff08;字符串 列表 元组 字典…

IntelliJ IDEA 2023.2社区版插件汇总

参考插件帝&#xff1a;https://gitee.com/zhengqingya/java-developer-document 突发小技巧&#xff1a;使用插件时要注意插件的版本兼容性&#xff0c;并根据自己的实际需求选择合适的插件。同时&#xff0c;不要过度依赖插件&#xff0c;保持简洁和高效的开发环境才是最重要…

linux 安装FTP

检查是否已经安装 $] rpm -qa |grep vsftpd vsftpd-3.0.2-29.el7_9.x86_64出现 vsftpd 信息表示已经安装&#xff0c;无需再次安装 yum安装 $] yum -y install vsftpd此命令需要root执行或有sudo权限的账号执行 /etc/vsftpd 目录 ftpusers # 禁用账号列表 user_list # 账号列…

C++类和对象入门(下)

C类和对象入门 1. Static成员1.1 Static成员的概念2.2 Static成员的特性 2.友元2.1 友元函数2.2 友元函数的特性2.3 友元类 3. 内部类3.1 内部类的概念和特性 4. 匿名对象5. 再次理解类和对象 1. Static成员 1.1 Static成员的概念 声明为static的类成员称为类的静态成员&…

Git基础知识:常见功能和命令行

文章目录 1.Git介绍2.安装配置2.1 查看配置信息 3.文件管理3.1 创建仓库3.2 版本回退3.3 工作流程3.4 撤销修改3.5 删除文件 4.远程仓库4.1 连接远程库4.2 本地上传至远程4.3 从远程库克隆到本地 5.分支管理5.1 创建分支5.2 删除分支5.3 合并分支解决冲突 参考&#xff1a; Git…

Vue前端框架入门

文章目录 Vue快速入门Vue指令生命周期 Vue 经过一小段时间学习 我认为vue就是在原js上进行的一个加强 简化JS中的DOM操作 vue是分两个层的 一个叫做视图层(View)&#xff0c;你可以理解为展现出来的前端页面 一个叫数据模型层(Model),包含数据和一些数据的处理方法 MVVM就是实…

Mybatis 实体类属性名和表中字段名不一致怎么处理

一. 前言 最近耀哥有学生出去面试&#xff0c;被问到 “Mybatis实体类的属性名和表中的字段名不一致该怎么处理&#xff1f;”&#xff0c;这其实是一个很经典的面试题&#xff0c;接下来耀哥就为大家详细解析一下这道面试题。 二. 分析 2.1 实体类和字段名不一致所带来的后果…

汽车智能化再掀新热潮!「中央计算架构」进入规模量产周期

中央计算区域控制的新一代整车电子架构&#xff0c;已经成为车企继电动化、智能化&#xff08;功能上车&#xff09;之后&#xff0c;新一轮竞争的焦点。 如果说智能化的1.0阶段&#xff0c;是智能驾驶智能座舱的争夺战&#xff1b;那么&#xff0c;即将进入的2.0阶段&#xff…

postman----传参格式(json格式、表单格式)

本文主要讲解postman使用post请求方法的2中传参方式&#xff1a;json格式、表单格式 首先了解下&#xff0c;postman进行接口测试&#xff0c;必须条件是&#xff1a; ♥请求地址 ♥请求协议 ♥请求方式 ♥请求头 ♥参数 json格式 先看一下接口文档&#xff0c;根据接口文档&…

测试人员简单使用Jenkins

一、测试人员使用jenkins干什么&#xff1f; 部署测试环境 二、相关配置说明 一般由开发人员进行具体配置 1.Repository URL&#xff1a;填写git地址 2.填写开发分支&#xff0c;测试人员可通过相应分支进行测试环境的构建部署 当多个版本并行时&#xff0c;开发人员可以通过…