23.2.1 数据缓存的定义
定义 :数据缓存是一种存储 **机制,用于将常用数据存储在高速存储设备中,以便快速访问。
作用:
- 提高应用程序的性能。
- 减少数据库的访问次数。
- 提高用户体验。
常见的数据缓存:
- EhCache:Apache EhCache是一款开源的缓存库。
- Caffeine:Caffeine是一款高性能的缓存库。
- Redis:Redis是一款开源的缓存服务器。
✅ 结论:数据缓存是一种存储机制,作用是提高应用程序的性能、减少数据库的访问次数、提高用户体验。
23.2.2 数据缓存的特点
定义 :数据缓存的特点是指数据缓存的特性。
特点:
- 高速访问:数据缓存提供高速访问。
- 数据一致性:数据缓存提供数据一致性。
- 可扩展性:数据缓存可以扩展到多个应用程序之间的缓存通信。
- 易用性:数据缓存提供易用的编程模型。
✅ 结论:数据缓存的特点包括高速访问、数据一致性、可扩展性、易用性。
23.3 Spring Boot与数据缓存的集成
Spring Boot与数据缓存的集成是Java开发中的重要内容。
23.3.1 集成EhCache的步骤
定义 :集成EhCache的步骤是指使用Spring Boot与EhCache集成的方法。
步骤:
- 创建Spring Boot项目。
- 添加所需的依赖。
- 配置EhCache。
- 创建数据访问层。
- 创建业务层。
- 创建控制器类。
- 测试应用。
示例 :
pom.xml文件中的依赖:
xml
<dependencies>
<!-- Web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Data JPA依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2数据库依赖 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- EhCache依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
AI写代码xml
12345678910111213141516171819202122232425262728293031323334353637
application.properties文件中的EhCache配置:
ini
# 服务器端口
server.port=8080
# 数据库连接信息
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
# JPA配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# H2数据库控制台
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# EhCache配置
spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:ehcache.xml
AI写代码properties
1234567891011121314151617181920
ehcache.xml配置文件:
ini
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<defaultCache
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120">
</defaultCache>
<cache name="productCache"
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120">
</cache>
</ehcache>
AI写代码xml
1234567891011121314151617181920212223
实体类 **:
typescript
import javax.persistence.*;
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String productId;
private String productName;
private double price;
private int sales;
public Product() {
}
public Product(String productId, String productName, double price, int sales) {
this.productId = productId;
this.productName = productName;
this.price = price;
this.sales = sales;
}
// Getter和Setter方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getSales() {
return sales;
}
public void setSales(int sales) {
this.sales = sales;
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
", productId='" + productId + ''' +
", productName='" + productName + ''' +
", price=" + price +
", sales=" + sales +
'}';
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
Repository接口:
kotlin
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
}
AI写代码java
运行
123456
Service类:
kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
@CachePut(value = "productCache", key = "#product.id")
public Product addProduct(Product product) {
return productRepository.save(product);
}
@Transactional
@CachePut(value = "productCache", key = "#product.id")
public Product updateProduct(Product product) {
return productRepository.save(product);
}
@Transactional
@CacheEvict(value = "productCache", key = "#id")
public void deleteProduct(Long id) {
productRepository.deleteById(id);
}
@Transactional(readOnly = true)
@Cacheable(value = "productCache", key = "#id")
public Product getProductById(Long id) {
System.out.println("从数据库查询产品:" + id);
return productRepository.findById(id).orElse(null);
}
@Transactional(readOnly = true)
public List<Product> getAllProducts() {
return productRepository.findAll();
}
}
AI写代码java
运行
1234567891011121314151617181920212223242526272829303132333435363738394041424344
控制器类:
less
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/")
public List<Product> getAllProducts() {
return productService.getAllProducts();
}
@PostMapping("/")
public Product addProduct(@RequestBody Product product) {
return productService.addProduct(product);
}
@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody Product product) {
product.setId(id);
return productService.updateProduct(product);
}
@DeleteMapping("/{id}")
public void deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
}
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
return productService.getProductById(id);
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637
应用启动类:
typescript
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
@Autowired
private ProductService productService;
public void run(String... args) {
// 初始化数据
productService.addProduct(new Product("P001", "手机", 1000.0, 100));
productService.addProduct(new Product("P002", "电脑", 5000.0, 50));
productService.addProduct(new Product("P003", "电视", 3000.0, 80));
productService.addProduct(new Product("P004", "手表", 500.0, 200));
productService.addProduct(new Product("P005", "耳机", 300.0, 150));
}
}
AI写代码java
运行
123456789101112131415161718192021222324
测试类:
java
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ProductApplicationTests {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void contextLoads() {
}
@Test
void testGetProductById() {
Product product1 = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(product1).isNotNull();
assertThat(product1.getProductId()).isEqualTo("P001");
Product product2 = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(product2).isNotNull();
assertThat(product2.getProductId()).isEqualTo("P001");
}
@Test
void testAddProduct() {
Product product = new Product("P006", "平板", 2000.0, 70);
Product savedProduct = restTemplate.postForObject("http://localhost:" + port + "/api/products/", product, Product.class);
assertThat(savedProduct).isNotNull();
assertThat(savedProduct.getProductId()).isEqualTo("P006");
}
@Test
void testUpdateProduct() {
Product product = new Product("P001", "手机", 1500.0, 120);
restTemplate.put("http://localhost:" + port + "/api/products/1", product);
Product updatedProduct = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(updatedProduct).isNotNull();
assertThat(updatedProduct.getPrice()).isEqualTo(1500.0);
}
@Test
void testDeleteProduct() {
restTemplate.delete("http://localhost:" + port + "/api/products/2");
Product product = restTemplate.getForObject("http://localhost:" + port + "/api/products/2", Product.class);
assertThat(product).isNull();
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
✅ 结论:集成EhCache的步骤包括创建Spring Boot项目、添加所需的依赖、配置EhCache、创建数据访问层、创建业务层、创建控制器类、测试应用。
23.4 Spring Boot与数据缓存的配置
Spring Boot与数据缓存的配置是Java开发中的重要内容。
23.4.1 配置Caffeine **缓存
定义 :配置Caffeine缓存是指使用Spring Boot与Caffeine缓存集成的方法。
步骤:
- 创建Spring Boot项目。
- 添加所需的依赖。
- 配置Caffeine缓存。
- 创建数据访问层。
- 创建业务层。
- 创建控制器类。
- 测试应用。
示例 :
pom.xml文件中的依赖:
xml
<dependencies>
<!-- Web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Data JPA依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2数据库依赖 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Caffeine依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
AI写代码xml
12345678910111213141516171819202122232425262728293031323334353637
application.properties文件中的Caffeine缓存配置:
ini
# 服务器端口
server.port=8080
# 数据库连接信息
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
# JPA配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# H2数据库控制台
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# Caffeine缓存配置
spring.cache.type=caffeine
spring.cache.caffeine.spec=maximumSize=1000,expireAfterWrite=60s
AI写代码properties
1234567891011121314151617181920
控制器类:
less
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/")
public List<Product> getAllProducts() {
return productService.getAllProducts();
}
@PostMapping("/")
public Product addProduct(@RequestBody Product product) {
return productService.addProduct(product);
}
@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody Product product) {
product.setId(id);
return productService.updateProduct(product);
}
@DeleteMapping("/{id}")
public void deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
}
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
return productService.getProductById(id);
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637
测试类:
java
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ProductApplicationTests {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void contextLoads() {
}
@Test
void testGetProductById() {
Product product1 = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(product1).isNotNull();
assertThat(product1.getProductId()).isEqualTo("P001");
Product product2 = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(product2).isNotNull();
assertThat(product2.getProductId()).isEqualTo("P001");
}
@Test
void testAddProduct() {
Product product = new Product("P006", "平板", 2000.0, 70);
Product savedProduct = restTemplate.postForObject("http://localhost:" + port + "/api/products/", product, Product.class);
assertThat(savedProduct).isNotNull();
assertThat(savedProduct.getProductId()).isEqualTo("P006");
}
@Test
void testUpdateProduct() {
Product product = new Product("P001", "手机", 1500.0, 120);
restTemplate.put("http://localhost:" + port + "/api/products/1", product);
Product updatedProduct = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(updatedProduct).isNotNull();
assertThat(updatedProduct.getPrice()).isEqualTo(1500.0);
}
@Test
void testDeleteProduct() {
restTemplate.delete("http://localhost:" + port + "/api/products/2");
Product product = restTemplate.getForObject("http://localhost:" + port + "/api/products/2", Product.class);
assertThat(product).isNull();
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
✅ 结论:配置Caffeine缓存是指使用Spring Boot与Caffeine缓存集成的方法,步骤包括创建Spring Boot项目、添加所需的依赖、配置Caffeine缓存、创建数据访问层、创建业务层、创建控制器类、测试应用。
23.5 Spring Boot与数据缓存的基本方法
Spring Boot与数据缓存的基本方法包括使用@Cacheable、@CachePut、@CacheEvict注解。
23.5.1 使用@Cacheable注解
定义 :使用@Cacheable注解是指Spring Boot与数据缓存集成的基本方法之一。
作用:
- 实现数据缓存。
- 提高应用程序的性能。
示例:
kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional(readOnly = true)
@Cacheable(value = "productCache", key = "#id")
public Product getProductById(Long id) {
System.out.println("从数据库查询产品:" + id);
return productRepository.findById(id).orElse(null);
}
@Transactional(readOnly = true)
public List<Product> getAllProducts() {
return productRepository.findAll();
}
}
AI写代码java
运行
123456789101112131415161718192021222324
✅ 结论:使用@Cacheable注解是指Spring Boot与数据缓存集成的基本方法之一,作用是实现数据缓存、提高应用程序的性能。
23.5.2 使用@CachePut注解
定义 :使用@CachePut注解是指Spring Boot与数据缓存集成的基本方法之一。
作用:
- 实现数据缓存。
- 提高应用程序的性能。
示例:
kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
@CachePut(value = "productCache", key = "#product.id")
public Product addProduct(Product product) {
return productRepository.save(product);
}
@Transactional
@CachePut(value = "productCache", key = "#product.id")
public Product updateProduct(Product product) {
return productRepository.save(product);
}
@Transactional(readOnly = true)
@Cacheable(value = "productCache", key = "#id")
public Product getProductById(Long id) {
System.out.println("从数据库查询产品:" + id);
return productRepository.findById(id).orElse(null);
}
@Transactional(readOnly = true)
public List<Product> getAllProducts() {
return productRepository.findAll();
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536
✅ 结论:使用@CachePut注解是指Spring Boot与数据缓存集成的基本方法之一,作用是实现数据缓存、提高应用程序的性能。
23.5.3 使用@CacheEvict注解
定义 :使用@CacheEvict注解是指Spring Boot与数据缓存集成的基本方法之一。
作用:
- 实现数据缓存。
- 提高应用程序的性能。
示例:
kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
@CachePut(value = "productCache", key = "#product.id")
public Product addProduct(Product product) {
return productRepository.save(product);
}
@Transactional
@CachePut(value = "productCache", key = "#product.id")
public Product updateProduct(Product product) {
return productRepository.save(product);
}
@Transactional
@CacheEvict(value = "productCache", key = "#id")
public void deleteProduct(Long id) {
productRepository.deleteById(id);
}
@Transactional(readOnly = true)
@Cacheable(value = "productCache", key = "#id")
public Product getProductById(Long id) {
System.out.println("从数据库查询产品:" + id);
return productRepository.findById(id).orElse(null);
}
@Transactional(readOnly = true)
public List<Product> getAllProducts() {
return productRepository.findAll();
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142
✅ 结论:使用@CacheEvict注解是指Spring Boot与数据缓存集成的基本方法之一,作用是实现数据缓存、提高应用程序的性能。
23.6 Spring Boot的实际应用场景
在实际开发中,Spring Boot数据缓存与性能优化的应用场景非常广泛,如:
- 实现产品信息的缓存。
- 实现用户信息的缓存。
- 实现订单信息的缓存。
- 实现日志信息的缓存。
示例:
typescript
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
@Autowired
private ProductService productService;
public void run(String... args) {
// 初始化数据
productService.addProduct(new Product("P001", "手机", 1000.0, 100));
productService.addProduct(new Product("P002", "电脑", 5000.0, 50));
productService.addProduct(new Product("P003", "电视", 3000.0, 80));
productService.addProduct(new Product("P004", "手表", 500.0, 200));
productService.addProduct(new Product("P005", "耳机", 300.0, 150));
}
}
@Service
class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
@CachePut(value = "productCache", key = "#product.id")
public Product addProduct(Product product) {
return productRepository.save(product);
}
@Transactional
@CachePut(value = "productCache", key = "#product.id")
public Product updateProduct(Product product) {
return productRepository.save(product);
}
@Transactional
@CacheEvict(value = "productCache", key = "#id")
public void deleteProduct(Long id) {
productRepository.deleteById(id);
}
@Transactional(readOnly = true)
@Cacheable(value = "productCache", key = "#id")
public Product getProductById(Long id) {
System.out.println("从数据库查询产品:" + id);
return productRepository.findById(id).orElse(null);
}
@Transactional(readOnly = true)
public List<Product> getAllProducts() {
return productRepository.findAll();
}
}
@RestController
@RequestMapping("/api/products")
class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/")
public List<Product> getAllProducts() {
return productService.getAllProducts();
}
@PostMapping("/")
public Product addProduct(@RequestBody Product product) {
return productService.addProduct(product);
}
@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody Product product) {
product.setId(id);
return productService.updateProduct(product);
}
@DeleteMapping("/{id}")
public void deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
}
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
return productService.getProductById(id);
}
}
// 测试类
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ProductApplicationTests {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void contextLoads() {
}
@Test
void testGetProductById() {
Product product1 = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(product1).isNotNull();
assertThat(product1.getProductId()).isEqualTo("P001");
Product product2 = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(product2).isNotNull();
assertThat(product2.getProductId()).isEqualTo("P001");
}
@Test
void testAddProduct() {
Product product = new Product("P006", "平板", 2000.0, 70);
Product savedProduct = restTemplate.postForObject("http://localhost:" + port + "/api/products/", product, Product.class);
assertThat(savedProduct).isNotNull();
assertThat(savedProduct.getProductId()).isEqualTo("P006");
}
@Test
void testUpdateProduct() {
Product product = new Product("P001", "手机", 1500.0, 120);
restTemplate.put("http://localhost:" + port + "/api/products/1", product);
Product updatedProduct = restTemplate.getForObject("http://localhost:" + port + "/api/products/1", Product.class);
assertThat(updatedProduct).isNotNull();
assertThat(updatedProduct.getPrice()).isEqualTo(1500.0);
}
@Test
void testDeleteProduct() {
restTemplate.delete("http://localhost:" + port + "/api/products/2");
Product product = restTemplate.getForObject("http://localhost:" + port + "/api/products/2", Product.class);
assertThat(product).isNull();
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142