javaee之spring2

news2024/11/19 5:31:28

基于注解的IOC配置

一、先来说一下放在对象上面的注解

 Component:
 *          作用:用于把当前类对象存入spring容器中
 *          属性:
 *              value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
 *      Controller:一般用在表现层
 *      Service:一般用在业务层
 *      Repository:一般用在持久层
 *      以上三个注解他们的作用和属性与Component是一模一样。
 *      他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰

也就是说指定了此注解,就会自动给我们创建一个对象

二、再来说一下用于注入数据的

Autowired 

 Qualifier

 Resource

Value

 

 

下面做了两个持久层  

 在service层里面

 然后在客户端里面

 

 在整体使用注解的时候

 运行结果:

 

 

 上面解释出一个,如果单独用一个@AutoWired的时候,就是根据变量名称来找对象的

但是我们也可以指定我们需要需要用到的类名

 

 但是有一个注解可以单独用,就是Resource

 

下面来说一下基于XML的IOC的案例

 一、配置相关的依赖jar包并搭建数据库环境

        先把pom.xml给拿过来

        

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.pxx</groupId>
    <artifactId>spring1_copy_normal</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--apache提供的一个JDBC工具类库
        是对jdbc的一个简单封装
        -->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.4</version>
        </dependency>
        <!--
        MySQL数据库连接jar包
        -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>

        <!--
        c3p0的数据库连接池
        -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

        <!--
        junit单元测试jar包
        -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>



</project>

创建数据库

sql代码直接贴过来

create table account(
	id int primary key auto_increment,
	name varchar(40),
	money float
)character set utf8 collate utf8_general_ci;

insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);

我这个sql是放到D盘下面的,那么就是直接执行sql

 

 二、创建好每一个类

先创建一个关于表的实体类

Account.java

package com.pxx.domain;

import java.io.Serializable;

public class Account implements Serializable {
    private Integer id;
    private String name;
    private Float money;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Float getMoney() {
        return money;
    }

