搜索词>>foreach 耗时0.0520
  • jquery中的foreach数据的遍历

    jquery中的foreach(即each)数据的遍历或者处理HTML页面元素的遍历使用方法讲解jquery中的foreach(即each)数据的遍历或者处理HTML页面元素的遍历使用方法讲解 <pre> <code class="language-html"><!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jquery each</title> </head> <body> <div id="testDiv"> <ul> <li data-id="1">1F</li> <li data-id="2">2F</li> <li data-id="3">3F</li> <li data-id="4">4F</li> <li data-id="5">5F</li> </ul> </div> <!-- 引入jquery --> <script src="/resources/framework/jquery/jquery-1.12.4.min.js"></script> <script type="text/javascript"> $(function(){ //1.$(selector).each(function(index){}); //$(selector).each();适合场景,对HTML页面的DOM元素进行操作 //例如下面将进行ul的li遍历取出所有data-id的值 var tmpStr1=''; $('#testDiv ul li').each(function(index){//index参数,索引 tmpStr1+=$(this).attr("data-id");//获取li中的data-id属性的值 tmpStr1+=',';//豆号分开,方便查看 }); alert("tmpStr1->:"+tmpStr1); //2.$.each(arr,function(index,item){}) //$.each();适合对已知的元素数组进行遍历; //适合场景ajax调用后台返回数据遍历值,或者已知数组,例如: var arr=[1,2,3,9]; var tmpStr2=''; $.each(arr,function(index,item){//index,索引位置,item取出来的数组值 tmpStr2+=item; tmpStr2+=','; }); alert("tmpStr2->:"+tmpStr2); //也可以先获取HTML页面的dom对象数组,然后遍历 var tmpStr3=''; var arrli=$('#testDiv ul li'); $.each(arrli,function(index,item){ tmpStr3+=$(item).attr("data-id");//获取li中的data-id属性的值 tmpStr3+=',';//豆号分开,方便查看 }); alert("tmpStr3->:"+tmpStr3); //明显的$(selector).each()遍历HTML页面元素会写更少的代码 }) </script> </body> </html></code></pre> 运行HTML代码显示<br /> <img alt="jquery中的foreach(即each)数据的遍历或者处理HTML页面元素的遍历使用方法讲解" class="img-thumbnail" src="/assist/images/blog/71512dc5-e8e2-41b6-9786-d6b90c9af9bb.png" style="height:212px; width:577px" title="jquery中的foreach(即each)数据的遍历或者处理HTML页面元素的遍历使用方法讲解" /><br /> <img alt="jquery中的foreach(即each)数据的遍历或者处理HTML页面元素的遍历使用方法讲解" class="img-thumbnail" src="/assist/images/blog/6a1dc224-399a-45af-93f4-b58b872356c3.png" style="height:228px; width:558px" title="jquery中的foreach(即each)数据的遍历或者处理HTML页面元素的遍历使用方法讲解" /><br /> <img alt="jquery中的foreach(即each)数据的遍历或者处理HTML页面元素的遍历使用方法讲解" class="img-thumbnail" src="/assist/images/blog/8a0bddb4-4409-4cd3-96ea-225acb8805a5.png" style="height:223px; width:631px" /><br />  
  • jsp利用el表达式切割字符串

    1.引入相关el表达式标签库 <pre> <code class="language-html"><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %></code></pre> 2.使用方法 <pre> <code class="language-html"><c:if test="${!empty obj.tags }"> <c:set value="${ fn:split(obj.tags, ',')}" var="tags" /> <c:forEach items="${tags}" var="tag"> <span>${tag}</span> </c:forEach> </c:if></code></pre> <br /> 说明:<br /> ${obj.tags} tags是obj对象的一个属性,以逗号分隔<br />  
  • @Select注解中动态sql处理mybaties

    在Java编程中,ORM框架mybaties处理@Select注解中的动态sql处理方法在Java编程中,ORM框架mybaties处理@Select注解中的动态sql处理方法<br /> <br /> 代码如下 <pre> <code class="language-java">public interface UserMapper { @Select("<script>select * from user u where u.id in <foreach collection=\"ids\" item=\"item\" index=\"index\" open=\"(\" close=\")\" separator=\",\"> #{item}</foreach> </script>") @Results(value = { @Result(property = "userSex", column = "user_sex", javaType = String.class), @Result(property = "userName", column = "user_name"), @Result(property = "userAge", column = "user_age") }) List<User> list(@Param("ids")Long [] ids); }</code></pre> <br /> <strong>简单的说就是讲以前mapper.XML中的sql写法搬到Java代码中.用<SCRIPT></SCRIPT>包裹起来</strong>
  • mybaties 处理集合(List)参数_mybaties 处理 IN条件

    某些情况下,我们使用mybaties时需要使用IN(虽然IN数据多了效率不高,但是少量还是可以用得)条件查询,这时候我们就需要传递参数了,下面是mybaties处理IN条件得参数使用方法首先Mapper接口需要传递一个集合数据过来,集合数据某些情况下,我们使用mybaties时需要使用IN(虽然IN数据多了效率不高,但是少量还是可以用得)条件查询,这时候我们就需要传递参数了,下面是mybaties处理IN条件得参数使用方法首先Mapper接口需要传递一个集合数据过来,集合数据可以是对象也可以是简单类型,下面以简单类型为例:$title(TestMapper.java) List<User> getListIdIn(@Param("ids")List<String> ids);接下来是mapper xml文件$title(TestMapper.xml) ...省略其他代码.... <if test="ids!=null and ids.size()>0"> and id in <foreach collection="ids" item="id" index="index" open="(" close=")" separator=","> #{id} </foreach> </if> ...省略其他代码...
  • Spring 5 WebClient和WebTestClient使用教程

    1.引言Spring开发人员,您是否曾经觉得需要一个易于使用且高效的流畅功能样式 API 的异步/非阻塞 HTTP客户端?如果是,那么我欢迎您阅读关于WebClient的文章,WebClient是Spring 5中引入的新的被动HTTP客户1.引言Spring开发人员,您是否曾经觉得需要一个易于使用且高效的流畅功能样式 API 的异步/非阻塞 HTTP客户端?如果是,那么我欢迎您阅读关于WebClient的文章,WebClient是Spring 5中引入的新的被动HTTP客户端。2.如何使用WebClientWebClient是Spring 5的反应性Web框架Spring WebFlux的一部分。要使用WebClient,您需要将spring-webflux模块包含在您的项目中。在现有的Spring Boot项目中添加依赖项如果您有一个现有的Spring Boot项目,则可以spring-webflux通过在该pom.xml文件中添加以下依赖项来添加该模块-<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>请注意,您需要Spring Boot 2.xx版本才能使用Spring WebFlux模块。从Scratch创建一个新项目如果您从头开始创建项目,那么您可以使用Spring Initializr网站的spring-webflux模块生成初始项目-转到http://start.spring.io。选择弹簧引导版本2.xx的。在依赖项部分添加反应性Web依赖项。如果需要,请更改组和工件的详细信息,然后单击生成工程下载项目。3.使用WebClient消费远程API让我们做一些有趣的事情,并使用WebClient来使用Real World API。在本文中,我们将使用WebClient来使用Github的API。我们将使用WebClient在用户的Github存储库上执行CRUD操作。创建WebClient的一个实例1.使用该create()方法创建WebClient您可以使用create()工厂方法创建WebClient的实例-WebClient webClient = WebClient.create();如果您只使用特定服务的API,那么您可以使用该服务的baseUrl来初始化WebClientWebClient webClient = WebClient.create("https://api.github.com");2.使用WebClient构建器创建WebClientWebClient还附带了一个构建器,它为您提供了一些自定义选项,包括过滤器,默认标题,cookie,客户端连接器等 -WebClient webClient = WebClient.builder() .baseUrl("https://api.github.com") .defaultHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.github.v3+json") .defaultHeader(HttpHeaders.USER_AGENT, "Spring 5 WebClient") .build();使用WebClient发出请求并检索响应以下是如何使用WebClient GET向Github的List Repositories API发出请求-public Flux<GithubRepo> listGithubRepositories(String username, String token) { return webClient.get() .uri("/user/repos") .header("Authorization", "Basic " + Base64Utils .encodeToString((username + ":" + token).getBytes(UTF_8))) .retrieve() .bodyToFlux(GithubRepo.class); }了解API调用的简单性和简洁性!假设我们有一个名为类GithubRepo,确认到GitHub的API响应,上面的函数会返回一个Flux的GithubRepo对象。请注意,我使用Github的基本认证机制来调用API。它需要您的github用户名和个人访问令牌,您可以从https://github.com/settings/tokens中生成该令牌。使用exchange()方法来检索响应该retrieve()方法是获取响应主体的最简单方法。但是,如果您希望对响应拥有更多的控制权,那么您可以使用可exchange()访问整个ClientResponse标题和正文的方法 -public Flux<GithubRepo> listGithubRepositories(String username, String token) { return webClient.get() .uri("/user/repos") .header("Authorization", "Basic " + Base64Utils .encodeToString((username + ":" + token).getBytes(UTF_8))) .exchange() .flatMapMany(clientResponse -> clientResponse.bodyToFlux(GithubRepo.class)); }在请求URI中使用参数您可以在请求URI中使用参数,并在uri()函数中分别传递它们的值。所有参数都被花括号包围。在提出请求之前,这些参数将被WebClient自动替换 -public Flux<GithubRepo> listGithubRepositories(String username, String token) { return webClient.get() .uri("/user/repos?sort={sortField}&direction={sortDirection}", "updated", "desc") .header("Authorization", "Basic " + Base64Utils .encodeToString((username + ":" + token).getBytes(UTF_8))) .retrieve() .bodyToFlux(GithubRepo.class); }使用URIBuilder构造请求URI您也可以使用UriBuilder类似的方法获取对请求URI的完全程序控制,public Flux<GithubRepo> listGithubRepositories(String username, String token) { return webClient.get() .uri(uriBuilder -> uriBuilder.path("/user/repos") .queryParam("sort", "updated") .queryParam("direction", "desc") .build()) .header("Authorization", "Basic " + Base64Utils .encodeToString((username + ":" + token).getBytes(UTF_8))) .retrieve() .bodyToFlux(GithubRepo.class); }在WebClient请求中传递Request Body如果你有一个Mono或一个形式的请求体Flux,那么你可以直接将它传递给body()WebClient中的方法,否则你可以从一个对象中创建一个单声道/通量并像这样传递 -public Mono<GithubRepo> createGithubRepository(String username, String token, RepoRequest createRepoRequest) { return webClient.post() .uri("/user/repos") .body(Mono.just(createRepoRequest), RepoRequest.class) .header("Authorization", "Basic " + Base64Utils .encodeToString((username + ":" + token).getBytes(UTF_8))) .retrieve() .bodyToMono(GithubRepo.class); }如果您具有实际值而不是Publisher(Flux/ Mono),则可以使用syncBody()快捷方式传递请求正文 -public Mono<GithubRepo> createGithubRepository(String username, String token, RepoRequest createRepoRequest) { return webClient.post() .uri("/user/repos") .syncBody(createRepoRequest) .header("Authorization", "Basic " + Base64Utils .encodeToString((username + ":" + token).getBytes(UTF_8))) .retrieve() .bodyToMono(GithubRepo.class); } 最后,你可以使用BodyInserters类提供的各种工厂方法来构造一个BodyInserter对象并将其传递给该body()方法。本BodyInserters类包含的方法来创建一个BodyInserter从Object,Publisher,Resource,FormData,MultipartData等-public Mono<GithubRepo> createGithubRepository(String username, String token, RepoRequest createRepoRequest) { return webClient.post() .uri("/user/repos") .body(BodyInserters.fromObject(createRepoRequest)) .header("Authorization", "Basic " + Base64Utils .encodeToString((username + ":" + token).getBytes(UTF_8))) .retrieve() .bodyToMono(GithubRepo.class); }添加过滤器功能WebClient支持使用ExchangeFilterFunction。您可以使用过滤器函数以任何方式拦截和修改请求。例如,您可以使用过滤器函数为Authorization每个请求添加一个标头,或记录每个请求的详细信息。这ExchangeFilterFunction需要两个参数 -在ClientRequest与ExchangeFilterFunction过滤器链中的下一个。它可以修改ClientRequest并调用ExchangeFilterFucntion过滤器链中的下一个来继续下一个过滤器或ClientRequest直接返回修改以阻止过滤器链。1.使用过滤器功能添加基本认证在上面的所有示例中,我们都包含一个Authorization用于使用Github API进行基本身份验证的标头。由于这是所有请求共有的内容,因此您可以在创建过滤器函数时将此逻辑添加到过滤器函数中WebClient。该ExchaneFilterFunctionsAPI已经为基本认证提供了一个过滤器。你可以像这样使用它 -WebClient webClient = WebClient.builder() .baseUrl(GITHUB_API_BASE_URL) .defaultHeader(HttpHeaders.CONTENT_TYPE, GITHUB_V3_MIME_TYPE) .filter(ExchangeFilterFunctions .basicAuthentication(username, token)) .build();现在,您不需要Authorization在每个请求中添加标题。过滤器函数将拦截每个WebClient请求添加此标头。2.使用过滤器功能记录所有请求我们来看一个习惯的例子ExchangeFilterFunction。我们将编写一个过滤器函数来拦截并记录每个请求 -WebClient webClient = WebClient.builder() .baseUrl(GITHUB_API_BASE_URL) .defaultHeader(HttpHeaders.CONTENT_TYPE, GITHUB_V3_MIME_TYPE) .filter(ExchangeFilterFunctions .basicAuthentication(username, token)) .filter(logRequest()) .build(); 这里是logRequest()过滤器功能的实现-private ExchangeFilterFunction logRequest() { return (clientRequest, next) -> { logger.info("Request: {} {}", clientRequest.method(), clientRequest.url()); clientRequest.headers() .forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); return next.exchange(clientRequest); }; }3.使用ofRequestProcessor()和ofResponseProcessor()工厂方法来创建过滤器ExchangeFilterFunction API提供两个名为工厂方法ofRequestProcessor()和ofResponseProcessor()用于创建分别截获该请求和响应滤波器的功能。logRequest()我们在前一节中创建的过滤器函数可以使用ofRequestProcessor()这种工厂方法创建-private ExchangeFilterFunction logRequest() { ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { logger.info("Request: {} {}", clientRequest.method(), clientRequest.url()); clientRequest.headers() .forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); return Mono.just(clientRequest); }); } 如果您想拦截WebClient响应,则可以使用该ofResponseProcessor()方法创建像这样的过滤器功能 -private ExchangeFilterFunction logResposneStatus() { return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { logger.info("Response Status {}", clientResponse.statusCode()); return Mono.just(clientResponse); }); }处理WebClient错误只要接收到状态码为4xx或5xx的响应retrieve(),WebClient中的方法WebClientResponseException就会抛出一个。您可以使用onStatus()像这样的方法来自定义,public Flux<GithubRepo> listGithubRepositories() { return webClient.get() .uri("/user/repos?sort={sortField}&direction={sortDirection}", "updated", "desc") .retrieve() .onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.error(new MyCustomClientException()) ) .onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.error(new MyCustomServerException()) ) .bodyToFlux(GithubRepo.class); }请注意,与retrieve()方法不同,该exchange()方法在4xx或5xx响应的情况下不会引发异常。您需要自己检查状态代码,并以您想要的方式处理它们。使用@ExceptionHandler控制器内部的WebClientResponseExceptions处理您可以@ExceptionHandler在控制器内部使用这种方式来处理WebClientResponseException并返回适当的响应给客户端 -@ExceptionHandler(WebClientResponseException.class) public ResponseEntity<String> handleWebClientResponseException(WebClientResponseException ex) { logger.error("Error from WebClient - Status {}, Body {}", ex.getRawStatusCode(), ex.getResponseBodyAsString(), ex); return ResponseEntity.status(ex.getRawStatusCode()).body(ex.getResponseBodyAsString()); }使用Spring 5 WebTestClient测试Rest APIWebTestClient包含类似于WebClient的请求方法。另外,它还包含检查响应状态,标题和正文的方法。您也可以像AssertJ使用WebTestClient 一样使用断言库。查看以下示例以了解如何使用WebTestClient执行其他API测试 -提示:项目源码下载spring-webclient-webtestclient-demo-master.zip
  • Java8中的流Stream

    jdk8新特性流的使用<h2><strong>java 8中的流(Stream)</strong></h2> 之前因为工作原因经常需要对查询的数据库的数据集合进行筛选或者排序之类的操作,今天看了下jdk8特性,根据stream可以自动满足这些操作。 <p>流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)</p> <p>Java 8中的Stream API可以让你写出这样的代码:</p> <p> 声明性——更简洁,更易读</p> <p> 可复合——更灵活</p> <p> 可并行——性能更好<br /> <br /> 首先看一下使用流和不使用流的区别,需求: 把集合中年龄小于等于20的人的名字取出来并排序<br /> 不使用流:</p> <pre> <code class="language-java">//传统JDK排序抽取数据 // 把集合中年龄小于等于20的人的名字取出来并排序 // 第一步:取年龄 <= 20的用户 List<User> tmpList = new ArrayList<>(); for (User u : list) { if (u.getAge() <= 20){ tmpList.add(u); } } // 第二步:排序 Collections.sort(tmpList, new Comparator<User>() { public int compare(User u1, User u2) { return u1.getName().compareTo(u2.getName()); } }); // 第三步 List<String> userNames = new ArrayList<>(); for(User u : tmpList){ userNames.add(u.getName()); }</code></pre> <p>jdk8流新特性<br />  </p> <pre> <code class="language-java">//JDK流新特性 //为了利用多核架构并行执行这段代码,只需要把stream()换成parallelStream(): List<String> userNames = list.stream() .filter(userJdk8 -> userJdk8.getAge() <= 20) .sorted(Comparator.comparing(User::getName)) .map(User::getName) .collect(Collectors.toList()); System.out.println(userNames.toString());</code></pre> <p> </p> <h2><strong>流与集合的区别:</strong></h2> <p>集合与流之间的差异就在于什么时候进行计算。集合是一个内存中的数据结构,它包含数据结构中目前所有的值——集合中的每个元素都得先算出来才能添加到集合中。(你可以往集合里加东西或者删东西,但是不管什么时候,集合中的每个元素都是放在内存里的,元素都得先算出来才能成为集合的一部分。)相比之下,流则是在概念上固定的数据结构(你不能添加或删除元素),其元素则是按需计算的。 从另一个角度来说,流就像是一个延迟创建的集合:只有在消费者要求的时候才会计算值。以质数为例,要是想创建一个包含所有质数的集合,那这个程序算起来就没完没了了,因为总有新的质数要算,然后把它加到集合里面。而流的话,仅仅从流中提取需要的值,而这些值——在用户看不见的地方,只会按需生成。<br /> 流只能被消费一次,如果被消费多次,则会抛出异常:</p> <pre> <code>java.lang.IllegalStateException: stream has already been operated upon or closed</code></pre> <p>如下代码所示: 这段代码的意思是遍历 lists 集合</p> <pre> <code class="language-java">List<String> lists = Arrays.asList("java8","lambda","stream"); Stream<String> stringStream = lists.stream(); Consumer<String> consumer = (x) -> System.out.println(x); stringStream.forEach(consumer); //stream has already been operated upon or closed stringStream.forEach(consumer);</code></pre> <p>之前测试类完整代码,更多stream参考<a rel="external nofollow" target="_blank" href="https://docs.oracle.com/javase/8/docs/api/">jdk8API在线文档</a>:<br />  </p> <pre> <code class="language-java">package com.yeyue; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; /** * @ClassName: JDK8Test * @Description: jdk8流的作用 此例是把集合中年龄小于等于20的人的名字取出来并排序 * @author: xiaoboLi * @date: 2017/11/22 14:32 * @Copyright: 2017 All rights reserved. */ public class JDK8Test { public static void main(String[] args) { List<User> list = new ArrayList<>(); User user = new User(11, "zhangsan", 1); list.add(user); user = new User(19, "lisi", 1); list.add(user); user = new User(10, "wanger", 0); list.add(user); user = new User(7, "wangmazi", 0); list.add(user); user = new User(25, "hanmeimei", 0); list.add(user); user = new User(30, "lilei", 0); list.add(user); //传统JDK排序抽取数据 // 把集合中年龄小于等于20的人的名字取出来并排序 // 第一步:取年龄 <= 20的用户 List<User> tmpList = new ArrayList<>(); for (User u : list) { if (u.getAge() <= 20){ tmpList.add(u); } } // 第二步:排序 Collections.sort(tmpList, new Comparator<User>() { public int compare(User u1, User u2) { return u1.getName().compareTo(u2.getName()); } }); // 第三步 List<String> userNames = new ArrayList<>(); for(User u : tmpList){ userNames.add(u.getName()); } System.out.println(userNames.toString()); //JDK流新特性 //为了利用多核架构并行执行这段代码,只需要把stream()换成parallelStream(): userNames = list.stream() .filter(userJdk8 -> userJdk8.getAge() <= 20) .sorted(Comparator.comparing(User::getName)) .map(User::getName) .collect(Collectors.toList()); System.out.println(userNames.toString()); //取小于20岁的人员信息并且根据年龄升序排序 List<User> aList = list.stream() .filter(userJdk8 -> userJdk8.getAge() <= 20) .sorted(Comparator.comparing(User::getAge)) .collect(Collectors.toList()); for (User u : aList) { System.out.println(u.getName()); } } } class User { private int age; private String name; private int sex; public User(int age, String name, int sex) { this.age = age; this.name = name; this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } }</code></pre>
  • spring boot elasticsearch 5.x/6.x版本整合详解

    前言    本教程主要讲解spring boot如何整合 spring data elasticsearch 实现elasticsearch检索引擎的整合使用前言    本教程主要讲解spring boot如何整合 spring data elasticsearch 实现elasticsearch检索引擎的整合使用。需要注意的是spring boot 1.x就算当前最新的1.5.11支持的elasticsearch版本仅为2.x。如果需要spring boot支持5.x版本的elasticsearch或者6.x版本的elasticsearch则需要将spring boot版本升级到最新的2.0.1即可。本教程所使用的elasticsearch版本为6.2。所以使用的spring boot版本将会是2.0.1spring boot elasticsearch整合项目结构图 ​Spring Boot elasticsearch整合项目文件详解1.pom.xml文件 由于本项目使用的maven管理。所以这里就只能看到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> <artifactId>demo-springboot-springdata-elasticsearch</artifactId> <packaging>jar</packaging> <url>https://www.leftso.com</url> <version>1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--HTTP方式接入--> <!-- <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> </dependency>--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <!-- Package as an executable jar/war --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 核心依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> Book.java 这个类主要用于创建检索的对象实体。package com.leftso.project.demo.book.model; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; @Document(indexName = "lee", type = "books") public class Book { @Id private String id; private String title; private String author; private String releaseDate; public Book() { } public Book(String id, String title, String author, String releaseDate) { this.id = id; this.title = title; this.author = author; this.releaseDate = releaseDate; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getReleaseDate() { return releaseDate; } public void setReleaseDate(String releaseDate) { this.releaseDate = releaseDate; } @Override public String toString() { return "Book{" + "id='" + id + '\'' + ", title='" + title + '\'' + ", author='" + author + '\'' + ", releaseDate='" + releaseDate + '\'' + '}'; } } BookRepository.java 该接口主要继承了spring data的接口。实现了语义即可实现功能。spring data的强大大家都懂。package com.leftso.project.demo.book.repository; import com.leftso.project.demo.book.model.Book; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; public interface BookRepository extends ElasticsearchRepository<Book, String> { Page<Book> findByAuthor(String author, Pageable pageable); Page<Book> findByTitle(String title, Pageable pageable); }BookService.java 该接口主要是写了几个测试的方法。package com.leftso.project.demo.book.service; import com.leftso.project.demo.book.model.Book; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; public interface BookService { Book save(Book book); void delete(Book book); Book findOne(String id); Iterable<Book> findAll(); Page<Book> findByAuthor(String author, PageRequest pageRequest); Page<Book> findByTitle(String title, PageRequest pageRequest); }spring boot 启动类Application.javapackage com.leftso.project.demo; import com.leftso.project.demo.book.model.Book; import com.leftso.project.demo.book.service.BookService; import org.elasticsearch.client.Client; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import java.util.Map; @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private ElasticsearchOperations es; @Autowired private BookService bookService; public static void main(String args[]) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { printElasticSearchInfo(); Book b1=bookService.save(new Book("1001", "这是一个Spring Boot1.0的书籍", "Rambabu Posa", "23-FEB-2017")); Book b2=bookService.save(new Book("1002", "Apache的一本书籍", "Rambabu Posa", "13-MAR-2017")); bookService.save(new Book("1003", "Solr是一个搜索引擎", "Rambabu Posa", "21-MAR-2017")); //fuzzey search // Page<Book> books = bookService.findByAuthor("Rambabu", new PageRequest(0, 10)); Page<Book> books = bookService.findByTitle("书", new PageRequest(0, 10)); books.forEach(x -> System.out.println(x)); } //useful for debug private void printElasticSearchInfo() { System.out.println("--ElasticSearch-->"); Client client = es.getClient(); Map<String, String> asMap = client.settings().getAsMap(); asMap.forEach((k, v) -> { System.out.println(k + " = " + v); }); System.out.println("<--ElasticSearch--"); } } 启动类实现了一个CommandLineRunner接口。该接口主要有个run方法。启动spring boot的时候会执行run方法的内容。就当测试啦。spring boot elasticsearch整合测试 鼠标右键启动application.java即可:​查看下方的执行情况:​从上图可以看到已经连接到elasticsearch 192.168.0.225:3000服务那边去了​从上图可以看到我们已经存入elasticsearch 并且通过spring data elasticsearch 的查询接口查询出了Book title字段中包含“书”的所有结果。提示:项目源码下载 demo-springboot-springdata-elasticsearch.zip
  • Cassandra数据库使用Datastax详解

    今天我又回到了更多的Cassandra和Java集成中,重点关注使用Datastax Java驱动程序,而不是我已经写了很多的Spring Data Cassandra今天我又回到了更多的Cassandra和Java集成中,重点关注使用Datastax Java驱动程序,而不是我已经写了很多的Spring Data Cassandra。Spring Data实际上使用了Datastax驱动程序来与Cassandra进行交互,但是它还带有一些额外的好东西。但我们今天不想要这些!我们将直接使用Datastax驱动程序,并且在看到如何使用Datastax驱动程序后,我们会将其与Spring Data进行比较。这篇文章假设你已经熟悉Cassandra和Spring Data Cassandra。由于我已经写了很多关于这个主题的文章,所以我仅仅关心Cassandra如何在需要上下文的情况下工作。如果您没有这个背景信息,我建议您阅读Spring Data Cassandra入门,我明显谈到了使用Spring Data Cassandra,但也对Cassandra的工作方式做了比本文更加全面的解释。还有Datastax Academy提供了一些非常有用的资源来学习如何使用Cassandra。首先,依赖关系。<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-core</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-mapping</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency> </dependencies>和往常一样,我使用的是Spring Boot,只是因为我们剥夺了Spring的数据并不意味着我们需要从所有Spring库中完全变冷的火鸡。Datastax相关的依赖关系是cassandra-driver-core和cassandra-driver-mapping。cassandra-driver-core,顾名思义就是提供了与Cassandra交互的核心功能,例如设置会话和编写查询。cassandra-driver-mapping不需要查询Cassandra,但提供了一些对象映射,与核心驱动程序一起使用,它现在将作为ORM使用,而不仅仅是允许我们执行CQL语句。我们现在已经对我们的依赖关系进行了排序,下一步是连接到Cassandra,以便我们可以真正开始查询它。@Configuration public class CassandraConfig { @Bean public Cluster cluster( @Value("${cassandra.host:127.0.0.1}") String host, @Value("${cassandra.cluster.name:cluster}") String clusterName, @Value("${cassandra.port:9042}") int port) { return Cluster.builder() .addContactPoint(host) .withPort(port) .withClusterName(clusterName) .build(); } @Bean public Session session(Cluster cluster, @Value("${cassandra.keyspace}") String keyspace) throws IOException { final Session session = cluster.connect(); setupKeyspace(session, keyspace); return session; } private void setupKeyspace(Session session, String keyspace) throws IOException { final Map<String, Object> replication = new HashMap<>(); replication.put("class", "SimpleStrategy"); replication.put("replication_factor", 1); session.execute(createKeyspace(keyspace).ifNotExists().with().replication(replication)); session.execute("USE " + keyspace); // String[] statements = split(IOUtils.toString(getClass().getResourceAsStream("/cql/setup.cql")), ";"); // Arrays.stream(statements).map(statement -> normalizeSpace(statement) + ";").forEach(session::execute); } @Bean public MappingManager mappingManager(Session session) { final PropertyMapper propertyMapper = new DefaultPropertyMapper() .setNamingStrategy(new DefaultNamingStrategy(LOWER_CAMEL_CASE, LOWER_SNAKE_CASE)); final MappingConfiguration configuration = MappingConfiguration.builder().withPropertyMapper(propertyMapper).build(); return new MappingManager(session, configuration); } }与使用Spring Data的类似设置相比,这里有更多的核心(与Spring Boot的自动配置结合使用时,甚至不需要这个类),但类本身非常简单。这里显示的Cluster和Sessionbean 的基本设置是应用程序工作所需的最低限度的最低限度,并且对于您编写的任何应用程序而言可能保持不变。提供了更多方法,以便您可以添加任何其他配置以使其适合您的使用情况。通过使用来自application.properties我们的值来设置主机地址,集群名称和端口Cluster。在Cluster随后被用来创建一个Session。这样做有两种选择,可以设置默认的键盘空间。如果你想设置默认密钥空间,那么你所需要做的就是使用下面的代码。@Bean public Session session(Cluster cluster, @Value("${cassandra.keyspace}") String keyspace) throws IOException { final Session session = cluster.connect(keyspace); // any other setup return session; }密钥空间被传递给connect将创建一个Session然后执行的方法,USE <keyspace>从而设置默认密钥空间。这依赖于在创建会话之前存在的密钥空间,如果它不会在执行USE语句时失败。如果您不知道启动时是否存在密钥空间,或者您知道您肯定希望根据属性文件中的密钥空间值动态创建密钥空间,那么您将需要调用connect而不指定密钥空间。然后你需要自己创建它,所以你实际上有东西可以使用。要做到这一点使用由createKeyspace提供的方法SchemaBuilder。以下是创建密钥空间的CQL语句。CREATE KEYSPACE IF NOT EXISTS <keyspace> WITH REPLICATION = { 'class':'SimpleStrategy', 'replication_factor':1 };我还在下面添加了密码空间代码,因为它现在有点远了。private void setupKeyspace(Session session, String keyspace) throws IOException { final Map<String, Object> replication = new HashMap<>(); replication.put("class", "SimpleStrategy"); replication.put("replication_factor", 1); session.execute(createKeyspace(keyspace).ifNotExists().with().replication(replication)); session.execute("USE " + keyspace); }这SchemaBuilder是很好,易于使用,看起来非常类似于你通过它的CQL。我们增加一个ifNotExists条款,先调用设定的复制因子with,然后传递Map<String, Object>到replicationMethod。此映射需要包含类和复制因子,基本上使用这里显示的键,但将映射的值更改为您需要的值。不要忘记execute语句,然后告诉会话使用刚刚创建的密钥空间。不幸的是,没有更好的方法来手动设置默认密钥空间,并且执行USE语句是唯一的选择。继以前两个有关设置默认密钥空间的选项之后。如果我们选择不设置默认密钥空间,那么我们需要在每个我们创建的表上以及每个执行的查询上加上一个密钥空间。Datastax提供了将密钥空间名称添加到查询以及映射到实体的方法,这并不难。我不会再深入研究这个主题,但要知道,如果您已经正确设置了其他所有内容,则不设置密钥空间不会阻止您的应用程序工作。一旦设置了密钥空间,我们就可以开始创建表格。有两种可能的方法来做到这一点。一,执行一些CQL语句,无论它们是Java代码中的字符串,还是从外部CQL脚本中读取。二,使用SchemaBuilder来创建它们。让我们先看看执行CQL语句,还是更准确地从CQL文件执行它们。您可能已经注意到,在原始示例中留下了一些注释掉的代码,但未注释代码将找到名为的文件setup.cql,读出单个CQL语句,执行它,然后移至下一个语句。这里又是。String[] statements = split(IOUtils.toString(getClass().getResourceAsStream("/cql/setup.cql")), ";"); Arrays.stream(statements).map(statement -> normalizeSpace(statement) + ";").forEach(session::execute); 下面是创建Cassandra表的文件中包含的CQL。REATE TABLE IF NOT EXISTS people_by_country( country TEXT, first_name TEXT, last_name TEXT, id UUID, age INT, profession TEXT, salary INT, PRIMARY KEY((country), first_name, last_name, id) );的主键由的country,first_name,last_name和id字段。分区键仅由country字段组成,而集群列是键中的其余键,id仅用于唯一性,因为您显然可以使用具有相同名称的人。在我的早期文章Spring Data Cassandra入门中,我深入探讨了主键的主题。此代码使用commons-io和commons-lang3依赖关系。如果我们不以这种方式执行CQL,那么可以删除这些依赖关系(在这篇文章的上下文中)。怎么样使用SchemaBuilder?我没有包含任何代码来创建原始代码片段中的表格,因为我正在玩耍并试图找出最好的地方放置它,现在我已将其卡在存储库中,但我仍然不相信那是它是完美的地方。无论如何,我会在这里粘贴代码,以便我们现在可以查看它,然后当它重新出现时我们可以跳过它。private void createTable(Session session) { session.execute( SchemaBuilder.createTable(TABLE) .ifNotExists() .addPartitionKey("country", text()) .addClusteringColumn("first_name", text()) .addClusteringColumn("last_name", text()) .addClusteringColumn("id", uuid()) .addColumn("age", cint()) .addColumn("profession", text()) .addColumn("salary", cint())); }这与上面显示的CQL很好地匹配。我们能够使用addPartitionKey和定义不同的列类型addClusteringColumn来创建我们的主键和addColumn标准字段。还有很多其他的方法,比如addStaticColumn和withOptions允许你再调用clusteringOrder来定义集群列的排序方向。您调用这些方法的顺序非常重要,因为分区键和聚簇列将按其各自方法的调用顺序创建。Datastax还提供了DataType该类来更容易地定义列类型,例如text匹配TEXT和cint匹配INT。和上次一样SchemaBuilder,一旦我们对桌子设计感到满意,我们就需要execute 它。在MappingManager下面,创建bean的代码片段如下。@Bean public MappingManager mappingManager(Session session) { final PropertyMapper propertyMapper = new DefaultPropertyMapper() .setNamingStrategy(new DefaultNamingStrategy(LOWER_CAMEL_CASE, LOWER_SNAKE_CASE)); final MappingConfiguration configuration = MappingConfiguration.builder().withPropertyMapper(propertyMapper).build(); return new MappingManager(session, configuration); }该MappingManagerbean来自于cassandra-driver-mapping依赖关系,并将映射ResultSet到一个实体(我们稍后会看到)。现在我们只需要创建bean。如果我们对在Cassandra中将Java驼峰案例转换为全部小写字母并且没有分隔符的默认命名策略不满意,我们需要设置自己的。要做到这一点,我们可以传入一个DefaultNamingStrategy来定义我们在Java类中使用的情况以及我们在Cassandra中使用的情况。由于在Java中,我们通常使用骆驼案例LOWER_CAMEL_CASE,因为我喜欢在Cassandra中使用蛇案例,所以我们可以使用它们LOWER_SNAKE_CASE(这些都在NamingConventions课堂中找到)。对lower的引用指定了字符串中第一个字符的大小写,LOWER_CAMEL_CASE表示firstName和UPPER_CAMEL_CASE表示FirstName。DefaultPropertyMapper为更具体的配置提供额外的方法,但MappingConfiguration只有一个工作PropertyMapper需要传递给a MappingManager。接下来我们应该看到的是将会持续到Cassandra并从Cassandra中检索的实体,这为我们节省了手动设置插入值和转换读取结果的工作量。Datastax驱动程序为我们提供了一种相对简单的方法,通过使用注释来标记属性,例如它所映射到的表的名称,哪个字段与Cassandra列以及主键所组成的字段相匹配。@Table(name = "people_by_country") public class Person { @PartitionKey private String country; @ClusteringColumn private String firstName; @ClusteringColumn(1) private String lastName; @ClusteringColumn(2) private UUID id; private int age; private String profession; private int salary; private Person() { } public Person(String country, String firstName, String lastName, UUID id, int age, String profession, int salary) { this.country = country; this.firstName = firstName; this.lastName = lastName; this.id = id; this.age = age; this.profession = profession; this.salary = salary; } // getters and setters for each property // equals, hashCode, toString } 这个实体表示如people_by_country表所示的表@Table。我再次将下表中的CQL作为参考。CREATE TABLE IF NOT EXISTS people_by_country( country TEXT, first_name TEXT, last_name TEXT, id UUID, age INT, profession TEXT, salary INT, PRIMARY KEY((country), first_name, last_name, id) );该@Table注释必须指定实体代表表的名称,还配备了根据您的要求,如各种其他的选择keyspace,如果你不想使用密钥空间的默认Sessionbean被配置为使用,caseSensitiveTable这是自我解释。主键是什么?如上所述,主键由分区键组成,分区键本身包含一个或多个列和/或集群列。为了匹配上面定义的Cassandra表,我们在必填字段中添加了注释@PartitionKey和@ClusteringColumn注释。这两个注释都有一个属性,value它指定列在主键中的显示顺序。默认值是0这是为什么一些注释不包含值的原因。获得这个实体的最后一个要求是getter,setter和一个默认的构造函数,这样mapper就可以做到这一点。如果你不想让任何人访问它,默认的构造函数可以是私有的,因为映射器使用反射来检索它。你可能不希望在你的实体上放置setter,因为你希望这个对象是不可变的,不幸的是,对于这件事你没有什么可以做的,你只能承认这个争斗。虽然我个人认为这很好,因为你可以(也许应该)将实体转换为另一个可以在应用程序中传递的对象,而不需要任何实体注释,因此不需要知道数据库本身。然后,实体可以保持可变状态,并且您传递的其他对象可以按照您的意愿完全工作。在我们继续之前,我想提到的最后一件事。还记得DefaultNamingConvention我们之前定义的吗?这意味着我们的字段正在匹配正确的列,而无需在实体中做任何额外的工作。如果您没有这样做或想要为列名提供不同的字段名称,那么您可以使用@Column注释并在那里指定它。我们几乎拥有构建示例应用程序所需的所有组件。倒数第二个组件正在创建一个存储库,该存储库将包含用于持续读取和从Cassandra读取数据的所有逻辑。我们将利用MappingManager我们之前创建的bean和我们放到实体上的注释将a ResultSet转换为实体,而不需要我们自己做任何事情。@Repository public class PersonRepository { private Mapper<Person> mapper; private Session session; private static final String TABLE = "people_by_country"; public PersonRepository(MappingManager mappingManager) { createTable(mappingManager.getSession()); this.mapper = mappingManager.mapper(Person.class); this.session = mappingManager.getSession(); } private void createTable(Session session) { // use SchemaBuilder to create table } public Person find(String country, String firstName, String secondName, UUID id) { return mapper.get(country, firstName, secondName, id); } public List<Person> findAll() { final ResultSet result = session.execute(select().all().from(TABLE)); return mapper.map(result).all(); } public List<Person> findAllByCountry(String country) { final ResultSet result = session.execute(select().all().from(TABLE).where(eq("country", country))); return mapper.map(result).all(); } public void delete(String country, String firstName, String secondName, UUID id) { mapper.delete(country, firstName, secondName, id); } public Person save(Person person) { mapper.save(person); return person; } }通过MappingManager构造函数注入in并调用该类的mapper方法Person,我们将返回一个Mapper<Person>将亲自处理我们所有映射需求的函数。我们还需要检索Session能够执行很好包含在MappingManager我们注入的查询。对于三个查询,我们直接依靠映射器与Cassandra进行交互,但这只适用于单个记录。get,save并且delete每个工作都通过接受构成Person实体主键的值来工作,并且必须以正确的顺序输入,否则您将遇到意外的结果或异常将被抛出。其他情况需要执行查询才能调用映射器,将返回的数据ResultSet转换为实体或实体集合。我已经利用QueryBuilder写查询,我也选择了这个职位,不写预先准备的语句。尽管在大多数情况下,您应该使用准备好的陈述,我认为我将在未来的一篇文章中介绍这些陈述,虽然它们足够相似,QueryBuilder仍然可以使用,所以我相信如果需要,您可以自己弄清楚。QueryBuilder提供的静态方法来创建select,insert,update并且delete然后可以链接在一起,以语句(我知道这听起来很明显)构建查询。这里QueryBuilder使用的也是您可以在Spring Data Cassandra中使用的那个,当您需要手动创建自己的查询并且不依赖来自Cassandra存储库的推断查询时。创建这个小应用程序的最后一步是实际运行它。由于我们使用Spring Boot,我们只需添加标准@SpringBootApplication并运行该类。我已经完成了下面的工作,以及使用CommandLineRunner执行存储库中的方法,以便我们可以检查他们是否在做我们期望的。@SpringBootApplication public class Application implements CommandLineRunner { @Autowired private PersonRepository personRepository; public static void main(String args[]) { SpringApplication.run(Application.class); } @Override public void run(String... args) { final Person bob = new Person("UK", "Bob", "Bobbington", UUID.randomUUID(), 50, "Software Developer", 50000); final Person john = new Person("UK", "John", "Doe", UUID.randomUUID(), 30, "Doctor", 100000); personRepository.save(bob); personRepository.save(john); System.out.println("Find all"); personRepository.findAll().forEach(System.out::println); System.out.println("Find one record"); System.out.println(personRepository.find(john.getCountry(), john.getFirstName(), john.getLastName(), john.getId())); System.out.println("Find all by country"); personRepository.findAllByCountry("UK").forEach(System.out::println); john.setProfession("Unemployed"); john.setSalary(0); personRepository.save(john); System.out.println("Demonstrating updating a record"); System.out.println(personRepository.find(john.getCountry(), john.getFirstName(), john.getLastName(), john.getId())); personRepository.delete(john.getCountry(), john.getFirstName(), john.getLastName(), john.getId()); System.out.println("Demonstrating deleting a record"); System.out.println(personRepository.find(john.getCountry(), john.getFirstName(), john.getLastName(), john.getId())); } } 该run方法包含一些打印行,所以我们可以看到发生了什么,下面是他们输出的内容。Find all Person{country='US', firstName='Alice', lastName='Cooper', id=e113b6c2-5041-4575-9b0b-a0726710e82d, age=45, profession='Engineer', salary=1000000} Person{country='UK', firstName='Bob', lastName='Bobbington', id=d6af6b9a-341c-4023-acb5-8c22e0174da7, age=50, profession='Software Developer', salary=50000} Person{country='UK', firstName='John', lastName='Doe', id=f7015e45-34d7-4f25-ab25-ca3727df7759, age=30, profession='Doctor', salary=100000} Find one record Person{country='UK', firstName='John', lastName='Doe', id=f7015e45-34d7-4f25-ab25-ca3727df7759, age=30, profession='Doctor', salary=100000} Find all by country Person{country='UK', firstName='Bob', lastName='Bobbington', id=d6af6b9a-341c-4023-acb5-8c22e0174da7, age=50, profession='Software Developer', salary=50000} Person{country='UK', firstName='John', lastName='Doe', id=f7015e45-34d7-4f25-ab25-ca3727df7759, age=30, profession='Doctor', salary=100000} Demonstrating updating a record Person{country='UK', firstName='John', lastName='Doe', id=f7015e45-34d7-4f25-ab25-ca3727df7759, age=30, profession='Unemployed', salary=0} Demonstrating deleting a record null我们可以看到findAll已经返回了所有记录,find并且只检索到与输入主键值相匹配的记录。findAllByCountry已经排除了爱丽丝,并只发现了英国的记录。save再次调用现有记录将更新记录而不是插入。最后delete将从数据库中删除该人的数据(如删除Facebook?!?!)。这是一个包装。我将尝试在未来写一些后续文章,因为我们可以使用Datastax驱动程序进行一些更有趣的事情,这是我们在本文中未涉及到的。我们在这里涵盖的内容应该足以让您使用驱动程序的第一步,并从您的应用程序开始查询Cassandra。在我们走之前,我想对Datastax驱动程序和Spring Data Cassandra进行一些比较。与Spring Data Cassandra相比,Datastax驱动程序(在我看来)中缺少支持创建表格的支持。Spring Data能够根据您的实体创建您的表格这一事实可以消除所有这些额外的工作,以基本上重写您已经编写的内容。显然,如果您不想使用实体注释,则差异将消失,因为您需要在Datastax和Spring Data中手动创建表。实体设计的方式和使用的注释也很不相同。这一点与我之前提到的观点密切相关。由于Spring Data可以为您创建表格,因此更需要更精确的注释,以便您指定表格的设计,例如聚类列的排序顺序。这显然可以使课堂变得混乱,并且会带来一系列通常不被看好的注释。Spring Data还为标准查询提供了更好的支持,例如findAll插入一组实体。显然,这不是完全世界的尽头,实现这些将花费很少的努力,但这几乎总结了Datastax驱动程序和Spring Data Cassandra之间的主要区别。Spring Data更容易使用。关于这个问题我不认为还有什么可说的。由于Spring Data Cassandra是基于Datastax驱动程序构建的,因此显然它可以执行驱动程序的所有功能,如果缺少任何需要的内容,则可以直接访问Datastax类并执行所需的操作。但是Spring Data提供的便利不应该被查看,我认为我甚至没有涉及它提供的一些更有用的部分,因为这篇文章只是介绍基础知识。一旦您使用Spring Boot的自动配置和Cassandra存储库为您产生的推断查询,甚至不要让我开始了解它的容易程度。我应该停止......这正在变成一场咆哮。总之,使用Datastax驱动程序连接和查询Cassandra数据库是相当直接的。建立与Cassandra的连接,创建您需要的实体并编写使用前者的存储库,然后获得所需的一切。我们还将Datastax驱动程序与Spring Data Cassandra进行了比较,Datastax将尽其所能满足您的需求,但Spring Data使其更容易。项目源码下载:demo-datastax-java-driver-master.zip
  • java编程基础数组ArrayList使用详解

    java编程基础数组ArrayList使用详解<p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">Java编程基础中的ArrayList用于存储动态大小的元素集合。与大小固定的数组相反,ArrayList会在添加新元素时自动增大其大小。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">ArrayList是Java集合框架的一部分,它实现了Java的<code>List</code>接口。<img alt="list" class="img-thumbnail" src="/assist/images/blog/3a58de20c693483dba6ea4d6a42b7e2a.jpg" /></span></span></span><br /> <br />  </p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">以下几点需要注意Java中的ArrayList -</span></span></span></p> <ul style="margin-left:30px; margin-right:0px"> <li> <p style="margin-left:0px; margin-right:0px">ArrayList是一个可调整大小的数组,也称为动态数组。它的尺寸越来越大,以适应新的元素,并在元素被移除时缩小尺寸。</p> </li> <li> <p style="margin-left:0px; margin-right:0px">ArrayList内部使用数组来存储元素。就像数组一样,它允许您通过索引来检索元素。</p> </li> <li> <p style="margin-left:0px; margin-right:0px">Java ArrayList允许重复值和空值。</p> </li> <li> <p style="margin-left:0px; margin-right:0px">Java ArrayList是一个有序的集合。它维护元素的插入顺序。</p> </li> <li> <p style="margin-left:0px; margin-right:0px">您不能创建原始类型,如一个ArrayList <code>int</code>,<code>chat</code>等你需要用盒装的类型,如<code>Integer</code>,<code>Character</code>,<code>Boolean</code>等。</p> </li> <li> <p style="margin-left:0px; margin-right:0px">Java ArrayList不同步。如果多个线程同时尝试修改ArrayList,那么最终结果将是非确定性的。如果多个线程要修改它,你必须显式同步对ArrayList的访问。</p> </li> </ul> <h2 style="margin-left:0px; margin-right:0px; text-align:start">创建一个ArrayList并添加新的元素</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">这个例子显示:</span></span></span></p> <ul style="margin-left:30px; margin-right:0px"> <li>如何使用<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#ArrayList--" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>ArrayList()</code></a>构造函数创建ArrayList 。</li> <li>使用该<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#add-E-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>add()</code></a>方法向ArrayList添加新元素。</li> </ul> <pre> <code class="language-java">import java.util.ArrayList; import java.util.List; public class CreateArrayListExample { public static void main(String[] args) { // Creating an ArrayList of String List<String> animals = new ArrayList<>(); // Adding new elements to the ArrayList animals.add("Lion"); animals.add("Tiger"); animals.add("Cat"); animals.add("Dog"); System.out.println(animals); // Adding an element at a particular index in an ArrayList animals.add(2, "Elephant"); System.out.println(animals); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><br /> <span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出</span></span></span></p> <pre> <code class="language-html">[Lion, Tiger, Cat, Dog] [Lion, Tiger, Elephant, Cat, Dog]</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">从另一个集合创建一个ArrayList</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">这个例子显示:</span></span></span></p> <ul style="margin-left:30px; margin-right:0px"> <li> <p style="margin-left:0px; margin-right:0px">如何使用<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#ArrayList-java.util.Collection-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>ArrayList(Collection c)</code></a>构造函数从另一个ArrayList创建一个ArrayList 。</p> </li> <li> <p style="margin-left:0px; margin-right:0px">如何使用该<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#addAll-java.util.Collection-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>addAll()</code></a>方法将现有ArrayList中的所有元素添加到新的ArrayList中。</p> <pre> <code class="language-java">import java.util.ArrayList; import java.util.List; public class CreateArrayListFromCollectionExample { public static void main(String[] args) { List<Integer> firstFivePrimeNumbers = new ArrayList<>(); firstFivePrimeNumbers.add(2); firstFivePrimeNumbers.add(3); firstFivePrimeNumbers.add(5); firstFivePrimeNumbers.add(7); firstFivePrimeNumbers.add(11); // Creating an ArrayList from another collection List<Integer> firstTenPrimeNumbers = new ArrayList<>(firstFivePrimeNumbers); List<Integer> nextFivePrimeNumbers = new ArrayList<>(); nextFivePrimeNumbers.add(13); nextFivePrimeNumbers.add(17); nextFivePrimeNumbers.add(19); nextFivePrimeNumbers.add(23); nextFivePrimeNumbers.add(29); // Adding an entire collection to an ArrayList firstTenPrimeNumbers.addAll(nextFivePrimeNumbers); System.out.println(firstTenPrimeNumbers); } }</code></pre> </li> </ul> <p style="margin-left:0px; margin-right:0px; text-align:start"><br /> <span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">访问ArrayList中的元素</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">这个例子显示:</span></span></span></p> <ul style="margin-left:30px; margin-right:0px"> <li>如何使用该<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#isEmpty--" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>isEmpty()</code></a>方法检查ArrayList是否为空。</li> <li>如何使用该<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#size--" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>size()</code></a>方法找到ArrayList的大小。</li> <li>如何使用该<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#get-int-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>get()</code></a>方法访问ArrayList中特定索引处的元素。</li> <li>如何使用该<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#set-int-E-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>set()</code></a>方法修改ArrayList中特定索引处的元素。</li> </ul> <pre> <code class="language-java">import java.util.ArrayList; import java.util.List; public class AccessElementsFromArrayListExample { public static void main(String[] args) { List<String> topCompanies = new ArrayList<>(); // Check is an ArrayList is empty System.out.println("Is the topCompanies list empty? : " + topCompanies.isEmpty()); topCompanies.add("Google"); topCompanies.add("Apple"); topCompanies.add("Microsoft"); topCompanies.add("Amazon"); topCompanies.add("Facebook"); // Find the size of an ArrayList System.out.println("Here are the top " + topCompanies.size() + " companies in the world"); System.out.println(topCompanies); // Retrieve the element at a given index String bestCompany = topCompanies.get(0); String secondBestCompany = topCompanies.get(1); String lastCompany = topCompanies.get(topCompanies.size() - 1); System.out.println("Best Company: " + bestCompany); System.out.println("Second Best Company: " + secondBestCompany); System.out.println("Last Company in the list: " + lastCompany); // Modify the element at a given index topCompanies.set(4, "Walmart"); System.out.println("Modified top companies list: " + topCompanies); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">Is the topCompanies list empty? : true Here are the top 5 companies in the world [Google, Apple, Microsoft, Amazon, Facebook] Best Company: Google Second Best Company: Apple Last Company in the list: Facebook Modified top companies list: [Google, Apple, Microsoft, Amazon, Walmart]</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">从ArrayList中移除元素</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">这个例子显示:</span></span></span></p> <ol style="margin-left:30px; margin-right:0px"> <li> <p style="margin-left:0px; margin-right:0px">如何删除ArrayList |中给定索引处的元素 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#remove-java.lang.Object-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">delete</a><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#remove-int-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">(int索引)</a></p> </li> <li> <p style="margin-left:0px; margin-right:0px">如何从ArrayList |中删除元素 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#remove-java.lang.Object-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">delete(Object o)</a></p> </li> <li> <p style="margin-left:0px; margin-right:0px">如何从给定集合中存在的ArrayList中移除所有元素| <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#remove-java.lang.Object-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">delete</a>All<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#removeAll-java.util.Collection-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">()</a></p> </li> <li> <p style="margin-left:0px; margin-right:0px">如何删除所有匹配给定谓词|的元素 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#removeIf-java.util.function.Predicate-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">removeIf()</a></p> </li> <li> <p style="margin-left:0px; margin-right:0px">如何清除ArrayList | <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#clear--" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">clear()</a></p> </li> </ol> <pre> <code class="language-java">import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; public class RemoveElementsFromArrayListExample { public static void main(String[] args) { List<String> programmingLanguages = new ArrayList<>(); programmingLanguages.add("C"); programmingLanguages.add("C++"); programmingLanguages.add("Java"); programmingLanguages.add("Kotlin"); programmingLanguages.add("Python"); programmingLanguages.add("Perl"); programmingLanguages.add("Ruby"); System.out.println("Initial List: " + programmingLanguages); // Remove the element at index `5` programmingLanguages.remove(5); System.out.println("After remove(5): " + programmingLanguages); // Remove the element "Kotlin" (The remove() method returns false if the element does not exist in the ArrayList) boolean isRemoved = programmingLanguages.remove("Kotlin"); System.out.println("After remove(\"Kotlin\"): " + programmingLanguages); // Remove all the elements belonging to the collection scriptingLanguages List<String> scriptingLanguages = new ArrayList<>(); scriptingLanguages.add("Python"); scriptingLanguages.add("Ruby"); scriptingLanguages.add("Perl"); programmingLanguages.removeAll(scriptingLanguages); System.out.println("After removeAll(scriptingLanguages): " + programmingLanguages); // Remove all the elements that satisfy the given predicate programmingLanguages.removeIf(new Predicate<String>() { @Override public boolean test(String s) { return s.startsWith("C"); } }); /* The above removeIf() call can also be written using lambda expression like this - programmingLanguages.removeIf(s -> s.startsWith("C")) */ System.out.println("After Removing all elements that start with \"C\": " + programmingLanguages); // Remove all elements from the ArrayList programmingLanguages.clear(); System.out.println("After clear(): " + programmingLanguages); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">Initial List: [C, C++, Java, Kotlin, Python, Perl, Ruby] After remove(5): [C, C++, Java, Kotlin, Python, Ruby] After remove("Kotlin"): [C, C++, Java, Python, Ruby] After removeAll(scriptingLanguages): [C, C++, Java] After Removing all elements that start with "C": [Java] After clear(): []</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">迭代ArrayList</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">以下示例显示如何使用迭代遍历ArrayList</span></span></span></p> <ol style="margin-left:30px; margin-right:0px"> <li>Java 8 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#forEach-java.util.function.Consumer-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>forEach</code></a>循环。</li> <li><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#iterator--" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>iterator()</code></a>。</li> <li><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#iterator--" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>iterator()</code></a>和Java 8 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#forEachRemaining-java.util.function.Consumer-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">forEachRemaining()</a>方法。</li> <li><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#listIterator-int-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>listIterator()</code></a>。</li> <li>每个循环都很简单。</li> <li>用索引循环。</li> </ol> <pre> <code class="language-java">import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; public class IterateOverArrayListExample { public static void main(String[] args) { List<String> tvShows = new ArrayList<>(); tvShows.add("Breaking Bad"); tvShows.add("Game Of Thrones"); tvShows.add("Friends"); tvShows.add("Prison break"); System.out.println("=== Iterate using Java 8 forEach loop ==="); tvShows.forEach(tvShow -> { System.out.println(tvShow); }); System.out.println("\n=== Iterate using an iterator() ==="); Iterator<String> tvShowIterator = tvShows.iterator(); while (tvShowIterator.hasNext()) { String tvShow = tvShowIterator.next(); System.out.println(tvShow); } System.out.println("\n=== Iterate using an iterator() and Java 8 forEachRemaining() method ==="); tvShowIterator = tvShows.iterator(); tvShowIterator.forEachRemaining(tvShow -> { System.out.println(tvShow); }); System.out.println("\n=== Iterate using a listIterator() to traverse in both directions ==="); // Here, we start from the end of the list and traverse backwards. ListIterator<String> tvShowListIterator = tvShows.listIterator(tvShows.size()); while (tvShowListIterator.hasPrevious()) { String tvShow = tvShowListIterator.previous(); System.out.println(tvShow); } System.out.println("\n=== Iterate using simple for-each loop ==="); for(String tvShow: tvShows) { System.out.println(tvShow); } System.out.println("\n=== Iterate using for loop with index ==="); for(int i = 0; i < tvShows.size(); i++) { System.out.println(tvShows.get(i)); } } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">=== Iterate using Java 8 forEach loop === Breaking Bad Game Of Thrones Friends Prison break === Iterate using an iterator() === Breaking Bad Game Of Thrones Friends Prison break === Iterate using an iterator() and Java 8 forEachRemaining() method === Breaking Bad Game Of Thrones Friends Prison break === Iterate using a listIterator() to traverse in both directions === Prison break Friends Game Of Thrones Breaking Bad === Iterate using simple for-each loop === Breaking Bad Game Of Thrones Friends Prison break === Iterate using for loop with index === Breaking Bad Game Of Thrones Friends Prison break</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">在遍历期间需要修改ArrayList时,<code>iterator()</code>和<code>listIterator()</code>方法很有用。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">考虑下面的例子,在<code>iterator.remove()</code>遍历它的时候我们使用方法从ArrayList中移除元素-</span></span></span></p> <pre> <code class="language-java">import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ArrayListIteratorRemoveExample { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); numbers.add(13); numbers.add(18); numbers.add(25); numbers.add(40); Iterator<Integer> numbersIterator = numbers.iterator(); while (numbersIterator.hasNext()) { Integer num = numbersIterator.next(); if(num % 2 != 0) { numbersIterator.remove(); } } System.out.println(numbers); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">[18, 40]</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">在ArrayList中搜索元素</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">下面的例子显示了如何:</span></span></span></p> <ul style="margin-left:30px; margin-right:0px"> <li> <p style="margin-left:0px; margin-right:0px">检查ArrayList是否包含给定的元素|  <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#contains-java.lang.Object-" rel="external nofollow" target="_blank">contains</a><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#contains-java.lang.Object-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">()</a></p> </li> <li> <p style="margin-left:0px; margin-right:0px">查找ArrayList |中第一次出现元素的索引 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#indexOf-java.lang.Object-" rel="external nofollow" target="_blank">indexOf</a><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#indexOf-java.lang.Object-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">()</a></p> </li> <li> <p style="margin-left:0px; margin-right:0px">查找ArrayList |中最后一次出现元素的索引 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#lastIndexOf-java.lang.Object-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank">lastIndexOf()</a></p> </li> </ul> <pre> <code class="language-java">import java.util.ArrayList; import java.util.List; public class SearchElementsInArrayListExample { public static void main(String[] args) { List<String> names = new ArrayList<>(); names.add("John"); names.add("Alice"); names.add("Bob"); names.add("Steve"); names.add("John"); names.add("Steve"); names.add("Maria"); // Check if an ArrayList contains a given element System.out.println("Does names array contain \"Bob\"? : " + names.contains("Bob")); // Find the index of first occurrence of an element in an ArrayList System.out.println("indexOf \"Steve\": " + names.indexOf("Steve")); System.out.println("indexOf \"Mark\": " + names.indexOf("Mark")); // Find the index of the last occurrence of an element in an ArrayList System.out.println("lastIndexOf \"John\" : " + names.lastIndexOf("John")); System.out.println("lastIndexOf \"Bill\" : " + names.lastIndexOf("Bill")); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">Does names array contain "Bob"? : true indexOf "Steve": 3 indexOf "Mark": -1 lastIndexOf "John" : 4 lastIndexOf "Bill" : -1</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">用户定义对象的ArrayList</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">由于ArrayList支持泛型,因此可以创建<strong>任何</strong>类型的ArrayList 。它可以是简单的类型,如<code>Integer</code>,<code>String</code>,<code>Double</code>或复杂类型等的ArrayLists的ArrayList,或包含HashMap的ArrayList或任何用户定义的对象的ArrayList。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">在以下示例中,您将学习如何创建用户定义对象的ArrayList。</span></span></span></p> <pre> <code class="language-java">import java.util.ArrayList; import java.util.List; class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class ArrayListUserDefinedObjectExample { public static void main(String[] args) { List<User> users = new ArrayList<>(); users.add(new User("Rajeev", 25)); users.add(new User("John", 34)); users.add(new User("Steve", 29)); users.forEach(user -> { System.out.println("Name : " + user.getName() + ", Age : " + user.getAge()); }); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">Name : Rajeev, Age : 25 Name : John, Age : 34 Name : Steve, Age : 29</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">排序ArrayList</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">对ArrayList进行排序是您在程序中遇到的一个非常常见的任务。在本节中,我会告诉你如何 -</span></span></span></p> <ul style="margin-left:30px; margin-right:0px"> <li>使用<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>Collections.sort()</code></a>方法对ArrayList进行排序。</li> <li>使用<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#sort-java.util.Comparator-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>ArrayList.sort()</code></a>方法对ArrayList进行排序。</li> <li>用自定义比较器对用户定义对象的ArrayList进行排序。</li> </ul> <h4 style="margin-left:0px; margin-right:0px; text-align:start">1.使用Collections.sort()方法对ArrayList进行排序</h4> <pre> <code class="language-java">import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ArrayListCollectionsSortExample { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); numbers.add(13); numbers.add(7); numbers.add(18); numbers.add(5); numbers.add(2); System.out.println("Before : " + numbers); // Sorting an ArrayList using Collections.sort() method Collections.sort(numbers); System.out.println("After : " + numbers); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">Before : [13, 7, 18, 5, 2] After : [2, 5, 7, 13, 18]</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">2.使用ArrayList.sort()方法对ArrayList排序<br />  </p> <pre> <code class="language-java">import java.util.ArrayList; import java.util.Comparator; import java.util.List; public class ArrayListSortExample { public static void main(String[] args) { List<String> names = new ArrayList<>(); names.add("Lisa"); names.add("Jennifer"); names.add("Mark"); names.add("David"); System.out.println("Names : " + names); // Sort an ArrayList using its sort() method. You must pass a Comparator to the ArrayList.sort() method. names.sort(new Comparator<String>() { @Override public int compare(String name1, String name2) { return name1.compareTo(name2); } }); // The above `sort()` method call can also be written simply using lambda expressions names.sort((name1, name2) -> name1.compareTo(name2)); // Following is an even more concise solution names.sort(Comparator.naturalOrder()); System.out.println("Sorted Names : " + names); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">输出:</span></span></span></p> <pre> <code class="language-html">Names : [Lisa, Jennifer, Mark, David] Sorted Names : [David, Jennifer, Lisa, Mark]</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">3.使用自定义比较器对对象的ArrayList进行排序<br />  </p> <pre> <code class="language-java">import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public class ArrayListObjectSortExample { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("Sachin", 47)); people.add(new Person("Chris", 34)); people.add(new Person("Rajeev", 25)); people.add(new Person("David", 31)); System.out.println("Person List : " + people); // Sort People by their Age people.sort((person1, person2) -> { return person1.getAge() - person2.getAge(); }); // A more concise way of writing the above sorting function people.sort(Comparator.comparingInt(Person::getAge)); System.out.println("Sorted Person List by Age : " + people); // You can also sort using Collections.sort() method by passing the custom Comparator Collections.sort(people, Comparator.comparing(Person::getName)); System.out.println("Sorted Person List by Name : " + people); } }</code></pre> 输出: <pre> <code class="language-html">Person List : [{name='Sachin', age=47}, {name='Chris', age=34}, {name='Rajeev', age=25}, {name='David', age=31}] Sorted Person List by Age : [{name='Rajeev', age=25}, {name='David', age=31}, {name='Chris', age=34}, {name='Sachin', age=47}] Sorted Person List by Name : [{name='Chris', age=34}, {name='David', age=31}, {name='Rajeev', age=25}, {name='Sachin', age=47}]</code></pre>   <h2 style="margin-left:0px; margin-right:0px; text-align:start">同步对ArrayList的访问</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">ArrayList类不同步。如果多个线程同时尝试修改一个ArrayList,那么最终的结果变得不确定,因为一个线程可能会覆盖另一个线程所做的更改。</span></span></span></p> <h4 style="margin-left:0px; margin-right:0px; text-align:start">示例演示ArrayList在多线程环境中的不可预知行为</h4> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">以下示例显示了当多个线程同时尝试修改ArrayList时发生的情况。</span></span></span></p> <pre> <code class="language-java">import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class UnsafeArrayListExample { public static void main(String[] args) throws InterruptedException { List<Integer> unsafeArrayList = new ArrayList<>(); unsafeArrayList.add(1); unsafeArrayList.add(2); unsafeArrayList.add(3); // Create a thread pool of size 10 ExecutorService executorService = Executors.newFixedThreadPool(10); // Create a Runnable task that increments the each element of the ArrayList by one Runnable task = () -> { incrementArrayList(unsafeArrayList); }; // Submit the task to the executor service 100 times. // All the tasks will modify the ArrayList concurrently for(int i = 0; i < 100; i++) { executorService.submit(task); } executorService.shutdown(); executorService.awaitTermination(60, TimeUnit.SECONDS); System.out.println(unsafeArrayList); } // Increment all the values in the ArrayList by one private static void incrementArrayList(List<Integer> unsafeArrayList) { for(int i = 0; i < unsafeArrayList.size(); i++) { Integer value = unsafeArrayList.get(i); unsafeArrayList.set(i, value + 1); } } }</code></pre> 上述程序的最终输出应该相等,<code>[101, 102, 103]</code>因为我们将ArrayList中的值增加了100次。但是如果你运行这个程序,它会在每次运行时产生不同的输出 -<br /> 输出: <pre> <code class="language-html">[96, 96, 98]</code></pre>   <h4 style="margin-left:0px; margin-right:0px; text-align:start">演示如何将并发修改同步到ArrayList的示例</h4> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">好吧!现在让我们看看我们如何<code>ArrayList</code>在多线程环境中同步访问。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">以下示例显示了上一个示例的同步版本。与以前的程序不同,该程序的输出是确定性的,并且始终是相同的。</span></span></span></p> <pre> <code class="language-java">import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class SynchronizedArrayListExample { public static void main(String[] args) throws InterruptedException { List<Integer> safeArrayList = Collections.synchronizedList(new ArrayList<>()); safeArrayList.add(1); safeArrayList.add(2); safeArrayList.add(3); // Create a thread pool of size 10 ExecutorService executorService = Executors.newFixedThreadPool(10); // Create a Runnable task that increments the each element of the ArrayList by one Runnable task = () -> { incrementArrayList(safeArrayList); }; // Submit the task to the executor service 100 times. // All the tasks will modify the ArrayList concurrently for(int i = 0; i < 100; i++) { executorService.submit(task); } executorService.shutdown(); executorService.awaitTermination(60, TimeUnit.SECONDS); System.out.println(safeArrayList); } // Increment all the values in the ArrayList by one private static void incrementArrayList(List<Integer> safeArrayList) { synchronized (safeArrayList) { for (int i = 0; i < safeArrayList.size(); i++) { Integer value = safeArrayList.get(i); safeArrayList.set(i, value + 1); } } } }</code></pre> 输出: <pre> <code class="language-html">[101, 102, 103]</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">以上示例使用<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedList-java.util.List-" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>Collections.synchronizedList()</code></a>方法来获取ArrayList的同步视图。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff">而且,对<code>incrementArrayList()</code>方法内的ArrayList的修改被封装在一个<code>synchronized</code>块中。这确保了两个线程不能同时增加ArrayList元素。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:rgba(0, 0, 0, 0.87)"><span style="font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif"><span style="background-color:#ffffff"><em><a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html" rel="external nofollow" style="box-sizing:border-box; color:#419be8; text-decoration:none; word-wrap:break-word" target="_blank"><code>CopyOnWriteArrayList</code></a>如果你需要线程安全,你也可以使用。它是ArrayList类的线程安全版本。它通过创建ArrayList的新副本来实现所有的变异操作。</em></span></span></span></p>
  • java常用框架SpringMVC3/4入门教程

    SpringMVC框架是一个java里面非常轻量级的mvc框架之一,与spring框架同源,整合方便快捷.java常用框架SpringMVC3/4入门教程 <p>1SpringMVC3</p> <p>1.1项目结构图</p> <img alt="java常用框架SpringMVC3/4入门教程" src="/assist/images/blog/50f775fc-8470-4e98-bab8-a9195d8d2671.png" style="height:527px; width:313px" /> <p>1.2Pom.xml</p> <pre> <code class="language-xml"><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/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>seven.org</groupId>    <artifactId>springmvc3</artifactId>    <packaging>war</packaging>    <version>0.0.1-SNAPSHOT</version>    <name>springmvc3 Maven Webapp</name>    <url>http://maven.apache.org</url>    <properties>       <junit.version>4.12</junit.version>       <spring.version>3.2.2.RELEASE</spring.version>       <org.codehaus.jackson.version>1.9.13</org.codehaus.jackson.version>       <commons-fileupload.version>1.3.1</commons-fileupload.version>    </properties>    <dependencies>       <dependency>          <!-- test -->          <groupId>junit</groupId>          <artifactId>junit</artifactId>          <version>${junit.version}</version>          <scope>test</scope>       </dependency>         <!-- spring framework start -->       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-core</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-context</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-web</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-webmvc</artifactId>          <version>${spring.version}</version>       </dependency>       <!-- spring framework end -->         <!-- 为SpringMVC提供json数据类型支持 -->         <!-- 注意,新版的 jackson-core-asl已经升级为Group:com.fasterxml.jackson.core|Artifact:jackson-core在SpringMVC4中需要使用新版 -->       <dependency>          <groupId>org.codehaus.jackson</groupId>          <artifactId>jackson-core-asl</artifactId>          <version>${org.codehaus.jackson.version}</version>       </dependency>       <dependency>          <groupId>org.codehaus.jackson</groupId>          <artifactId>jackson-mapper-asl</artifactId>          <version>${org.codehaus.jackson.version}</version>       </dependency>         <!-- el 标签库 -->       <!-- standard.jar -->       <dependency>          <groupId>taglibs</groupId>          <artifactId>standard</artifactId>          <version>1.1.2</version>       </dependency>       <!-- JSTL -->       <dependency>          <groupId>javax.servlet</groupId>          <artifactId>jstl</artifactId>          <version>1.1.2</version>       </dependency>       <!-- /el 标签库 -->         <!-- 文件上传下载 -->       <dependency>          <groupId>commons-fileupload</groupId>          <artifactId>commons-fileupload</artifactId>          <version>${commons-fileupload.version}</version>       </dependency>         <!-- slf4j 和 log4j合用的Maven配置 -->       <dependency>          <groupId>org.slf4j</groupId>          <artifactId>slf4j-log4j12</artifactId>          <version>1.7.2</version>       </dependency>      </dependencies>    <build>       <finalName>springmvc3</finalName>    </build> </project></code></pre>   <p>1.3web.xml</p> <pre> <code class="language-xml"><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    version="3.0">    <display-name>Archetype Created Web Application</display-name>      <!-- 字符集处理 -->    <filter>       <filter-name>CharacterEncodingFilter</filter-name>       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>       <init-param>          <param-name>encoding</param-name>          <param-value>utf-8</param-value>       </init-param>    </filter>    <filter-mapping>       <filter-name>CharacterEncodingFilter</filter-name>       <url-pattern>/*</url-pattern>    </filter-mapping>        <!-- spring 配置 -->    <context-param>       <param-name>contextConfigLocation</param-name>       <param-value>classpath:/cfg/spring/spring-beans.xml</param-value>    </context-param>    <listener>       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>      <!-- 配置缓存清除监听器,负责处理由 JavaBean Introspector 功能而引起的缓存泄露 -->    <listener>       <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>    </listener>        <!-- springMVC配置 -->    <servlet>       <servlet-name>springMVCSerlet</servlet-name>       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>       <init-param>          <param-name>contextConfigLocation</param-name>          <param-value>classpath:/cfg/spring/spring-servlet.xml</param-value>       </init-param>       <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>       <servlet-name>springMVCSerlet</servlet-name>       <url-pattern>/</url-pattern>    </servlet-mapping>      <!-- 添加下面容器,防止同一个服务器部署多个项目web.root冲突 -->    <context-param>       <param-name>webAppRootKey</param-name>       <param-value>springMVC3</param-value>    </context-param>        <!-- log4j配置 -->    <context-param>       <param-name>log4jConfigLocation</param-name>       <param-value>classpath:/cfg/log/Log4j.properties</param-value>    </context-param>    <context-param>       <param-name>log4jRefreshInterval</param-name>       <param-value>60000</param-value>    </context-param>      <!-- session timeout -->    <session-config>       <!-- 分钟 -->       <session-timeout>60</session-timeout>    </session-config>      <!-- welcome page -->    <welcome-file-list>       <welcome-file>index.html</welcome-file>       <welcome-file>index.jsp</welcome-file>    </welcome-file-list>      <!-- session copy -->    <distributable /> </web-app></code></pre>   <p>1.4spring-servlet.xml</p> <pre> <code class="language-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:mvc="http://www.springframework.org/schema/mvc"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans-3.2.xsd             http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-3.2.xsd ">      <!-- 自动扫描包 -->    <context:component-scan base-package="com" />      <!-- 注解驱动 -->    <mvc:annotation-driven />    <mvc:default-servlet-handler />    <!-- 资源管理不拦截 -->    <mvc:resources location="/resources/" mapping="/resources/**" />    <mvc:resources location="/upload/" mapping="/upload/**" />      <!-- 内部资源视图解析器 prefix + logicName + suffix /WEB-INF/jsps/ + index + .jsp -->    <bean id="internalResourceViewResolver"       class="org.springframework.web.servlet.view.InternalResourceViewResolver">       <!-- 前缀 -->       <property name="prefix" value="/WEB-INF/pages/" />       <!-- 后缀 -->       <property name="suffix" value="" />    </bean>        <!-- 上传图片/文件需要配置 -->    <bean id="multipartResolver"       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">       <property name="maxUploadSize" value="104857600" />       <property name="maxInMemorySize" value="4096" />    </bean>        <!-- 配置JSON支持 start -->    <bean id="mappingJacksonHttpMessageConverter"    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">       <property name="supportedMediaTypes">          <list>             <!-- 处理返回的json数据的编码,默认是ISO-88859-1 -->             <value>text/html;charset=UTF-8</value>          </list>       </property>    </bean>    <bean    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">       <!-- messageConverters属性中加入 mappingJacksonHttpMessageConverter用来处理json数据类行 -->       <property name="messageConverters">          <list>             <ref bean="mappingJacksonHttpMessageConverter" />          </list>       </property>    </bean>    <!-- 配置JSON支持 end -->     </beans></code></pre> <br /> 1.5spring-beans.xml <pre> <code class="language-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:mvc="http://www.springframework.org/schema/mvc"    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jpa="http://www.springframework.org/schema/data/jpa"    xsi:schemaLocation="http://www.springframework.org/schema/beans                 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd             http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd               http://www.springframework.org/schema/aop             http://www.springframework.org/schema/aop/spring-aop-3.2.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-3.2.xsd             http://www.springframework.org/schema/tx             http://www.springframework.org/schema/tx/spring-tx-3.2.xsd             http://www.springframework.org/schema/data/jpa             http://www.springframework.org/schema/data/jpa/spring-jpa.xsd ">    <context:annotation-config />    <!-- 启动自动扫描该包下所有的注解(如@controller) -->    <context:component-scan base-package="com" />   </beans>  </code></pre>   <p>1.6Log4j配置文件</p> <pre> <code>#defind the rooeLogger ,the rootlogger min level is INFO,and two way to output log log4j.rootLogger = INFO,FILE,CONSOLE,DATABASE   #---------------------------------------------------------------------- #defind the FILE as file everyday                                     | #---------------------------------------------------------------------- log4j.appender.FILE = org.apache.log4j.DailyRollingFileAppender   #the log min level set as INFO log4j.appender.FILE.Threshold=INFO   #log file encoding set UTF-8 log4j.appender.FILE.encoding=UTF-8   #log file path log4j.appender.FILE.File=/home/tomcat/log/springmvc3/springmvc3   #log file name append log4j.appender.FILE.DatePattern='_'yyyy-MM-dd'.log'   #Immediate write the log is true log4j.appender.FILE.ImmediateFlush=true   #the layout of the log log4j.appender.FILE.layout=org.apache.log4j.PatternLayout   #the detail layout of log  in the log file log4j.appender.FILE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} Springmvc3 %-5p [%c:%L] | %m%n   #------------------------------------------------------------------------- #this use the 'org.apache.log4j.ConsoleAppender' to output in the Console| #------------------------------------------------------------------------- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender   #output min level is INFO log4j.appender.Threshold=INFO   #the output target is Console log4j.appender.CONSOLE.Target=System.out   #the layout of the log log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} springmvc3 %-5p | %m%n   #---------------------------------------------------------------------------- #insert the log into database                                               | #---------------------------------------------------------------------------- log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender #The jdbc url log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/springmvc3 #The jdbc driver log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver #DB user log4j.appender.DATABASE.user=root #DB password log4j.appender.DATABASE.password=root #sql log4j.appender.DATABASE.sql=INSERT INTO zhl_log (operationTime,logLevel,logClass,logDetail)  VALUES ("%d{yyyy-MM-dd HH:mm:ss}", "%-5p","%F:%L", "%m") #layout log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout #layout detail log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</code></pre> <br /> 1.7测试vo <pre> <code class="language-java">package com.xqlee.springmvc.vo;   /**  *  *  * <pre>  * @功能说明 [测试bean]  * @其他说明 [暂无]  * @文件编码 [UTF-8]  * @所属包名 [com.xqlee.springmvc.vo]  * @项目名称 [cdws]  * @创建日期 []  * @创建人员 [lxq]  * @最后修改 []  * @修改说明 [暂无更新]  * @修改人员 [lxq]  * @公司组织 [org]  * @版本说明 [v 1.0]  *  * </pre>  */ public class Tobject {      private String id;    private String name;    private String num;      public Tobject(String id, String name, String num) {       this.id = id;       this.name = name;       this.num = num;    }      public String getId() {       return id;    }      public void setId(String id) {       this.id = id;    }      public String getName() {       return name;    }      public void setName(String name) {       this.name = name;    }      public String getNum() {       return num;    }      public void setNum(String num) {       this.num = num;    }   }</code></pre> <br /> 1.8测试controller <pre> <code class="language-java">package com.xqlee.springmvc.controller;   import java.util.Vector;   import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;   import com.xqlee.springmvc.vo.Tobject;   /**  *  *  * <pre>  * @功能说明 [测试类]  * @其他说明 [暂无]  * @文件编码 [UTF-8]  * @所属包名 [com.xqlee.springmvc.controller]  * @项目名称 [cdws]  * @创建日期 []  * @创建人员 [lxq]  * @最后修改 []  * @修改说明 [暂无更新]  * @修改人员 [lxq]  * @公司组织 [org]  * @版本说明 [v 1.0]  *  * </pre>  */ @Controller(value = "/beanTestController.do") public class BeanTestController {    @RequestMapping(params = "method=Vector")    // @ResponseBody    public Object testVector(HttpServletRequest request,          HttpServletResponse response) {       // 创建容器       Vector<Tobject> vtb = new Vector<Tobject>();       Tobject tb;       for (int i = 0; i <= 5; i++) {          tb = new Tobject("ID-" + i, "名称Name-" + i, "Num-" + i);          vtb.add(tb);       }       request.setAttribute("vtb", vtb);       return "../../vector.jsp";    }      @RequestMapping(params = "method=testJson")    @ResponseBody    public Object testJson(HttpServletRequest request,          HttpServletResponse response) {       // 创建容器       Vector<Tobject> vtb = new Vector<Tobject>();       Tobject tb;       for (int i = 0; i <= 5; i++) {          tb = new Tobject("ID-" + i, "名称Name-" + i, "Num-" + i);          vtb.add(tb);       }       return vtb;    }   }</code></pre>   <p>1.9index.jsp</p> <pre> <code class="language-html"><!DOCTYPE> <html> <body>    <h2>Hello World!</h2>    <a href="beanTestController.do?method=Vector">Vector Test</a> </body> </html></code></pre> <br /> 1.10vector.jsp <pre> <code class="language-html"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE> <html> <body>    <table border='1'>       <thead>          <tr>             <td>ID</td>             <td>Name</td>             <td>Num</td>          </tr>       </thead>       <tbody>          <c:forEach items="${vtb}" var="Object">             <tr>                 <td>${Object.id}</td>                 <td>${Object.name}</td>                 <td>${Object.num}</td>             </tr>          </c:forEach>       </tbody>    </table>     </body> </html></code></pre> <br /> 2 SpringMVC4 <p>2.1项目结构图</p> <img alt="2" src="/assist/images/blog/63555b40-5fa1-41e6-9d7c-3d9e088a6223.png" style="height:510px; width:387px" /> <p>2.2pom.xml</p> <pre> <code class="language-xml"><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/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>seven.org</groupId>    <artifactId>springMVC</artifactId>    <packaging>war</packaging>    <version>0.0.1-SNAPSHOT</version>    <name>springMVC Maven Webapp</name>    <url>http://maven.apache.org</url>    <!-- 属性版本 -->    <properties>       <junit.version>4.12</junit.version>       <spring.version>4.1.7.RELEASE</spring.version>       <org.slf4j.version>1.7.2</org.slf4j.version>       <mysql.driver.version>5.1.32</mysql.driver.version>    <com.fasterxml.jackson.jaxrs.version>2.4.1</com.fasterxml.jackson.jaxrs.version>       <commons-fileupload.version>1.3.1</commons-fileupload.version>      </properties>    <dependencies>         <!-- 测试所需 -->       <dependency>          <groupId>junit</groupId>          <artifactId>junit</artifactId>          <version>${junit.version}</version>          <scope>test</scope>       </dependency>         <!-- spring core -->       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-core</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-context</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-web</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-webmvc</artifactId>          <version>${spring.version}</version>       </dependency>         <!-- MySQL数据库驱动 导入 start -->       <dependency>          <groupId>mysql</groupId>          <artifactId>mysql-connector-java</artifactId>          <version>${mysql.driver.version}</version>       </dependency>       <!-- MySQL数据库驱动 导入 end -->           <!-- el 标签库 -->       <!-- standard.jar -->       <dependency>          <groupId>taglibs</groupId>          <artifactId>standard</artifactId>          <version>1.1.2</version>       </dependency>       <!-- JSTL -->       <dependency>          <groupId>javax.servlet</groupId>          <artifactId>jstl</artifactId>          <version>1.1.2</version>       </dependency>       <!-- /el 标签库 -->         <!-- 处理json -->       <dependency>          <groupId>com.fasterxml.jackson.jaxrs</groupId>          <artifactId>jackson-jaxrs-xml-provider</artifactId>          <version>${com.fasterxml.jackson.jaxrs.version}</version>       </dependency>         <!-- 文件上传下载 -->       <dependency>          <groupId>commons-fileupload</groupId>          <artifactId>commons-fileupload</artifactId>          <version>${commons-fileupload.version}</version>       </dependency>         <!-- slf4j 和 log4j合用的Maven配置 -->       <dependency>          <groupId>org.slf4j</groupId>          <artifactId>slf4j-log4j12</artifactId>          <version>${org.slf4j.version}</version>       </dependency>      </dependencies>    <build>       <finalName>springMVC</finalName>    </build> </project></code></pre> <br /> 2.3web.xml <pre> <code class="language-xml"><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    version="3.0">    <display-name>Archetype Created Web Application</display-name>      <!-- 字符集处理 -->    <filter>       <filter-name>CharacterEncodingFilter</filter-name>       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>       <init-param>          <param-name>encoding</param-name>          <param-value>utf-8</param-value>       </init-param>    </filter>    <filter-mapping>       <filter-name>CharacterEncodingFilter</filter-name>       <url-pattern>/*</url-pattern>    </filter-mapping>        <!-- spring 核心配置 -->    <context-param>       <param-name>contextConfigLocation</param-name>       <param-value>classpath:/cfg/spring/spring-beans.xml</param-value>    </context-param>    <listener>       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>      <!-- 配置缓存清除监听器,负责处理由 JavaBean Introspector 功能而引起的缓存泄露 -->    <listener>       <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>    </listener>        <!-- springMVC配置 -->    <servlet>       <servlet-name>springMVCSerlet</servlet-name>       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>       <init-param>          <param-name>contextConfigLocation</param-name>          <param-value>classpath:/cfg/spring/spring-servlet.xml</param-value>       </init-param>       <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>       <servlet-name>springMVCSerlet</servlet-name>       <url-pattern>/</url-pattern>    </servlet-mapping>      <!-- 添加下面容器,防止同一个服务器部署多个项目web.root冲突 -->    <context-param>       <param-name>webAppRootKey</param-name>       <param-value>springMVC4</param-value>    </context-param>      <!-- session timeout -->    <session-config>       <!-- 分钟 -->       <session-timeout>60</session-timeout>    </session-config>      <!-- log4j配置 -->    <context-param>       <param-name>log4jConfigLocation</param-name>       <param-value>classpath:/cfg/log/Log4j.properties</param-value>    </context-param>    <context-param>       <param-name>log4jRefreshInterval</param-name>       <param-value>60000</param-value>    </context-param>    <!--添加监听 -->    <listener>       <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>    </listener>    <!-- /log4j配置 -->      <!-- welcome page -->    <welcome-file-list>       <welcome-file>index.html</welcome-file>       <welcome-file>index.jsp</welcome-file>    </welcome-file-list>      <!-- session copy -->    <distributable /> </web-app></code></pre>   <p>2.4 weblogic.xml</p> <pre> <code class="language-xml"><?xml version="1.0" encoding="UTF-8"?> <weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd    http://xmlns.oracle.com/weblogic/weblogic-web-app    http://xmlns.oracle.com/weblogic/weblogic-web-app/1.2/weblogic-web-app.xsd">      <container-descriptor>       <!-- 针对weblogic10以下的版本使用该语句,不能与厦门的prefer-application-packages同时使用 -->       <!-- <prefer-web-inf-classes>true</prefer-web-inf-classes> -->       <!-- 针对weblogic10及以上的版本如果上面语句无法成功使用该语句,不能与厦门的prefer-web-inf-classes同时使用 -->       <prefer-application-packages>          <package-name>org.apache.commons.lang.*</package-name>          <package-name>antlr.*</package-name>          <package-name>org.hibernate.*</package-name>          <package-name>javax.persistence.*</package-name>       </prefer-application-packages>    </container-descriptor> </weblogic-web-app></code></pre>   <p>2.5spring-servlet.xml</p> <pre> <code class="language-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:mvc="http://www.springframework.org/schema/mvc"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans-4.1.xsd             http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-4.1.xsd ">      <!-- 自动扫描controller包下所有 -->    <context:component-scan base-package="com.xqlee.springmvc.controller" />    <!-- 注解驱动 -->    <mvc:annotation-driven />    <mvc:default-servlet-handler />    <!-- 资源管理不拦截 -->    <mvc:resources location="/resources/" mapping="/resources/**" />    <mvc:resources location="/upload/" mapping="/upload/**" />      <!-- 内部资源视图解析器 prefix + logicName + suffix /WEB-INF/jsps/ + index + .jsp -->    <bean id="internalResourceViewResolver"       class="org.springframework.web.servlet.view.InternalResourceViewResolver">       <!-- 前缀 -->       <property name="prefix" value="/WEB-INF/pages/" />       <!-- 后缀 -->       <property name="suffix" value="" />    </bean>      <!-- 处理在controller中使用注解@ResponseBody标签返回JSON数据 Start -->    <!-- 注意[由于我在pom.xml引入的是2.4.1版本]:所以class=org.springframework.http.converter.json.MappingJackson2HttpMessageConverter -->    <!-- [如果pom.xml引入的是1.xx版本]class=org.springframework.http.converter.json.MappingJacksonHttpMessageConverter -->    <bean id="mappingJackson2HttpMessageConverter"    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">       <property name="supportedMediaTypes">          <list>             <value>text/html;charset=UTF-8</value>             <value>text/json;charset=UTF-8</value>             <value>application/json;charset=UTF-8</value>          </list>       </property>    </bean>    <bean    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">       <property name="messageConverters">          <list>             <ref bean="mappingJackson2HttpMessageConverter" />          </list>       </property>    </bean>    <!-- JSON数据处理 End -->      <!-- 上传图片/文件需要配置 -->    <bean id="multipartResolver"       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">       <property name="maxUploadSize" value="-1" /><!-- -1表示没有限制 -->       <property name="maxInMemorySize" value="4096" />    </bean>   </beans></code></pre>   <p>2.6spring-beans.xml</p> <pre> <code class="language-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:mvc="http://www.springframework.org/schema/mvc"    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jpa="http://www.springframework.org/schema/data/jpa"    xsi:schemaLocation="http://www.springframework.org/schema/beans                 http://www.springframework.org/schema/beans/spring-beans-4.1.xsd             http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd               http://www.springframework.org/schema/aop             http://www.springframework.org/schema/aop/spring-aop-4.1.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-4.1.xsd             http://www.springframework.org/schema/tx             http://www.springframework.org/schema/tx/spring-tx-4.1.xsd             http://www.springframework.org/schema/data/jpa             http://www.springframework.org/schema/data/jpa/spring-jpa.xsd ">    <context:annotation-config />    <!-- 启动自动扫描该包下所有的注解(如@controller) 一般扫描service,entity,dao,controller由springMVC扫描 -->    <context:component-scan       base-package="com.xqlee.springmvc.service,com.xqlee.springmvc.entity,com.xqlee.springmvc.dao" /> </beans></code></pre>   <p>2.7 Log4j配置文件</p> <pre> <code>#defind the rooeLogger ,the rootlogger min level is INFO,and two way to output log log4j.rootLogger = INFO,FILE,CONSOLE,DATABASE   #---------------------------------------------------------------------- #defind the FILE as file everyday                                     | #---------------------------------------------------------------------- #log4j.appender.FILE = org.apache.log4j.DailyRollingFileAppender   #the log min level set as INFO #log4j.appender.FILE.Threshold=INFO   #log file encoding set UTF-8 #log4j.appender.FILE.encoding=UTF-8   #log file path #log4j.appender.FILE.File=/home/tomcat/log/springmvc4/springmvc4   #log file name append #log4j.appender.FILE.DatePattern='_'yyyy-MM-dd'.log'   #Immediate write the log is true #log4j.appender.FILE.ImmediateFlush=true   #the layout of the log #log4j.appender.FILE.layout=org.apache.log4j.PatternLayout   #the detail layout of log  in the log file #log4j.appender.FILE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} springmvc4 %-5p [%c:%L] | %m%n   #------------------------------------------------------------------------- #this use the 'org.apache.log4j.ConsoleAppender' to output in the Console| #------------------------------------------------------------------------- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender   #output min level is INFO log4j.appender.Threshold=INFO   #the output target is Console log4j.appender.CONSOLE.Target=System.out   #the layout of the log log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} springmvc4 %-5p | %m%n   #---------------------------------------------------------------------------- #insert the log into database                                               | #---------------------------------------------------------------------------- #log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender #The jdbc url #log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/springmvc4 #The jdbc driver #log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver #DB user #log4j.appender.DATABASE.user=root #DB password #log4j.appender.DATABASE.password=root #sql #log4j.appender.DATABASE.sql=INSERT INTO zhl_log (operationTime,logLevel,logClass,logDetail)  VALUES ("%d{yyyy-MM-dd HH:mm:ss}", "%-5p","%F:%L", "%m") #layout #log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout #layout detail #log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</code></pre>   <p>2.8测试vo</p> <pre> <code class="language-java">package com.xqlee.springmvc.vo;   /**  *  *  * <pre>  * @功能说明 [测试bean]  * @其他说明 [暂无]  * @文件编码 [UTF-8]  * @所属包名 [com.xqlee.springmvc.vo]  * @项目名称 [cdws]  * @创建日期 []  * @创建人员 [lxq]  * @最后修改 []  * @修改说明 [暂无更新]  * @修改人员 [lxq]  * @公司组织 [org]  * @版本说明 [v 1.0]  *  * </pre>  */ public class User {      private String id;    private String name;    private String num;      public User(String id, String name, String num) {       this.id = id;       this.name = name;       this.num = num;    }      public String getId() {       return id;    }      public void setId(String id) {       this.id = id;    }      public String getName() {       return name;    }      public void setName(String name) {       this.name = name;    }      public String getNum() {       return num;    }      public void setNum(String num) {       this.num = num;    }   }</code></pre>   <p>2.9测试controller</p> <pre> <code class="language-java">package com.xqlee.springmvc.controller;   import java.util.Vector;   import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;   import com.xqlee.springmvc.vo.User;   /**  *  *  * <pre>  * &#64;功能说明 [测试类]  * &#64;其他说明 [暂无]  * &#64;文件编码 [UTF-8]  * &#64;所属包名 [com.xqlee.springmvc.controller]  * &#64;项目名称 [cdws]  * &#64;创建日期 []  * &#64;创建人员 [lxq]  * &#64;最后修改 []  * &#64;修改说明 [暂无更新]  * &#64;修改人员 [lxq]  * &#64;公司组织 [org]  * &#64;版本说明 [v 1.0]  *  * </pre>  */ @Controller(value = "/beanTestController.do") public class TestController {    /** 日志 **/    private static final Log log = LogFactory.getLog(TestController.class);      @RequestMapping(params = "method=Vector")    // @ResponseBody    public Object testVector(HttpServletRequest request, HttpServletResponse response) {       // 创建容器       Vector<User> vtb = new Vector<User>();       User tb;       for (int i = 0; i <= 5; i++) {          tb = new User("ID-" + i, "小Name-" + i, "李Num-" + i);          vtb.add(tb);       }       request.setAttribute("vtb", vtb);       log.info("即将跳转.....");       return "../../vector.jsp";    } }</code></pre>   <p>2.10 index.jsp</p> <pre> <code class="language-html"><!DOCTYPE> <html> <body>    <h2>Hello World!</h2>    <a href="beanTestController.do?method=Vector">Vector Test</a> </body> </html></code></pre>   <p>2.11 vector.jsp</p> <pre> <code class="language-html"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE> <html> <body>    <table border='1'>       <thead>          <tr>             <td>ID</td>             <td>Name</td>             <td>Num</td>          </tr>       </thead>       <tbody>          <c:forEach items="${vtb}" var="Object">             <tr>                 <td>${Object.id}</td>                 <td>${Object.name}</td>                 <td>${Object.num}</td>             </tr>          </c:forEach>       </tbody>    </table>     </body> </html></code></pre>   <p>2.12运行结果</p> <img alt="3" src="/assist/images/blog/d439127f-c160-4faa-a47b-1f3118f87ba5.png" style="height:213px; width:422px" /><br /> <img alt="4" src="/assist/images/blog/46005b58-d05f-4bab-b517-11ed209014c9.png" style="height:486px; width:611px" /><br />