• [技术干货] Spring和Spring Boot的区别
    Spring和Spring Boot都是Java开发的框架,用于简化和加速Java应用程序的开发。  Spring是一个开源的应用程序框架,它提供了一个综合的编程和配置模型,用于构建Java应用程序。Spring框架提供了许多功能,如依赖注入、面向切面编程、事务管理等,它也可以与其他框架和技术进行集成,如Hibernate、MVC框架等。Spring框架需要开发人员进行大量的配置和编写XML文件。  Spring Boot是一个开源的微服务框架,它是在Spring框架的基础上构建的。Spring Boot的目标是简化Spring应用程序的配置和部署。它提供了自动配置、起步依赖和可嵌入式服务器等功能,使得开发人员能够快速地创建独立的、可部署的Spring应用程序。Spring Boot大大减少了配置的工作量,开发人员只需要少量的代码就能够创建一个功能完整的Spring应用程序。  总而言之,Spring是一个全功能的应用程序框架,适用于大型的、复杂的应用程序开发,而Spring Boot则是一个更轻量级、更简化的框架,适用于快速、简单的应用程序开发。  Spring和Spring Boot是Java开发中常用的两个框架,它们在功能和实现上存在一些区别。以下是它们之间的一些主要区别:  配置方式:在Spring中,开发人员需要手动配置大量的组件,如数据源、事务管理器、Web服务器等。相比之下,Spring Boot通过自动配置方式,可以根据classpath中的依赖关系自动配置很多组件,简化了应用程序的配置过程。 依赖管理:Spring Boot采用了“约定优于配置”的思想,提供了一系列的starter依赖。这些依赖包含了所需的依赖和默认配置,使得开发者可以快速开始一个新的项目,而Spring则需要手动管理依赖。 微服务支持:Spring Boot的设计初衷是支持微服务的快速开发。因此,它提供了很多针对微服务的功能,例如服务注册与发现、负载均衡、断路器等。而Spring则需要通过额外的组件来实现这些功能。 项目构建:Spring Boot可以使用内嵌的Tomcat或Jetty服务器,无需部署到外部服务器,可以更加方便地构建独立的可执行JAR包或WAR包。而Spring则需要部署到外部服务器。 操作简化:Spring Boot提供了极其快速和简化的操作,让Spring开发者快速上手。它提供了Spring运行的默认配置,为通用Spring项目提供了很多非功能性特性。 总的来说,Spring Boot是Spring框架的扩展,它简化了Spring应用程序的配置和开发流程,为更快、更高效的开发生态系统铺平了道路。 ———————————————— 原文链接:https://blog.csdn.net/qq_23997827/article/details/135697093 
  • [技术干货] 在 Spring Boot 中使用 MyBatis-Plus 进行批量操作数据
    引言 MyBatis-Plus 是 MyBatis 的增强工具包,提供了许多便捷的功能来简化 MyBatis 的使用。在实际项目中,我们经常需要进行批量的数据操作,例如批量插入、批量更新和批量删除。本文将介绍如何在 Spring Boot 中使用 MyBatis-Plus 进行这些批量操作。 Mybatis-Plus是一个Mybatis(opens new window)的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发。 Mybatis-Plus的优势 无侵入:只做增强不做改变,引入它不会对现有工程产生影响。 损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作。 强大的CRUD操作:内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作,更有强大的条件构造器,满足各类使用需求。 支持Lambda形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写 错。 支持主键自动生成:支持多达4种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题。 支持ActiveRecord模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作。 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )。 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用。 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询。 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、 Postgre、SQLServer 等多种数据库。 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询。 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作。  1. 准备工作 首先,确保你的 Spring Boot 项目中已经添加了 MyBatis-Plus 的依赖。在 Maven 项目中,可以在 pom.xml 文件中添加以下依赖:  <dependency>     <groupId>com.baomidou</groupId>     <artifactId>mybatis-plus-boot-starter</artifactId>     <version>最新版本</version> </dependency> 2. 批量插入数据 @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {       public void saveBatchUsers(List<User> userList) {         saveBatch(userList);     } } 在上述代码中,saveBatch 方法接收一个实体列表作为参数,然后执行批量插入操作。UserMapper 是你的 MyBatis Mapper 接口,User 是你的实体类。  3. 批量更新数据 @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {       public void updateBatchUsers(List<User> userList) {         updateBatchById(userList);     } } updateBatchById 方法同样接收一个实体列表参数,执行批量更新操作。  4. 批量删除数据 @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {       public void removeUsersByIds(List<Long> userIds) {         removeByIds(userIds);     } } removeByIds 方法接收一个主键 ID 的列表,执行批量删除操作。  5. 总结 通过 MyBatis-Plus 提供的 saveBatch、updateBatchById 和 removeByIds 方法,我们可以非常方便地实现在 Spring Boot 项目中的批量操作数据。这些方法简化了 SQL 的编写,提高了开发效率,同时也遵循了 MyBatis-Plus 的约定大于配置的设计理念。  在实际应用中,根据业务需求和数据量,选择合适的批量操作方法可以有效提高系统性能,减少数据库交互次数。希望本文能帮助你更好地利用 MyBatis-Plus 进行批量操作数据的开发。 ————————————————   原文链接:https://blog.csdn.net/qq_28068311/article/details/134559225 
  • [技术干货] Mybatis-plus批量操作
    前言 Mybatis-Plus是一个Mybatis(opens new window)的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发。   Mybatis-Plus的优势 有:无侵入:只做增强不做改变,引入它不会对现有工程产生影响。 损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作。 强大的CRUD操作:内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作,更有强大的条件构造器,满足各类使用需求。 支持Lambda形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写 错。 支持主键自动生成:支持多达4种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题。 支持ActiveRecord模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作。 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )。 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用。 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询。 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、 Postgre、SQLServer 等多种数据库。 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询。 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作。    使用Mybatis-plus可以很方便的实现批量新增和批量修改,不仅比自己写foreach遍历方便很多,而且性能也更加优秀。但是Mybatis-plus官方提供的批量修改和批量新增都是根据id来修改的,有时候我们需求其他字段,所以就需要我们自己修改一下。  一、批量修改         在Mybatis-plus的IService接口中有updateBatchById方法,我们常用以下方法根据id批量修改数据。      @Transactional(rollbackFor = Exception.class)     default boolean updateBatchById(Collection<T> entityList) {         return updateBatchById(entityList, DEFAULT_BATCH_SIZE);     }       @Transactional(rollbackFor = Exception.class)     @Override     public boolean updateBatchById(Collection<T> entityList, int batchSize) {         String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);         return executeBatch(entityList, batchSize, (sqlSession, entity) -> {             MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();             param.put(Constants.ENTITY, entity);             sqlSession.update(sqlStatement, param);         });     } 但是当我们想根据其他字段批量修改数据时,该方法就无能为力了。所以我们就可以根据第二个updateBatchById方法在自己的service类里面写一个新的批量新增方法。      public boolean updateBatchByColumn(Collection<?> entityList, String idCard) {         String sqlStatement = getSqlStatement(SqlMethod.UPDATE);         return executeBatch(entityList, (sqlSession, entity) -> {             LambdaUpdateWrapper<SysUser> updateWrapper = Wrappers.<SysUser>lambdaUpdate()                     .eq(SysUser::getIdCard, idCard);             Map<String, Object> param = CollectionUtils.newHashMapWithExpectedSize(2);             param.put(Constants.ENTITY, entity);             param.put(Constants.WRAPPER, updateWrapper);             sqlSession.update(sqlStatement, param);         });     } 注意sqlStatement是使用的SqlMethod.UPDATE,SysUser对象是举例,使用的是若依的用户数据。  二、批量新增或修改         在Mybatis-plus的ServiceImpl 类中有一个saveOrUpdateBatch 方法用于批量新增或修改,通过CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity))根据id查询数据是否已存在,不存在新增,存在则修改,源码如下:      @Transactional(rollbackFor = Exception.class)     @Override     public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {         TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);         Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");         String keyProperty = tableInfo.getKeyProperty();         Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");         return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {             Object idVal = tableInfo.getPropertyValue(entity, keyProperty);             return StringUtils.checkValNull(idVal)                 || CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));         }, (sqlSession, entity) -> {             MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();             param.put(Constants.ENTITY, entity);             sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);         });     } 最终调用的是SqlHelper.saveOrUpdateBatch方法,该方法第六个参数是BiPredicate,这就是用于判断数据库中数据是否存在的关键,所以我们需要修改这个函数式接口,修改为根据其他条件查询数据库。该方法的第七个参数是BiConsumer,该函数式接口用于修改数据,如果不想根据id修改数据,可以参考第一部门进行修改。      @Transactional(rollbackFor = Exception.class)     public boolean saveOrUpdateBatchByColumn(Collection<?> entityList, String idCard) {           return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, super.log, entityList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {             LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.<SysUser>lambdaQuery()                     .eq(SysUser::getIdCard, idCard);             Map<String, Object> map = CollectionUtils.newHashMapWithExpectedSize(1);             map.put(Constants.WRAPPER, queryWrapper);             return CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_LIST), map));         }, (sqlSession, entity) -> {             Map<String, Object> param = CollectionUtils.newHashMapWithExpectedSize(2);             param.put(Constants.ENTITY, entity);             sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);         });     } 三、不使用Mybatis-plus进行批量操作         有时候项目里没有引用Mybatis-plus,但是也想进行批量操作,数据量大了后foreach循环会影响性能。所以可以参考Mybatis-plus的批量操作,编写在mybatis环境下的批量操作,代码如下:  @Component public class MybatisBatchUtils {       private static final int BATCH_SIZE = 1000;       @Autowired     private SqlSessionFactory sqlSessionFactory;       public <T,U,R> boolean batchUpdateOrInsert(List<T> data, Class<U> mapperClass, BiFunction<T,U,R> function) {         int i = 1;         SqlSession batchSqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);         try {             U mapper = batchSqlSession.getMapper(mapperClass);             int size = data.size();             for (T element : data) {                 function.apply(element, mapper);                 if ((i % BATCH_SIZE == 0) || i == size) {                     batchSqlSession.flushStatements();                 }                 i++;             }             // 非事务环境下强制commit,事务情况下该commit相当于无效             batchSqlSession.commit(!TransactionSynchronizationManager.isSynchronizationActive());             return true;         } catch (Exception e) {             batchSqlSession.rollback();             throw new RuntimeException(e);         } finally {             batchSqlSession.close();         }     } } 写在最后的话         Mybatis-plus真好用,少写好多代码。有些不太适用的方法,也可以很简单在官方的基础上进行扩展。 ————————————————                      原文链接:https://blog.csdn.net/WayneLee0809/article/details/126424482 
  • [技术干货] springboot 配置文件里部分配置未生效的解决
    springboot 配置文件里部分配置未生效最近用springboot搭了个项目,上线过段时间就会出现卡死,猜测是数据库连接池的连接被占满,用的连接池是druid,于是给项目加上了一个数据库连接池监控。代码如下:@Configuration public class DruidConfiguration { /** * * 注册一个StatViewServlet * * @return * */ @Bean public ServletRegistrationBean DruidStatViewServle2() { // org.springframework.boot.context.embedded.ServletRegistrationBean提供类的进行注册. ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); // 添加初始化参数:initParams // 白名单: // servletRegistrationBean.addInitParameter("allow", "127.0.0.1"); // IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not // permitted to view this page. // servletRegistrationBean.addInitParameter("deny", "192.168.1.73"); // 登录查看信息的账号密码. servletRegistrationBean.addInitParameter("loginUsername", "admin"); servletRegistrationBean.addInitParameter("loginPassword", "admin"); // 是否能够重置数据. servletRegistrationBean.addInitParameter("resetEnable", "false"); return servletRegistrationBean; } /** * * 注册一个:filterRegistrationBean * * @return * */ @Bean public FilterRegistrationBean druidStatFilter2() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); // 添加过滤规则. filterRegistrationBean.addUrlPatterns("/*"); // 添加不需要忽略的格式信息. filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid2/*"); return filterRegistrationBean; } }于是重启项目,进入监控页面发现与配置文件里面的部分配置对应不上,当时也没在意,以为是显示的默认配置。过阵子又卡死了,发现等待获取连接的线程数有10来个,果然和前面预料到的一样。于是在配置文件里面各种改数据库连接池的配置。但,并没有什么卵用,因为项目根本就没有读取到这些配置,这个问题,网上也没能找到类似的文章和解决方案,到现在也没有发现问题出现在哪儿,最后的解决办法是将配置文件里面关于数据库的配置全都注释掉,加上了一个java类来配置代码如下:/** * druid数据连接池配置 * @author win 10 * */ @Configuration public class DatasourceConfig { @Bean public DruidDataSource druidDataSource() { //Druid 数据源配置 DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://127.0.0.1/autoorder?useUnicode=true&amp;characterEncoding=UTF-8&amp;allowMultiQueries=true"); dataSource.setUsername("root"); dataSource.setPassword("root"); //初始连接数(默认值0) dataSource.setInitialSize(3); //最小连接数(默认值0) dataSource.setMinIdle(1); //最大连接数(默认值8,注意"maxIdle"这个属性已经弃用) dataSource.setMaxActive(20); dataSource.setMaxWait(30000); try { dataSource.setFilters("stat,wall,slf4j"); } catch (SQLException e) { e.printStackTrace(); } dataSource.setTestWhileIdle(true); dataSource.setValidationQuery("SELECT 1"); dataSource.setTimeBetweenEvictionRunsMillis(60000); dataSource.setMinEvictableIdleTimeMillis(30000); dataSource.setTestOnBorrow(true); dataSource.setTestOnReturn(false); return dataSource; } }重启项目进入发现配置is working!卡死的问题解决,但是还是未能找到为什么通过resource里面的配置文件部分配置不生效的原因。贴出配置文件:# 服务启动端口 server.port=8776 #定时器开关 server.scheduler.syncorder=false server.scheduler.xepnr=false # 运维管理相关参数 timeout.host=5000 timeout.project=5000 #spring.http.encoding.force=true #spring.http.encoding.charset=UTF-8 #spring.http.encoding.enabled=true #server.tomcat.uri-encoding=UTF-8 spring.thymeleaf.content-type=text/html spring.thymeleaf.cache=false spring.thymeleaf.mode=LEGACYHTML5 # jdbc_config datasource #spring.datasource.url=jdbc:mysql://127.0.0.1:3306/autoorder?useUnicode=true&amp;characterEncoding=UTF-8&amp;allowMultiQueries=true #spring.datasource.username=root #spring.datasource.password=root #spring.datasource.driver-class-name=com.mysql.jdbc.Driver #spring.datasource.type=com.alibaba.druid.pool.DruidDataSource #spring.datasource.maxActive=20 #spring.datasource.initialSize=1 #spring.datasource.minIdle=3 #spring.datasource.maxWait=20000 #连接空闲时长,超过时则会检查是否可用,与test-while-idle搭配 #spring.datasource.timeBetweenEvictionRunsMillis=60000 #spring.datasource.minEvictableIdleTimeMillis=300000 #连接空闲时检查是否可用 #spring.datasource.testWhileIdle=true #每次获取连接时 检查是否可用 #spring.datasource.testOnBorrow=true #每次归还连接时 检查是否可用 #spring.datasource.testOnReturn=fasle #缓存游标是否开启 #spring.datasource.poolPreparedStatements=false #spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 #spring.datasource.filters=stat,wall,slf4j #验证数据库连接的有效性的sql #spring.datasource.validationQuery=SELECT 1 #开启连接回收机制 #spring.datasource.removeAbandoned=true #单位 s #spring.datasource.removeAbandonedTimeout=180 #spring.datasource.timeBetweenEvictionRunsMillis=300000 # mybatis_config mybatis.mapper-locations= classpath:org/jc/db/mapper/*Mapper.xml mybatis.typeAliasesPackage= org.jc.db.entity #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID"; global-config.id-type=0 ##字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" field-strategy= 2 #驼峰下划线转换 db-column-underline= true #刷新mapper 调试神器 global-config.refresh-mapper= true #数据库大写下划线转换 #capital-mode: true #序列接口实现类配置 #key-generator: com.baomidou.springboot.xxx #逻辑删除配置 #logic-delete-value: 0 #logic-not-delete-value: 1 #自定义填充策略接口实现 #meta-object-handler: com.baomidou.springboot.xxx #自定义SQL注入器 #sql-injector: com.baomidou.springboot.xxx ## log_config DEBUG ERROR INFO WARN #logging.level.root=info ##logging.level.io.z77z.dao= DEBUG #logging.file= ./logs/express_interf.log #logging.pattern.console= %d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n #logging.pattern.file= %d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n spring.http.multipart.maxFileSize=100Mb spring.http.multipart.maxRequestSize=200Mb有看到的小伙伴知道这个问题所在的欢迎指点一二。记录一次创建springboot 配置文件不生效的坑使用idea自动生成了一个springboot项目。把application.properties改成了application.yml文件。打包成jar包运行。神奇的事情发生了,设置的端口不生效。解决:1.自己把yml文件改回properties文件。运行,仍旧不生效2.上网百度。各种方案。然后还是不行。3.突发奇想,因为我创建的项目是只需要一个五分钟循环执行的任务,所以我没导入web的maven。故导入。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>问题解决!!!!以上为个人经验,希望能给大家一个参考。原文链接:https://www.easck.com/cos/2021/0812/867820.shtml
  • [互动交流] FusionInsight_HD_8.2.0.1产品,在Flink SQL客户端中select 'hello'报错KeeperErrorCode = ConnectionLoss for /flink_base/flink
    flinkSQL client中select 还是报错的,请帮忙指点下,哪里有问题?谢谢org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.KeeperException$SessionClosedRequireAuthException: KeeperErrorCode = Session closed because client failed to authenticate for /flink_base/flink或者org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /flink_base/flinkzookeeper已经启动,192.168.0.82:24002 ,而且zookeeper中的ACL权限已经设置,但是在设置配额失败[zk: 192.168.0.82:24002(CONNECTED) 5] setquota -n 1000000 /flink_base/flink Insufficient permission : /flink_base/flink tail -f /home/dmp/app/ficlient/Flink/flink/log/flink-root-sql-client-192-168-0-85.log  中的日志如下flink-conf.yaml中的全部配置如下akka.ask.timeout: 120 s akka.client-socket-worker-pool.pool-size-factor: 1.0 akka.client-socket-worker-pool.pool-size-max: 2 akka.client-socket-worker-pool.pool-size-min: 1 akka.framesize: 10485760b akka.log.lifecycle.events: false akka.lookup.timeout: 30 s akka.server-socket-worker-pool.pool-size-factor: 1.0 akka.server-socket-worker-pool.pool-size-max: 2 akka.server-socket-worker-pool.pool-size-min: 1 akka.ssl.enabled: true akka.startup-timeout: 10 s akka.tcp.timeout: 60 s akka.throughput: 15 blob.fetch.backlog: 1000 blob.fetch.num-concurrent: 50 blob.fetch.retries: 50 blob.server.port: 32456-32520 blob.service.ssl.enabled: true classloader.check-leaked-classloader: false classloader.resolve-order: child-first client.rpc.port: 32651-32720 client.timeout: 120 s compiler.delimited-informat.max-line-samples: 10 compiler.delimited-informat.max-sample-len: 2097152 compiler.delimited-informat.min-line-samples: 2 env.hadoop.conf.dir: /home/dmp/app/ficlient/Flink/flink/conf env.java.opts.client: -Djava.io.tmpdir=/home/dmp/app/ficlient/Flink/tmp env.java.opts.jobmanager: -Djava.security.krb5.conf=/opt/huawei/Bigdata/common/runtime/krb5.conf -Djava.io.tmpdir=${PWD}/tmp -Des.security.indication=true env.java.opts.taskmanager: -Djava.security.krb5.conf=/opt/huawei/Bigdata/common/runtime/krb5.conf -Djava.io.tmpdir=${PWD}/tmp -Des.security.indication=true env.java.opts: -Xloggc:<LOG_DIR>/gc.log -XX:+PrintGCDetails -XX:-OmitStackTraceInFastThrow -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=20 -XX:GCLogFileSize=20M -Djdk.tls.ephemeralDHKeySize=3072 -Djava.library.path=${HADOOP_COMMON_HOME}/lib/native -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false -Dbeetle.application.home.path=/opt/huawei/Bigdata/common/runtime/security/config -Dwcc.configuration.path=/opt/huawei/Bigdata/common/runtime/security/config -Dscc.configuration.path=/opt/huawei/Bigdata/common/runtime/securityforscc/config -Dscc.bigdata.common=/opt/huawei/Bigdata/common/runtime env.yarn.conf.dir: /home/dmp/app/ficlient/Flink/flink/conf flink.security.enable: true flinkserver.alarm.cert.skip: true flinkserver.host.ip: fs.output.always-create-directory: false fs.overwrite-files: false heartbeat.interval: 10000 heartbeat.timeout: 120000 high-availability.job.delay: 10 s high-availability.storageDir: hdfs://hacluster/flink/recovery high-availability.zookeeper.client.acl: creator high-availability.zookeeper.client.connection-timeout: 90000 high-availability.zookeeper.client.max-retry-attempts: 5 high-availability.zookeeper.client.retry-wait: 5000 high-availability.zookeeper.client.session-timeout: 90000 high-availability.zookeeper.client.tolerate-suspended-connections: true high-availability.zookeeper.path.root: /flink high-availability.zookeeper.path.under.quota: /flink_base high-availability.zookeeper.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 high-availability.zookeeper.quota.enabled: true high-availability: zookeeper job.alarm.enable: true jobmanager.heap.size: 1024mb jobmanager.web.403-redirect-url: https://192.168.0.82:28443/web/pages/error/403.html jobmanager.web.404-redirect-url: https://192.168.0.82:28443/web/pages/error/404.html jobmanager.web.415-redirect-url: https://192.168.0.82:28443/web/pages/error/415.html jobmanager.web.500-redirect-url: https://192.168.0.82:28443/web/pages/error/500.html jobmanager.web.access-control-allow-origin: * jobmanager.web.accesslog.enable: true jobmanager.web.allow-access-address: * jobmanager.web.backpressure.cleanup-interval: 600000 jobmanager.web.backpressure.delay-between-samples: 50 jobmanager.web.backpressure.num-samples: 100 jobmanager.web.backpressure.refresh-interval: 60000 jobmanager.web.cache-directive: no-store jobmanager.web.checkpoints.disable: false jobmanager.web.checkpoints.history: 10 jobmanager.web.expires-time: 0 jobmanager.web.history: 5 jobmanager.web.logout-timer: 600000 jobmanager.web.pragma-value: no-cache jobmanager.web.refresh-interval: 3000 jobmanager.web.ssl.enabled: false jobmanager.web.x-frame-options: DENY library-cache-manager.cleanup.interval: 3600 metrics.internal.query-service.port: 28844-28943 metrics.reporter.alarm.factory.class: com.huawei.mrs.flink.alarm.FlinkAlarmReporterFactory metrics.reporter.alarm.interval: 30 s metrics.reporter.alarm.job.alarm.checkpoint.consecutive.failures.num: 5 metrics.reporter.alarm.job.alarm.failure.restart.rate: 80 metrics.reporter.alarm.job.alarm.task.backpressure.duration: 180 s metrics.reporter: alarm nettyconnector.message.delimiter: $_ nettyconnector.registerserver.topic.storage: /flink/nettyconnector nettyconnector.sinkserver.port.range: 28444-28843 nettyconnector.ssl.enabled: false parallelism.default: 1 query.client.network-threads: 0 query.proxy.network-threads: 0 query.proxy.ports: 32541-32560 query.proxy.query-threads: 0 query.server.network-threads: 0 query.server.ports: 32521-32540 query.server.query-threads: 0 resourcemanager.taskmanager-timeout: 300000 rest.await-leader-timeout: 30000 rest.bind-port: 32261-32325 rest.client.max-content-length: 104857600 rest.connection-timeout: 15000 rest.idleness-timeout: 300000 rest.retry.delay: 3000 rest.retry.max-attempts: 20 rest.server.max-content-length: 104857600 rest.server.numThreads: 4 restart-strategy.failure-rate.delay: 10 s restart-strategy.failure-rate.failure-rate-interval: 60 s restart-strategy.failure-rate.max-failures-per-interval: 1 restart-strategy.fixed-delay.attempts: 3 restart-strategy.fixed-delay.delay: 10 s restart-strategy: none security.cookie: 9477298cd52a3e409ed0bc570bdc795179fcc7c301a1225e22f47fe0a3db47c2 security.enable: true security.kerberos.login.contexts: Client,KafkaClient security.kerberos.login.keytab: security.kerberos.login.principal: security.kerberos.login.use-ticket-cache: true security.networkwide.listen.restrict: true security.ssl.algorithms: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 security.ssl.enabled: false security.ssl.encrypt.enabled: false security.ssl.key-password: Bapuser@9000 security.ssl.keystore-password: Bapuser@9000 security.ssl.keystore: ssl/flink.keystore security.ssl.protocol: TLSv1.2 security.ssl.rest.enabled: false security.ssl.truststore-password: Bapuser@9000 security.ssl.truststore: ssl/flink.truststore security.ssl.verify-hostname: false slot.idle.timeout: 50000 slot.request.timeout: 300000 state.backend.fs.checkpointdir: hdfs://hacluster/flink/checkpoints state.backend.fs.memory-threshold: 20kb state.backend.incremental: true state.backend: rocksdb state.savepoints.dir: hdfs://hacluster/flink/savepoint task.cancellation.interval: 30000 task.cancellation.timeout: 180000 taskmanager.data.port: 32391-32455 taskmanager.data.ssl.enabled: false taskmanager.debug.memory.logIntervalMs: 0 taskmanager.debug.memory.startLogThread: false taskmanager.heap.size: 1024mb taskmanager.initial-registration-pause: 500 ms taskmanager.max-registration-pause: 30 s taskmanager.maxRegistrationDuration: 5 min taskmanager.memory.fraction: 0.7 taskmanager.memory.off-heap: false taskmanager.memory.preallocate: false taskmanager.memory.segment-size: 32768 taskmanager.network.detailed-metrics: false taskmanager.network.memory.buffers-per-channel: 2 taskmanager.network.memory.floating-buffers-per-gate: 8 taskmanager.network.memory.fraction: 0.1 taskmanager.network.memory.max: 1gb taskmanager.network.memory.min: 64mb taskmanager.network.netty.client.connectTimeoutSec: 300 taskmanager.network.netty.client.numThreads: -1 taskmanager.network.netty.num-arenas: -1 taskmanager.network.netty.sendReceiveBufferSize: 4096 taskmanager.network.netty.server.backlog: 0 taskmanager.network.netty.server.numThreads: -1 taskmanager.network.netty.transport: nio taskmanager.network.numberOfBuffers: 2048 taskmanager.network.request-backoff.initial: 100 taskmanager.network.request-backoff.max: 10000 taskmanager.numberOfTaskSlots: 1 taskmanager.refused-registration-pause: 10 s taskmanager.registration.timeout: 5 min taskmanager.rpc.port: 32326-32390 taskmanager.runtime.hashjoin-bloom-filters: false taskmanager.runtime.max-fan: 128 taskmanager.runtime.sort-spilling-threshold: 0.8 use.path.filesystem: true use.smarterleaderlatch: true web.submit.enable: false web.timeout: 10000 yarn.application-attempt-failures-validity-interval: 600000 yarn.application-attempts: 5 yarn.application-master.port: 32586-32650 yarn.heap-cutoff-min: 384 yarn.heap-cutoff-ratio: 0.25 yarn.heartbeat-delay: 5 yarn.heartbeat.container-request-interval: 500 yarn.maximum-failed-containers: 5 yarn.per-job-cluster.include-user-jar: ORDER zk.ssl.enabled: false zookeeper.clientPort.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 zookeeper.root.acl: OPEN zookeeper.sasl.disable: false zookeeper.sasl.login-context-name: Client zookeeper.sasl.service-name: zookeeper zookeeper.secureClientPort.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 
  • [互动交流] FusionInsight_HD_8.2.0.1产品,在Flink SQL客户端中select 'hello'报错KeeperErrorCode = ConnectionLoss for /flink_base/flink
    flinkSQL client中select 还是报错的,请帮忙指点下,哪里有问题?谢谢org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.KeeperException$SessionClosedRequireAuthException: KeeperErrorCode = Session closed because client failed to authenticate for /flink_base/flink或者org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /flink_base/flinkzookeeper已经启动,192.168.0.82:24002 ,而且zookeeper中的ACL权限已经设置,但是在设置配额失败[zk: 192.168.0.82:24002(CONNECTED) 2] create /flink_base/flink_base Created /flink_base/flink_base [zk: 192.168.0.82:24002(CONNECTED) 3] ls /flink_base/ Path must not end with / character [zk: 192.168.0.82:24002(CONNECTED) 4] ls /flink_base [flink, flink_base] [zk: 192.168.0.82:24002(CONNECTED) 5] [zk: 192.168.0.82:24002(CONNECTED) 5] [zk: 192.168.0.82:24002(CONNECTED) 5] [zk: 192.168.0.82:24002(CONNECTED) 5] setquota -n 1000000 /flink_base/flink Insufficient permission : /flink_base/flink [zk: 192.168.0.82:24002(CONNECTED) 6] getAcl /flink_base/flink 'world,'anyone : cdrwa [zk: 192.168.0.82:24002(CONNECTED) 7] setAcl /flink_base/flink world:anyone:rwcda [zk: 192.168.0.82:24002(CONNECTED) 8] setquota -n 1000000 /flink_base/flink Insufficient permission : /flink_base/flink [zk: 192.168.0.82:24002(CONNECTED) 9] getAcl /flink_base/ Path must not end with / character [zk: 192.168.0.82:24002(CONNECTED) 10] getAcl /flink_base 'world,'anyone : cdrwa [zk: 192.168.0.82:24002(CONNECTED) 11] getAcl /flink_base/flink 'world,'anyone : cdrwa [zk: 192.168.0.82:24002(CONNECTED) 12] ls /zookeeper/quota [beeline, elasticsearch, flink_base, graphbase, hadoop, hadoop-adapter-data, hadoop-flag, hadoop-ha, hbase, hdfs-acl-log, hive, hiveserver2, kafka, loader, mr-ha, rmstore, sparkthriftserver, sparkthriftserver2x, sparkthriftserver2x_sparkInternal_HAMode, yarn-leader-election] [zk: 192.168.0.82:24002(CONNECTED) 13] ls /zookeeper/quota/flink_base [zookeeper_limits, zookeeper_stats] [zk: 192.168.0.82:24002(CONNECTED) 5] setquota -n 1000000 /flink_base/flink Insufficient permission : /flink_base/flink tail -f /home/dmp/app/ficlient/Flink/flink/log/flink-root-sql-client-192-168-0-85.log  中的日志如下flink-conf.yaml中的全部配置如下akka.ask.timeout: 120 s akka.client-socket-worker-pool.pool-size-factor: 1.0 akka.client-socket-worker-pool.pool-size-max: 2 akka.client-socket-worker-pool.pool-size-min: 1 akka.framesize: 10485760b akka.log.lifecycle.events: false akka.lookup.timeout: 30 s akka.server-socket-worker-pool.pool-size-factor: 1.0 akka.server-socket-worker-pool.pool-size-max: 2 akka.server-socket-worker-pool.pool-size-min: 1 akka.ssl.enabled: true akka.startup-timeout: 10 s akka.tcp.timeout: 60 s akka.throughput: 15 blob.fetch.backlog: 1000 blob.fetch.num-concurrent: 50 blob.fetch.retries: 50 blob.server.port: 32456-32520 blob.service.ssl.enabled: true classloader.check-leaked-classloader: false classloader.resolve-order: child-first client.rpc.port: 32651-32720 client.timeout: 120 s compiler.delimited-informat.max-line-samples: 10 compiler.delimited-informat.max-sample-len: 2097152 compiler.delimited-informat.min-line-samples: 2 env.hadoop.conf.dir: /home/dmp/app/ficlient/Flink/flink/conf env.java.opts.client: -Djava.io.tmpdir=/home/dmp/app/ficlient/Flink/tmp env.java.opts.jobmanager: -Djava.security.krb5.conf=/opt/huawei/Bigdata/common/runtime/krb5.conf -Djava.io.tmpdir=${PWD}/tmp -Des.security.indication=true env.java.opts.taskmanager: -Djava.security.krb5.conf=/opt/huawei/Bigdata/common/runtime/krb5.conf -Djava.io.tmpdir=${PWD}/tmp -Des.security.indication=true env.java.opts: -Xloggc:<LOG_DIR>/gc.log -XX:+PrintGCDetails -XX:-OmitStackTraceInFastThrow -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=20 -XX:GCLogFileSize=20M -Djdk.tls.ephemeralDHKeySize=3072 -Djava.library.path=${HADOOP_COMMON_HOME}/lib/native -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false -Dbeetle.application.home.path=/opt/huawei/Bigdata/common/runtime/security/config -Dwcc.configuration.path=/opt/huawei/Bigdata/common/runtime/security/config -Dscc.configuration.path=/opt/huawei/Bigdata/common/runtime/securityforscc/config -Dscc.bigdata.common=/opt/huawei/Bigdata/common/runtime env.yarn.conf.dir: /home/dmp/app/ficlient/Flink/flink/conf flink.security.enable: true flinkserver.alarm.cert.skip: true flinkserver.host.ip: fs.output.always-create-directory: false fs.overwrite-files: false heartbeat.interval: 10000 heartbeat.timeout: 120000 high-availability.job.delay: 10 s high-availability.storageDir: hdfs://hacluster/flink/recovery high-availability.zookeeper.client.acl: creator high-availability.zookeeper.client.connection-timeout: 90000 high-availability.zookeeper.client.max-retry-attempts: 5 high-availability.zookeeper.client.retry-wait: 5000 high-availability.zookeeper.client.session-timeout: 90000 high-availability.zookeeper.client.tolerate-suspended-connections: true high-availability.zookeeper.path.root: /flink high-availability.zookeeper.path.under.quota: /flink_base high-availability.zookeeper.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 high-availability.zookeeper.quota.enabled: true high-availability: zookeeper job.alarm.enable: true jobmanager.heap.size: 1024mb jobmanager.web.403-redirect-url: https://192.168.0.82:28443/web/pages/error/403.html jobmanager.web.404-redirect-url: https://192.168.0.82:28443/web/pages/error/404.html jobmanager.web.415-redirect-url: https://192.168.0.82:28443/web/pages/error/415.html jobmanager.web.500-redirect-url: https://192.168.0.82:28443/web/pages/error/500.html jobmanager.web.access-control-allow-origin: * jobmanager.web.accesslog.enable: true jobmanager.web.allow-access-address: * jobmanager.web.backpressure.cleanup-interval: 600000 jobmanager.web.backpressure.delay-between-samples: 50 jobmanager.web.backpressure.num-samples: 100 jobmanager.web.backpressure.refresh-interval: 60000 jobmanager.web.cache-directive: no-store jobmanager.web.checkpoints.disable: false jobmanager.web.checkpoints.history: 10 jobmanager.web.expires-time: 0 jobmanager.web.history: 5 jobmanager.web.logout-timer: 600000 jobmanager.web.pragma-value: no-cache jobmanager.web.refresh-interval: 3000 jobmanager.web.ssl.enabled: false jobmanager.web.x-frame-options: DENY library-cache-manager.cleanup.interval: 3600 metrics.internal.query-service.port: 28844-28943 metrics.reporter.alarm.factory.class: com.huawei.mrs.flink.alarm.FlinkAlarmReporterFactory metrics.reporter.alarm.interval: 30 s metrics.reporter.alarm.job.alarm.checkpoint.consecutive.failures.num: 5 metrics.reporter.alarm.job.alarm.failure.restart.rate: 80 metrics.reporter.alarm.job.alarm.task.backpressure.duration: 180 s metrics.reporter: alarm nettyconnector.message.delimiter: $_ nettyconnector.registerserver.topic.storage: /flink/nettyconnector nettyconnector.sinkserver.port.range: 28444-28843 nettyconnector.ssl.enabled: false parallelism.default: 1 query.client.network-threads: 0 query.proxy.network-threads: 0 query.proxy.ports: 32541-32560 query.proxy.query-threads: 0 query.server.network-threads: 0 query.server.ports: 32521-32540 query.server.query-threads: 0 resourcemanager.taskmanager-timeout: 300000 rest.await-leader-timeout: 30000 rest.bind-port: 32261-32325 rest.client.max-content-length: 104857600 rest.connection-timeout: 15000 rest.idleness-timeout: 300000 rest.retry.delay: 3000 rest.retry.max-attempts: 20 rest.server.max-content-length: 104857600 rest.server.numThreads: 4 restart-strategy.failure-rate.delay: 10 s restart-strategy.failure-rate.failure-rate-interval: 60 s restart-strategy.failure-rate.max-failures-per-interval: 1 restart-strategy.fixed-delay.attempts: 3 restart-strategy.fixed-delay.delay: 10 s restart-strategy: none security.cookie: 9477298cd52a3e409ed0bc570bdc795179fcc7c301a1225e22f47fe0a3db47c2 security.enable: true security.kerberos.login.contexts: Client,KafkaClient security.kerberos.login.keytab: security.kerberos.login.principal: security.kerberos.login.use-ticket-cache: true security.networkwide.listen.restrict: true security.ssl.algorithms: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 security.ssl.enabled: false security.ssl.encrypt.enabled: false security.ssl.key-password: Bapuser@9000 security.ssl.keystore-password: Bapuser@9000 security.ssl.keystore: ssl/flink.keystore security.ssl.protocol: TLSv1.2 security.ssl.rest.enabled: false security.ssl.truststore-password: Bapuser@9000 security.ssl.truststore: ssl/flink.truststore security.ssl.verify-hostname: false slot.idle.timeout: 50000 slot.request.timeout: 300000 state.backend.fs.checkpointdir: hdfs://hacluster/flink/checkpoints state.backend.fs.memory-threshold: 20kb state.backend.incremental: true state.backend: rocksdb state.savepoints.dir: hdfs://hacluster/flink/savepoint task.cancellation.interval: 30000 task.cancellation.timeout: 180000 taskmanager.data.port: 32391-32455 taskmanager.data.ssl.enabled: false taskmanager.debug.memory.logIntervalMs: 0 taskmanager.debug.memory.startLogThread: false taskmanager.heap.size: 1024mb taskmanager.initial-registration-pause: 500 ms taskmanager.max-registration-pause: 30 s taskmanager.maxRegistrationDuration: 5 min taskmanager.memory.fraction: 0.7 taskmanager.memory.off-heap: false taskmanager.memory.preallocate: false taskmanager.memory.segment-size: 32768 taskmanager.network.detailed-metrics: false taskmanager.network.memory.buffers-per-channel: 2 taskmanager.network.memory.floating-buffers-per-gate: 8 taskmanager.network.memory.fraction: 0.1 taskmanager.network.memory.max: 1gb taskmanager.network.memory.min: 64mb taskmanager.network.netty.client.connectTimeoutSec: 300 taskmanager.network.netty.client.numThreads: -1 taskmanager.network.netty.num-arenas: -1 taskmanager.network.netty.sendReceiveBufferSize: 4096 taskmanager.network.netty.server.backlog: 0 taskmanager.network.netty.server.numThreads: -1 taskmanager.network.netty.transport: nio taskmanager.network.numberOfBuffers: 2048 taskmanager.network.request-backoff.initial: 100 taskmanager.network.request-backoff.max: 10000 taskmanager.numberOfTaskSlots: 1 taskmanager.refused-registration-pause: 10 s taskmanager.registration.timeout: 5 min taskmanager.rpc.port: 32326-32390 taskmanager.runtime.hashjoin-bloom-filters: false taskmanager.runtime.max-fan: 128 taskmanager.runtime.sort-spilling-threshold: 0.8 use.path.filesystem: true use.smarterleaderlatch: true web.submit.enable: false web.timeout: 10000 yarn.application-attempt-failures-validity-interval: 600000 yarn.application-attempts: 5 yarn.application-master.port: 32586-32650 yarn.heap-cutoff-min: 384 yarn.heap-cutoff-ratio: 0.25 yarn.heartbeat-delay: 5 yarn.heartbeat.container-request-interval: 500 yarn.maximum-failed-containers: 5 yarn.per-job-cluster.include-user-jar: ORDER zk.ssl.enabled: false zookeeper.clientPort.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 zookeeper.root.acl: OPEN zookeeper.sasl.disable: false zookeeper.sasl.login-context-name: Client zookeeper.sasl.service-name: zookeeper zookeeper.secureClientPort.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 
  • [互动交流] FusionInsight_HD_8.2.0.1产品,在Flink SQL客户端中select 'hello'报错KeeperErrorCode = ConnectionLoss for /flink_base/flink
    1.在flink sql client中执行sql  直接报错[ERROR] Could not execute SQL statement. Reason: org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /flink_base/flink 2.而且进入zookeeper中查询也是报错,求解求解[omm@192-168-0-82 zookeeper]$ pwd /opt/huawei/Bigdata/FusionInsight_HD_8.2.0.1/install/FusionInsight-Zookeeper-3.6.3/zookeeper [omm@192-168-0-82 zookeeper]$ bin/zkCli.sh -server 192.168.0.82:24002 Connecting to 192.168.0.82:24002 Welcome to ZooKeeper! JLine support is enabled  WATCHER::  WatchedEvent state:SyncConnected type:None path:null [zk: 192.168.0.82:24002(CONNECTING) 0] ls / KeeperErrorCode = Session closed because client failed to authenticate for / [zk: 192.168.0.82:24002(CONNECTED) 1] WATCHER::  WatchedEvent state:Disconnected type:None path:null  WATCHER::  WatchedEvent state:SyncConnected type:None path:null  WATCHER::  WatchedEvent state:Disconnected type:None path:null 后面是一直循环WATCHER:,flink-conf.yaml中的部分设置如下 flink.security.enable: true flinkserver.alarm.cert.skip: true flinkserver.host.ip: fs.output.always-create-directory: false fs.overwrite-files: false heartbeat.interval: 10000 heartbeat.timeout: 120000 high-availability.job.delay: 10 s high-availability.storageDir: hdfs://hacluster/flink/recovery high-availability.zookeeper.client.acl: creator high-availability.zookeeper.client.connection-timeout: 90000 high-availability.zookeeper.client.max-retry-attempts: 5 high-availability.zookeeper.client.retry-wait: 5000 high-availability.zookeeper.client.session-timeout: 90000 high-availability.zookeeper.client.tolerate-suspended-connections: true high-availability.zookeeper.path.root: /flink high-availability.zookeeper.path.under.quota: /flink_base high-availability.zookeeper.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 high-availability.zookeeper.quota.enabled: true high-availability: zookeeper yarn.application-attempts: 5 yarn.application-master.port: 32586-32650 yarn.heap-cutoff-min: 384 yarn.heap-cutoff-ratio: 0.25 yarn.heartbeat-delay: 5 yarn.heartbeat.container-request-interval: 500 yarn.maximum-failed-containers: 5 yarn.per-job-cluster.include-user-jar: ORDER zk.ssl.enabled: false zookeeper.clientPort.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 zookeeper.root.acl: OPEN zookeeper.sasl.disable: false zookeeper.sasl.login-context-name: Client zookeeper.sasl.service-name: zookeeper zookeeper.secureClientPort.quorum: 192.168.0.82:24002,192.168.0.81:24002,192.168.0.80:24002 
  • [技术干货] 基于mysql+jdbc+java swing的学生成绩信息管理系统-转载
     Java课程设计 前言 来csdn也有两年了,在这期间学了很多的知识,也跟着许多的大神做了几个小项目。但自己也在想什么时候能够有个自己的项目,之前在学校做过一个基于集合存储数据的学生信息管理系统,现在想着改进一下,于是趁着暑假做了一个小项目吧(基于mysql+jdbc+java swing的学生成绩信息管理系统)。一来是巩固自己的学习成果,二来是记录自己的学习历程,期待后面能做出更多的项目吧。  设计需求和思路 设计需求 1.利用jdbc将java程序与mysql建立连接  2.利用java swing将学生信息和成绩信息显现出来  3.通过使用sql指令来实现对学生信息和成绩信息的crud(增查改删)操作  设计思路 1.利用Navicat创建两个数据表(stu和classes),同时两个数据表用外键约束连接(  CONSTRAINT `fk_classes_stu` FOREIGN KEY (`class_id`) REFERENCES `stu` (`stu_num`) ON DELETE CASCADE )  2.使用sql指令对数据表中数据进行增删改查,并通过java swing显示  3.查询所有学生信息,利用连接查询将两个数据表的信息一并显示  详细操作 1.设计主界面(登录注册界面) 账号和密码通过HashMap来存储,账号为键密码为值,利用其基本方法来添加账号密码(注册),以及登录。  package view;   import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; import java.util.Map;   public class MainView extends JFrame {     private Map<String,String> userhashmap=new HashMap<>();     JPanel p1=new JPanel();     JPanel p2=new JPanel();     JPanel p3=new JPanel();     JPanel p4=new JPanel();     JLabel welcome=new JLabel("欢迎来到学生信息管理系统");     JLabel username=new JLabel("账号:");     JLabel password=new JLabel("密码:");       JTextField usernametext=new JTextField(10);     JPasswordField passwordField=new JPasswordField(10);       JButton confirm=new JButton("确认");     JButton exit=new JButton("退出");     JButton register=new JButton("注册");     public MainView() {         this.setTitle("学生信息管理系统");         this.setSize(800, 500);         this.setLayout(new GridLayout(4, 1,10,10));         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);           p4.add(welcome);         p1.add(username);         p1.add(usernametext);         p2.add(password);         p2.add(passwordField);         p3.add(confirm);         p3.add(register);         p3.add(exit);           this.add(p4);         this.add(p1);         this.add(p2);         this.add(p3);         register.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 if(e.getSource()==register){                     if(userhashmap.containsKey(usernametext.getText())){                         JOptionPane.showMessageDialog(null,"注册失败,您的账号已存在","警告",JOptionPane.WARNING_MESSAGE);                         return;                     }                     userhashmap.put(usernametext.getText(),passwordField.getText());                     JOptionPane.showMessageDialog(null,"注册成功","通知",JOptionPane.INFORMATION_MESSAGE);                 }             }         });         confirm.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 if (e.getSource() == confirm) {                     if (userhashmap.containsKey(usernametext.getText())) {                         if (userhashmap.get(usernametext.getText()).equals(passwordField.getText())) {                             JOptionPane.showMessageDialog(null,"登陆成功","通知",JOptionPane.INFORMATION_MESSAGE);                             dispose();                             ManagerView mv=new ManagerView();                             mv.setVisible(true);                         } else {                             JOptionPane.showMessageDialog(null,"密码错误","警告",JOptionPane.WARNING_MESSAGE);                         }                     }                     else{                         JOptionPane.showMessageDialog(null,"该用户不存在","警告",JOptionPane.WARNING_MESSAGE);                     }                 }             }         });         exit.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 System.exit(0);             }         });     }     public static void main(String[] args) {         MainView m=new MainView();         m.setVisible(true);     } }      2.设计学生信息管理界面和成绩信息管理界面 使用GridBagLayout布局设置左边为学生信息管理的按钮,右边为成绩信息管理的按钮  package view;   import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;   public class ManagerView extends JFrame{        JButton insert=new JButton("添加学生信息");      JButton delete=new JButton("删除学生");     JButton update=new JButton("学生信息修改");     JButton query=new JButton("查询学生信息");     JButton queryall=new JButton("查询所有学生信息");       JButton insertclass=new JButton("添加成绩信息");     JButton deleteclass=new JButton("删除成绩信息");     JButton updateclass=new JButton("修改成绩信息");     JLabel labelstu=new JLabel("学生管理系统");//设置“学生管理系统”标签     JLabel labelclass=new JLabel("成绩管理系统");//设置“成绩管理系统”标签       public ManagerView(){         this.setTitle("学生成绩管理");         this.setSize(1200,500);         this.setLayout(new GridBagLayout());         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);           //设置每个按钮长,高为140,120         Dimension dimension=new Dimension(140,30);//通过setPreferredSize()方法来设置按钮和标签大小,但要传入Dimension对象         insert.setPreferredSize(dimension);         delete.setPreferredSize(dimension);         update.setPreferredSize(dimension);         query.setPreferredSize(dimension);         queryall.setPreferredSize(dimension);         insertclass.setPreferredSize(dimension);         deleteclass.setPreferredSize(dimension);         updateclass.setPreferredSize(dimension);         labelstu.setPreferredSize(dimension);         labelclass.setPreferredSize(dimension);           GridBagConstraints constraintsleft=new GridBagConstraints();         constraintsleft.gridx = 0; // 列为0         constraintsleft.gridy = GridBagConstraints.RELATIVE; // 按钮的行相对于前一个按钮的行         constraintsleft.anchor = GridBagConstraints.CENTER; // 设置水平方向上的位置居中         constraintsleft.fill = GridBagConstraints.HORIZONTAL; // 填充水平方向         /*constraintsleft.weightx = 0.5; // 水平方向上的权重为0.5*/         constraintsleft.insets = new Insets(5, 5, 5, 200); // 设置按钮的内边距         constraintsleft.ipadx = 10;           this.add(labelstu,constraintsleft);         this.add(insert,constraintsleft);         this.add(delete,constraintsleft);         this.add(update,constraintsleft);         this.add(query,constraintsleft);         this.add(queryall,constraintsleft);           GridBagConstraints constraintsright=new GridBagConstraints();         constraintsright.gridx=1;         constraintsleft.gridy = GridBagConstraints.RELATIVE; // 按钮的行相对于前一个按钮的行         constraintsleft.anchor = GridBagConstraints.CENTER; // 设置水平方向上的位置居中         constraintsleft.fill = GridBagConstraints.HORIZONTAL; // 填充水平方向         /*constraintsleft.weightx = 0.5; // 水平方向上的权重为0.5*/         constraintsleft.insets = new Insets(5, 200, 5, 5); // 设置按钮的内边距         constraintsleft.ipadx = 10;           this.add(labelclass,constraintsright);         this.add(insertclass,constraintsright);         this.add(deleteclass,constraintsright);         this.add(updateclass,constraintsright);           insert.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 InsertStuView insertStuView=new InsertStuView();                 insertStuView.setVisible(true);             }         });         delete.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 DeleteStuView deleteStuView=new DeleteStuView();                 deleteStuView.setVisible(true);             }         });         update.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 UpdateStuview updateStuview=new UpdateStuview();                 updateStuview.setVisible(true);             }         });         query.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 QueryStuView queryStuView=new QueryStuView();                 queryStuView.setVisible(true);             }         });         insertclass.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 InsertClassView insertClassView=new InsertClassView();                 insertClassView.setVisible(true);             }         });         deleteclass.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 DeleteClassView deleteClassView=new DeleteClassView();                 deleteClassView.setVisible(true);             }         });         updateclass.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 UpdateClassView updateClassView =new UpdateClassView();                 updateClassView.setVisible(true);             }         }); /*        p1.add(insert);         p2.add(delete);         p3.add(query);         p4.add(update);         p5.add(orderby);*/         queryall.addActionListener(new ActionListener(){             @Override             public void actionPerformed(ActionEvent e) {                 QueryAllView queryAllView=new QueryAllView();                 queryAllView.setVisible(true);             }         });     } }    3.设计学生信息操作 添加学生信息 package view;   import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import service.StuManage;   public class InsertStuView extends JFrame {     JLabel labelname=new JLabel("请输入您的姓名");     JLabel labelgender=new JLabel("请输入您的性别");     JLabel labelid=new JLabel("请输入您的学号");     JTextField textname=new JTextField(15);     JTextField textgender=new JTextField(15);     JTextField textid=new JTextField(15);     JButton confirm=new JButton("确定");     JButton cancel=new JButton("取消");     JPanel p1=new JPanel();     JPanel p2=new JPanel();     JPanel p3=new JPanel();     JPanel p4=new JPanel();     public InsertStuView(){         this.setSize(500,300);         this.setTitle("请添加学生信息");         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         this.setLayout(new GridLayout(4,1,10,10));           p1.add(labelname);         p1.add(textname);         p2.add(labelgender);         p2.add(textgender);         p3.add(labelid);         p3.add(textid);         p4.add(confirm);         p4.add(cancel);           this.add(p1);         this.add(p2);         this.add(p3);         this.add(p4);         confirm.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 try {                     StuManage.insertStudata(textname.getText(),textgender.getText(),textid.getText());                 } catch (Exception ex) {                     JOptionPane.showMessageDialog(null,"添加失败","警告",JOptionPane.WARNING_MESSAGE);                 }                 dispose();             }         });         cancel.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 dispose();             }         });     } }   通过学号删除学生,因为学号不会重复 package view;   import service.StuManage;   import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;   public class DeleteStuView extends JFrame {     JLabel labelid=new JLabel("请输入您想删除学生的学号");     JTextField textField=new JTextField(15);     JPanel p1=new JPanel();     JPanel p2=new JPanel();     JButton confirm=new JButton("确定");     JButton cancel=new JButton("取消");     public DeleteStuView(){         this.setSize(500,300);         this.setLayout(new GridLayout(2,1,0,0));         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         this.setTitle("删除学生");         p1.add(labelid);         p1.add(textField);         p2.add(confirm);         p2.add(cancel);         p1.setBorder(BorderFactory.createEmptyBorder(70,0,0,0));         this.add(p1);         this.add(p2);           confirm.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 try{                     StuManage.deleteStudata(textField.getText());                 }catch(Exception ex){                     JOptionPane.showMessageDialog(null,"删除失败","警告",JOptionPane.WARNING_MESSAGE);                 }                 dispose();             }         });           cancel.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 dispose();             }         });     } }    学生信息修改 package view; import service.StuManage;   import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;   public class UpdateStuview extends JFrame{ JLabel labeloldid=new JLabel("请输入您要修改学生的学号"); JLabel labelname=new JLabel("请输入您要修改后的姓名"); JLabel labelgender=new JLabel("请输入您要修改后的性别"); JLabel labelid=new JLabel("请输入您要修改后的学号"); JTextField textFieldoldid=new JTextField(15); JTextField textname=new JTextField(15); JTextField textgender=new JTextField(15); JTextField textid=new JTextField(15); JButton confirm=new JButton("确定"); JButton cancel=new JButton("取消"); JPanel p1=new JPanel(); JPanel p2=new JPanel(); JPanel p3=new JPanel(); JPanel p4=new JPanel(); JPanel p5=new JPanel(); public UpdateStuview(){ this.setSize(500,300); this.setTitle("请修改学生信息"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(new GridLayout(5,1,10,10)); p1.add(labeloldid); p1.add(textFieldoldid); p2.add(labelname); p2.add(textname); p3.add(labelgender); p3.add(textgender); p4.add(labelid); p4.add(textid); p5.add(confirm); p5.add(cancel);   this.add(p1); this.add(p2); this.add(p3); this.add(p4); this.add(p5); confirm.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { StuManage.updateStudata(textname.getText(),textgender.getText(),textid.getText(),textFieldoldid.getText()); } catch (Exception ex) { JOptionPane.showMessageDialog(null,"修改失败","警告",JOptionPane.WARNING_MESSAGE); } dispose(); } }); cancel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dispose(); } }); } }    查询学生信息 package view;   import service.ClassManage;   import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;   public class QueryStuView extends JFrame {     JLabel id=new JLabel("请输入学生的id");     JTextField textid=new JTextField(15);     JButton confirm=new JButton("确定");     JButton cancel=new JButton("取消");     JLabel labelstu=new JLabel("学生信息表");     JLabel labelscore=new JLabel("成绩信息表");       JPanel p1=new JPanel();     JPanel p2=new JPanel();     JPanel p3=new JPanel();     JPanel p4=new JPanel();     String[] stucolumnname={"姓名","性别","学号"};     String[] scorecolumnname={"学科","分数","教师"}; public QueryStuView(){     this.setLayout(new GridLayout(4,4,10,10));     this.setTitle("学生信息查询");     this.setSize(1000,700);       DefaultTableModel stumodel=new DefaultTableModel();     DefaultTableModel scoremodel=new DefaultTableModel();       stumodel.setColumnIdentifiers(stucolumnname);     scoremodel.setColumnIdentifiers(scorecolumnname);       JTable stutable = new JTable(stumodel);     JTable scoretable=new JTable(scoremodel);     JScrollPane scrollstu=new JScrollPane(stutable);     JScrollPane scrollscore=new JScrollPane(scoretable);       p1.setBorder(BorderFactory.createEmptyBorder(70,0,0,0));     p1.add(id);     p1.add(textid);     p2.add(confirm);     p2.add(cancel);     p3.add(labelstu);     p3.add(scrollstu);     p4.add(labelscore);     p4.add(scrollscore);       this.add(p1);     this.add(p2);     this.add(p3);     this.add(p4);       confirm.addActionListener(new ActionListener() {         @Override         public void actionPerformed(ActionEvent e) {             try{                 stumodel.setRowCount(0);                 scoremodel.setRowCount(0);                 ClassManage.querystu(textid.getText(),stumodel,scoremodel);             }catch(Exception ex){                 JOptionPane.showMessageDialog(null,"查找失败","警告",JOptionPane.WARNING_MESSAGE);             }         }     });     cancel.addActionListener(new ActionListener() {         @Override         public void actionPerformed(ActionEvent e) {             dispose();         }     });     } }   查询所有学生信息 package view;   import service.ClassManage;   import javax.swing.*; import javax.swing.table.DefaultTableModel;   public class QueryAllView extends JFrame{     JLabel text=new JLabel("学生信息查询");     DefaultTableModel model=new DefaultTableModel();     JTable queryall=new JTable(model);     JScrollPane jScrollPane=new JScrollPane(queryall);     JPanel p1=new JPanel();     JPanel p2=new JPanel();       public QueryAllView(){         this.setTitle("学生成绩查询");         this.setSize(1000,700);         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);           String[] columnname={"姓名","性别","学号","科目","分数"};         model.setColumnIdentifiers(columnname);         p1.add(text);         p2.add(jScrollPane);           this.add(p1);         this.add(p2);         try{             ClassManage.queryall(model);         }catch(Exception ex){             JOptionPane.showMessageDialog(null,"查询失败","警告",JOptionPane.WARNING_MESSAGE);         }     } }  ———————————————— 版权声明:本文为CSDN博主「Java雪荷」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/xyendjsj/article/details/131774615 
  • [互动交流] 4.1.0版本的设计器如何安装java拓展
    默认安装失败,手动安装应该选择哪个目录呀?我的jre在c盘里,我选择c盘,提示安装成功,但是好像并没有安装成功,如何检验是否安装成功了?
  • [技术干货] Apache POI(处理Miscrosoft Office各种文件格式)
    学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需写作干货注入能量… 热爱写作,愿意让自己成为更好的人…一、Apache POI介绍Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。一般情况下,POI 都是用于操作 Excel 文件。二、应用场景Apache POI 的应用场景:银行网银系统导出交易明细各种业务系统导出Excel报表批量导入业务数据三、使用步骤1.导入maven坐标代码如下(示例):<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.16</version> </dependency>2.写入代码讲解在内存中创建一个Excel文件:XSSFWorkbook excel=new XSSFWorkbook();在Excel文件中创建一个Sheet页:XSSFSheet sheet=excel.createSheet("info");在Sheet中创建行对象,rownum编号从0开始:XSSFRow row=sheet.createRow(1);创建单元格并且写入文件内容:row.createCell(1).setCellValue("姓名"); row.createCell(2).setCellValue("城市");//创建一个新行: row=sheet.createRow(2); row.createCell(1).setCellValue("张三"); row.createCell(2).setCellValue("北京");通过输出流将内存中的Excel文件写入到磁盘:FileOutputStream out=new FileOutputStream(new File("D:\\info.xlsx")); excel.write(out);关闭资源:out.close(); excel.close();全部代码如下:package com.sky.test; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.File; import java.io.FileOutputStream; public class POITest { /** * 通过POI创建Excel文件并且写入文件内容 */ public static void write() throws Exception{ //在内存中创建一个Excel文件 XSSFWorkbook excel=new XSSFWorkbook(); //在Excel文件中创建一个Sheet页 XSSFSheet sheet=excel.createSheet("info"); //在Sheet中创建行对象,rownum编号从0开始 XSSFRow row=sheet.createRow(1); //创建单元格并且写入文件内容 row.createCell(1).setCellValue("姓名"); row.createCell(2).setCellValue("城市"); //创建一个新行 row=sheet.createRow(2); row.createCell(1).setCellValue("张三"); row.createCell(2).setCellValue("北京"); //创建一个新行 row=sheet.createRow(3); row.createCell(1).setCellValue("李四"); row.createCell(2).setCellValue("南京"); //通过输出流将内存中的Excel文件写入到磁盘 FileOutputStream out=new FileOutputStream(new File("D:\\info.xlsx")); excel.write(out); //关闭资源 out.close(); excel.close(); } public static void main(String[] args) throws Exception{ write(); } }效果如下:3.读取代码讲解创建文件读取流: InputStream in =new FileInputStream(("D:\\info.xlsx"));读取磁盘上已经存在的Excel文件:XSSFWorkbook excel=new XSSFWorkbook(in);读取Excel文件中的第一个Sheet页:XSSFSheet sheet=excel.getSheetAt(0);获取Sheet中最后一行的行号:int lastRowNum = sheet.getLastRowNum();输出:for(int i = 1; i <= lastRowNum ; i++){ //获得某一行 XSSFRow row = sheet.getRow(i); //获得单元格对象 String cellValue1 = row.getCell(1).getStringCellValue(); String cellValue2 = row.getCell(2).getStringCellValue(); System.out.println(cellValue1+" "+cellValue2); }关闭资源:in.close(); excel.close();完整代码如下:package com.sky.test; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; public class POITest { /** * 通过POI创建Excel文件并且写入文件内容 */ public static void write() throws Exception{ //在内存中创建一个Excel文件 XSSFWorkbook excel=new XSSFWorkbook(); //在Excel文件中创建一个Sheet页 XSSFSheet sheet=excel.createSheet("info"); //在Sheet中创建行对象,rownum编号从0开始 XSSFRow row=sheet.createRow(1); //创建单元格并且写入文件内容 row.createCell(1).setCellValue("姓名"); row.createCell(2).setCellValue("城市"); //创建一个新行 row=sheet.createRow(2); row.createCell(1).setCellValue("张三"); row.createCell(2).setCellValue("北京"); //创建一个新行 row=sheet.createRow(3); row.createCell(1).setCellValue("李四"); row.createCell(2).setCellValue("南京"); //通过输出流将内存中的Excel文件写入到磁盘 FileOutputStream out=new FileOutputStream(new File("D:\\info.xlsx")); excel.write(out); //关闭资源 out.close(); excel.close(); } /** * 通过POI读取Excel文件中的内容 * @throws Exception */ public static void read() throws Exception{ //创建文件读取流 InputStream in =new FileInputStream(("D:\\info.xlsx")); //读取磁盘上已经存在的Excel文件 XSSFWorkbook excel=new XSSFWorkbook(in); //读取Excel文件中的第一个Sheet页 XSSFSheet sheet=excel.getSheetAt(0); //获取Sheet中最后一行的行号 int lastRowNum = sheet.getLastRowNum(); for(int i = 1; i <= lastRowNum ; i++){ //获得某一行 XSSFRow row = sheet.getRow(i); //获得单元格对象 String cellValue1 = row.getCell(1).getStringCellValue(); String cellValue2 = row.getCell(2).getStringCellValue(); System.out.println(cellValue1+" "+cellValue2); } //关闭资源 in.close(); excel.close(); } public static void main(String[] args) throws Exception{ //write(); read(); } }总结以上就是Apache POI(处理Miscrosoft Office各种文件格式)的相关知识点,希望对你有所帮助。 积跬步以至千里,积怠惰以至深渊。时代在这跟着你一起努力哦!
  • [技术干货] WebSocket协议在java中的使用
    学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需写作干货注入能量… 热爱写作,愿意让自己成为更好的人…一、WebSocket介绍WebSocket 是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。1.Http和WebSocket比较:2.应用场景视频弹窗网页聊天体育实况更新股票基金报价实时更新二、WebSocket使用步骤1.客户端搭建博主这里使用案例的一个websocket.html页面作为WebSocket客户端,能够迅速的让我们了解通过WebSocket客户端与服务端之间的联系。 websocket.html页面效果如下:网页代码如下:<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>WebSocket Demo</title> </head> <body> <input id="text" type="text" /> <button onclick="send()">发送消息</button> <button onclick="closeWebSocket()">关闭连接</button> <div id="message"> </div> </body> <script type="text/javascript"> var websocket = null; var clientId = Math.random().toString(36).substr(2); //判断当前浏览器是否支持WebSocket if('WebSocket' in window){ //连接WebSocket节点 websocket = new WebSocket("ws://localhost:8080/ws/"+clientId); } else{ alert('Not support websocket') } //连接发生错误的回调方法 websocket.onerror = function(){ setMessageInnerHTML("error"); }; //连接成功建立的回调方法 websocket.onopen = function(){ setMessageInnerHTML("连接成功"); } //接收到消息的回调方法 websocket.onmessage = function(event){ setMessageInnerHTML(event.data); } //连接关闭的回调方法 websocket.onclose = function(){ setMessageInnerHTML("close"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function(){ websocket.close(); } //将消息显示在网页上 function setMessageInnerHTML(innerHTML){ document.getElementById('message').innerHTML += innerHTML + '<br/>'; } //发送消息 function send(){ var message = document.getElementById('text').value; websocket.send(message); } //关闭连接 function closeWebSocket() { websocket.close(); } </script> </html>2.导入maven坐标代码如下(示例):<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>3.导入WebSocket服务端组件WebSocketServer,用于和客户端通信WebSocketServer.java代码如下(示例):package com.sky.websocket; import org.springframework.stereotype.Component; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.Collection; import java.util.HashMap; import java.util.Map; /** * WebSocket服务 */ @Component @ServerEndpoint("/ws/{sid}") public class WebSocketServer { //存放会话对象 private static Map<String, Session> sessionMap = new HashMap(); /** * 连接建立成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam("sid") String sid) { System.out.println("客户端:" + sid + "建立连接"); sessionMap.put(sid, session); } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息 */ @OnMessage public void onMessage(String message, @PathParam("sid") String sid) { System.out.println("收到来自客户端:" + sid + "的信息:" + message); } /** * 连接关闭调用的方法 * * @param sid */ @OnClose public void onClose(@PathParam("sid") String sid) { System.out.println("连接断开:" + sid); sessionMap.remove(sid); } /** * 群发 * * @param message */ public void sendToAllClient(String message) { Collection<Session> sessions = sessionMap.values(); for (Session session : sessions) { try { //服务器向客户端发送消息 session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } }1.@ServerEndpoint主要是将目前的类定义成一个websocket服务器端, 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端 @ServerEndpoint("/ws/{sid}")注解是跟客户端中的连接WebSocket节点中的代码对应: 其中的Session是指当前服务端与客户端之间的会话2.@OnOpen@OnOpen注解表示当客户端连接上服务端时触发,加上@OnOpen后的方法就变成了回调方法。(建立连接的时候会调用)3.@OnMessage@OnMessage注解表示收到客户端发来的消息时触发。4.@OnClose@OnClose注解表示当连接关闭时触发。4.导入配置类WebSocketConfiguration,注册WebSocket的服务端组件WebSocketConfiguration.java代码如下(示例)package com.sky.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * WebSocket配置类,用于注册WebSocket的Bean */ @Configuration public class WebSocketConfiguration { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }5.导入定时任务类WebSocketTask,定时向客户端推送数据WebSocketTask.java代码如下(示例)package com.sky.task; import com.sky.websocket.WebSocketServer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Component public class WebSocketTask { @Autowired private WebSocketServer webSocketServer; /** * 通过WebSocket每隔5秒向客户端发送消息 */ @Scheduled(cron = "0/5 * * * * ?") public void sendMessageToClient() { webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now())); } }三、演示结果当我们运行项目后,点击WebSocket.html,在服务端的控制台会出现连接成功字样,此时调用的是OnOpen回方法:客户端每隔五秒收到来自服务端的消息:客户端也能向服务端进行通信:当我们点击关闭连接的时候也会在服务端的控制台输出:刷新页面也会建立新的连接:总结以上就是WebSocket协议在java中的应用的相关知识点,希望对你有所帮助。 积跬步以至千里,积怠惰以至深渊。时代在这跟着你一起努力哦!
  • [技术干货] Node.js 未来会在前端领域一家独大吗?
    Node.js 团队近期新发布20.6.0版本,在今年4月的版本上增强了安全性和API引入,同时也增加对新操作系统的支持以及对 TypeScript 兼容性的优化,虽然现在该版本处于测试阶段,你觉得Node.js在未来会呈现怎样的发展态势呢?Node.js新版本发布,你觉得哪一性能提升最实用?你觉得Node.js与JAVA相比,其优势在哪里?未来会超越JAVA吗?
  • [技术干货] 你觉得 JAVA 中最晦涩的知识点是什么?
    有人说“并发”是java语言中最晦涩难学的知识点,因为它涉及操作系统、内存、CPU、编程语言等多方面的基础知识,很考验程序员的内功。那么开发者们,你觉得java中最难学的知识点是什么?你为什么入坑 JAVA?
  • [其他] CollectionUtils.isEmpty和MapUtils.isEmpty、ArrayUtils.isEmpty的区别
     `CollectionUtils.isEmpty()`、`MapUtils.isEmpty()` 和 `ArrayUtils.isEmpty()` 都是 Apache Commons Collections 库中的工具类方法,用于判断集合、映射或数组是否为空。  - `CollectionUtils.isEmpty(collection)`:用于判断一个集合(如 List、Set)是否为空。如果集合为 null 或者集合中没有任何元素,则返回 true;否则返回 false。 - `MapUtils.isEmpty(map)`:用于判断一个映射(如 Map)是否为空。如果映射为 null 或者映射中没有任何键值对,则返回 true;否则返回 false。 - `ArrayUtils.isEmpty(array)`:用于判断一个数组是否为空。如果数组为 null 或者数组长度为 0,则返回 true;否则返回 false。  这三个方法的区别在于它们分别针对不同类型的数据结构进行判空操作。你可以根据需要选择适合的方法来判断相应的数据结构是否为空。 
  • [其他] java常用的判空函数
    Java常用的判空函数有以下几种:使用==判断对象是否为null:if (object == null) { // do something }使用equals()方法判断字符串是否为null或空字符串:if (string == null || string.equals("")) { // do something }使用Objects.isNull()方法判断对象是否为null: ```java import java.util.Objects;if (Objects.isNull(object)) { // do something }4. 使用`StringUtils.isEmpty()`方法判断字符串是否为null或空字符串(需要引入Apache Commons Lang库): ```java import org.apache.commons.lang3.StringUtils; if (StringUtils.isEmpty(string)) { // do something }
总条数:739 到第
上滑加载中