    public void setMoney(Float money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

再来创建IAccountDao.java

package com.pxx.dao;

import com.pxx.domain.Account;

import java.util.List;

/**
 * 账户持久层接口
 */
public interface IAccountDao {
    /**
     * 查询所有
     * @return
     */
    List<Account> findAllAccount();

    /**
     * 查询一个
     * @return
     */
    Account findAccountById(Integer accountId);

    /**
     * 保存
     * @param account
     */
    void saveAccount(Account account);

    /**
     * 更新
     * @param account
     */
    void updateAccount(Account account);

    /**
     * 删除
     * @param acccountId
     */
    void deleteAccount(Integer acccountId);
}

然后完成AccountDaoImpl.java

package com.pxx.dao.impl;

import com.pxx.dao.IAccountDao;
import com.pxx.domain.Account;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;

@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {

    //需要引入一个在commons.dbutils中的工具类,来操作数据库
    //这个工具类的名字就是QueryRunner
    private QueryRunner runner;

    //然后我们要用set注入对象
    //那么我们就需要一个set方法
    public void setRunnner(QueryRunner runner) {
        this.runner = runner;
    }

    @Override
    public List<Account> findAllAccount() {
        try{
            return runner.query("select * from account",new BeanListHandler<Account>(Account.class));
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Account findAccountById(Integer accountId) {
        try{
            return runner.query("select * from account where id = ? ",new BeanHandler<Account>(Account.class),accountId);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void saveAccount(Account account) {
        try{
            runner.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney());
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void updateAccount(Account account) {
        try{
            runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteAccount(Integer accountId) {
        try{
            runner.update("delete from account where id=?",accountId);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

现在去做业务层的service

IAccountService.java

package com.pxx.service;

import com.pxx.domain.Account;

import java.util.List;

public interface IAccountService {
    /**
     * 查询所有
     * @return
     */
    List<Account> findAllAccount();

    /**
     * 查询一个
     * @return
     */
    Account findAccountById(Integer accountId);

    /**
     * 保存
     * @param account
     */
    void saveAccount(Account account);

    /**
     * 更新
     * @param account
     */
    void updateAccount(Account account);

    /**
     * 删除
     * @param acccountId
     */
    void deleteAccount(Integer acccountId);
}

AccountServiceImpl.java

package com.pxx.service.impl;

import com.pxx.dao.IAccountDao;
import com.pxx.dao.impl.AccountDaoImpl;
import com.pxx.domain.Account;
import com.pxx.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service("accountService")
public class AccountServiceImpl implements IAccountService {

    //内部还是依赖了一个dao层的对象
    private IAccountDao accountDao;

    public void setAccountDao(IAccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public List<Account> findAllAccount() {
        return accountDao.findAllAccount();
    }

    @Override
    public Account findAccountById(Integer accountId) {
        return accountDao.findAccountById(accountId);
    }

    @Override
    public void saveAccount(Account account) {
        accountDao.saveAccount(account);
    }

    @Override
    public void updateAccount(Account account) {
        accountDao.updateAccount(account);
    }

    @Override
    public void deleteAccount(Integer acccountId) {
        accountDao.deleteAccount(acccountId);
    }
}

三、配置bean.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.pxx"></context:component-scan>

   <!--配置service-->
    <bean id="accountService" class="com.pxx.service.impl.AccountServiceImpl">
        <!--内部有一个dao层的实现对象,我们set注解-->
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!--
    现在就开配这个dao对象
    -->
    <bean id="accountDao" class="com.pxx.dao.impl.AccountDaoImpl">
        <!--
        它内部又有一个依赖,就是QueryRunner类
        -->
        <property name="runner" ref="runner"></property>
    </bean>

    <!--
        开始配置QueryRunner对象
        这个在commons.dbutil包里面
        它是封装了数据库操作的
    -->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <!--
        注入数据源
        -->
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>

    <!--
        配置数据源
    -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--
            数据库连接信息
        -->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="5201314"></property>
    </bean>
</beans>

现在写一个测试类,测试一下

在pom.xml上面添加上spring的测试依赖包

 添加上测试需要的注解信息

整个代码文件AccountServiceTest

 

package com.pxx;

import com.pxx.domain.Account;
import com.pxx.service.IAccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:bean.xml")
public class AccountServiceTest {

    //需要引入一个service
    @Autowired
    private IAccountService as;

    @Test
    public void testFindAll() {
        //3.执行方法
        List<Account> accounts = as.findAllAccount();
        for(Account account : accounts){
            System.out.println(account);
        }
    }

    @Test
    public void testFindOne() {
        //3.执行方法
        Account account = as.findAccountById(1);
        System.out.println(account);
    }

    @Test
    public void testSave() {
        Account account = new Account();
        account.setName("test");
        account.setMoney(12345f);
        //3.执行方法
        as.saveAccount(account);

    }

    @Test
    public void testUpdate() {
        //3.执行方法
        Account account = as.findAccountById(4);
        account.setMoney(23456f);
        as.updateAccount(account);
    }

    @Test
    public void testDelete() {
        //3.执行方法
        as.deleteAccount(4);
    }
}

下面把这个项目改成基于注解的配置

首先我们先去修改bean.xml文件

其实采用注解的方式我们就是需要把注入的对象或者注入数据类型全部删除。首先看一下上面这个容器是我们即使采用注解也需要引入的 ,他告诉我们要解析哪一个包下面的类。如果有些类不在这个包下面,我们是不可以采用注解的比如QueryRunner对象和它内部的一个连接池对象

所以这个bean.xml文档就变成了如下

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.pxx"></context:component-scan>

   
    <!--
        开始配置QueryRunner对象
        这个在commons.dbutil包里面
        它是封装了数据库操作的
    -->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <!--
        注入数据源
        -->
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>

    <!--
        配置数据源
    -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--
            数据库连接信息
        -->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="5201314"></property>
    </bean>
</beans>

项目改成基于注解配置的思路

1.首先在bean.xml里面配置需要在spring容器中存在的对象

2.配置每一个类的注解以及内部对象数据注解

关于Service的注解 

关于Dao的注解

  

运行结果
 

Spring的新注解 

现在我们面临一个问题,就算是我们写了注解但是还是脱离不了bean.xml文件

 那我们就把Spring的这个配置文件做成一个类来使用SpringConfiguration.java

先来看两个注解

 

 

 

 然后在bean.xml中就可以删除context配置

 

 下面又诞生一个问题,就是如下这些数据又该怎么配置

 先来说一个注解

 先来分析一下配置文件

 上面有Bean了还有类的方法抽取,接下来写代码

 那么现在就要把DataSource这部分给补全

那么这个时候就可以删掉配置文件了

 下面来说一下AnnotationConfigApplicationContext的使用

 这个就是引入了配置文件

下面我们去修改一下AccountServcieTest里面的代码,看看能不能用

之前的业务代码是这样的啊,全部引入的是xml文件

 现在我们要去得到配置文件,也就是class文件,就需要用到

AnnotationConfigApplicationContext

 测试一把:

 下面来说一下SpringConfiguration中的细节

 下面在来说一个注解@Import注解

细节1:配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。

 但是这句话也不绝对。

假如我们重新在写一个JdbcConfig.java的配置文件

这个是JdbcConfig.java

 把SpringConfiguration的东西给切掉

上面没有显示声明JdbcConfig,测试代码肯定会报错,如果你想不报错,就把这个配置文件放到这里面去

 运行结果:

 现在有一个问题就是,我们不想再SpringConfiguration上面写@Configuration,也不想在JdbcConfig上面写注解类,而且我们不想像下面一样导入两个配置文件

 它的作用是导入其他配置类,参数是传入其他配置类的字节码对象

 运行结果:

 再来说一个注解

先来定义一个配置文件放到resources目录下面,因为这个注解主要是读取配置文件的数据嘛

 运行结果:

 下面多说一句Qualifier注解的另外一种用法

 Spring整合junit问题分析

下面来分析一下AccountServiceTest.java中的代码

 于是,我们想了一个办法直接通过注解方式获取一个IAccountService对象然后去调用里面dao层的方法,但是

那么下面我们就来分析一下

 

 下面我们把Spring与junit进行整合一下

使用Junit单元测试:测试我们的配置
 Spring整合junit的配置
       1、导入spring整合junit的jar(坐标)


       2、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
              @Runwith
       3、告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置
           @ContextConfiguration
                   locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
                   classes:指定注解类所在地位置
 
    当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上

 整体业务代码:spring1_copy_normal

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ 第一天 基础 5 Spring 整合RabbitMQ 5.2 Spring 整合 RabbitMQ【消费者】 5.3 小结

RabbitMQ 【黑马程序员RabbitMQ全套教程&#xff0c;rabbitmq消息中间件到实战】 文章目录RabbitMQ第一天 基础5 Spring 整合RabbitMQ5.2 Spring 整合 RabbitMQ【消费者】5.2.1 消费者5.3 小结第一天 基础 5 Spring 整合RabbitMQ 5.2 Spring 整合 RabbitMQ【消费者】 5.2.1…

白话说Java虚拟机原理系列【第五章】:内存结构之堆详解

文章目录堆(Heap)对象在堆中的存储结构垃圾收集器详解对象存活判断算法引用的种类对象最终判定死亡之两次标记规则方法区的垃圾回收原则垃圾收集算法分代收集模型垃圾收集器对象分配原则垃圾收集触发方式垃圾收集器的参数异常前导说明&#xff1a; 本文基于《深入理解Java虚拟机…

大数据分析案例-基于逻辑回归算法构建垃圾邮件分类器模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【Django】第二课 基于Django超市订单管理系统开发

概念 本文在上一文之上&#xff0c;针对管理员&#xff0c;经理&#xff0c;普通员工身份的用户操作用户管理模块功能。 功能实现 1.普通员工登录系统后&#xff0c;对于用户管理模块不具备操作其他用户信息的权限。因此当普通员工登录后&#xff0c;弹出对话框提示用户。 2…

【Linux】Linux编辑器---vim的使用

等老了就养只柴犬&#xff0c;相依为命。 文章目录一、命令模式1.光标定位操作2.文本复制、粘贴、剪切、撤销3.文本编辑二、插入模式三、底行模式四、vim配置原理五、解决普通用户无法使用sudo提权一、命令模式 刚打开vim时&#xff0c;默认就是命令模式&#xff0c;命令模式的…

C++STL之string的使用

对于C语言中的字符串&#xff0c;我们只能使用char类型数组保存&#xff0c;并且是以\0结尾的. 操作起来非常不方便而且底层空间需要用户自己访问&#xff0c;非常造成容易越界访问. 这个时候&#xff0c;C的STL中的string类就很好解决了这些. 目录 string的使用 1.string…

mqtt的使用与二次封装

前提&#xff1a;先安装Mosquitto并启动服务&#xff0c;可使用mqttx进行接收发送的测试。 Mosquitto以配置启动命令 mosquitto -c mosquitto.conf -v原文链接&#xff1a;mqtt的使用 本文为测试使用固无账号密码&#xff0c;可在原文查看 封装后实现效果&#xff0c;加入一个…

LeetCode题解 16(15,22) 三数之和,括号生成

文章目录三数之和(15)代码解答:括号生成(22)代码解答:三数之和(15) 该题是让从1个数组中找到和为0的不重复的三个数,这次我们使用排序和指针的方法来解决 先将该数组从小到大进行排序 Arrays.sort(nums);我们需要遍历一遍该数组,同时我们还要去重的操作(例如[-1,-1,-1,2],这里面…

helm本地debug template渲染小记

前提条件 1&#xff0c; 安装helm 2&#xff0c;要能连接的k8s 3&#xff0c;本地有完成charts文件目录 具体步骤 本文因为是在项目流程中helm渲染出的deployment语法报错或者最终生成的不符合预期&#xff0c;因此本地使用helm命令进行debug验证测试。 我们先看一下基本的c…

怎么把word里面的彩色图转化为灰度图,直接在word里面操作,无需转其他软件,超简单!(位图和矢量图都可以)

怎么把word里面的彩色图转化为灰度图&#xff0c;直接在word里面操作&#xff0c;无需转其他软件&#xff0c;超简单&#xff01;&#xff08;位图和矢量图都可以&#xff09; Microsoft Office Word是微软公司的一个文字处理器应用程序。它最初是由Richard Brodie为了运行DOS…

深入理解自编码器(用变分自编码器生成图像)

文章目录自编码器欠完备自编码器正则自编码器稀疏自编码器去噪自编码器收缩自编码器变分自编码器References内容总结自花书《Deep Learning》以及《Python 深度学习》。 自编码器 自编码器&#xff08;autoencoder&#xff09;是神经网络的一种&#xff0c;经过训练后能尝试将…

机器学习经典算法:决策树(2)

1. 概述 决策树&#xff08;Decision Tree&#xff09;是有监督学习中的一种算法&#xff0c;并且是一种基本的分类与回归的方法。决策树有两种&#xff1a;分类树和回归树。 决策树是用于分类和回归的工具&#xff0c;它将数据特征值拆分为决策节点处的分支&#xff08;例如&a…

六、Kubernetes核心技术Pod详解、实例

1、概述 Pod 是 k8s 系统中可以创建和管理的最小单元&#xff0c;是资源对象模型中由用户创建或部署的最 小资源对象模型&#xff0c;也是在 k8s 上运行容器化应用的资源对象&#xff0c;其他的资源对象都是用来支 撑或者扩展 Pod 对象功能的&#xff0c;比如控制器对象是用来管…

某大型政务网站的优化咨询案例(视频点播VOD+GZIP压缩+静态文件CDN+Redis缓存+全文索引)

2022年圣诞节到来啦&#xff0c;很高兴这次我们又能一起度过~ 这次分享关于一个对某大型政务网站的优化咨询的案例&#xff0c;发生在今年的下半年&#xff0c;已过去一段时间&#xff0c;并取得了良好的成果&#xff01;* 项目背景 某大型政务网站准备上线&#xff0c;需要…

08-Golang中的运算符

[TOC](Golang中的运算符运算符介绍算数运算符基本介绍细节说明关系运算符(比较运算符&#xff09;基本介绍细节说明逻辑运算符基本介绍细节说明赋值运算符基本介绍细节说明运算符优先级运算符介绍 运算符是一种特殊的符号&#xff0c;用来表示数据的运算、赋值和比较 1.算数运…

Vue事件处理的基本使用

前言 事件处理在vue中也是非常重要的一项技术&#xff0c;它类似于js的事件处理&#xff0c;但是也有不同&#xff0c;下面就简单介绍一下在vue中如何进行事件使用以及一些要点 1 事件基本使用 在这里我们使用单击事件为例&#xff0c;简单讲讲在vue中单击事件的编写以及细节…

最近面试遇到一个算法题,简单写一点。

第⼀题&#xff08;必答&#xff09; 请针对有重复数字的数组设计⼀个快排算法&#xff0c;⽐如&#xff1a;[34, 34, 89, 1, 1, 20, 12]&#xff0c;排序后结果为 [89,34,34,20,12,1,1] 第⼆题&#xff08;必答&#xff09; 请利⽤Redis 实现⼀个通⽤分布式锁&#xff0c;并…

技术进步、研发计划启动及政策支持 共促我国合成生物学市场容量加速扩张

合成生物学是对生物体进行有目标的设计、改造乃至重新合成&#xff0c;这一名词最早出现于DNA重组技术发展的上世纪70年代。合成生物学汇聚并融合了生命科学、工程学和信息科学等诸多学科&#xff0c;在天然产物合成、化学工业、生物能源、生物医药等诸多领域有广泛的应用前景。…

【Animejs】——Anime.js照片墙案例实现

目录 一、实现的效果&#xff1a; 二、实现js的具体步骤 1、需要实现的逻辑梳理 2、切换风格的逻辑 三、完整代码&#xff1a; 用js编写使用animejs实现图片复杂的切换效果 一、实现的效果&#xff1a; 点击——> <——箭头&#xff0c;实现不同动画效果的炫酷切换 …

【小5聊】C++ 输入矩阵数字,然后回环方式输出

C 输入矩阵数字&#xff0c;然后回环方式输出 1、题目内容 输入 第一行是两个m和n&#xff0c;分别代表矩阵的行数和列数。 第二行开始输入对应矩阵 输出 第二行回转输出。 相邻的两个整数之间用一个空格分开&#xff0c;行尾无空格 样例输入 5 6 4 8 9 4 5 6 1 2 5 6…