1. キャッシュとして
1.1 使用する理由
データはメモリに保存され、データ クエリの速度が高速です。データベースのプレッシャーを共有できます。
1.2 キャッシュに入れるのに適したデータの種類
クエリの頻度は比較的高く、変更の頻度は比較的低いです。
セキュリティ係数の低いデータ
1.3 Redis をキャッシュとして使用する
1.3.1 構成クラスは使用しない
エンティティ クラスはシリアル化する必要があることに注意してください:
@Data @AllArgsConstructor @NoArgsConstructor @TableName(value = "tb_dept") public class Dept implements Serializable { @TableId(value = "id",type = IdType.AUTO) private Integer id; private String name; private String realname; }
対応する依存関係:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--连接数据源--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--mp的依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
コントローラー層対応コード:
@RestController @RequestMapping("order") public class DeptController { @Resource private DeptService deptService; @GetMapping("getById/{id}") //order/getById/1 //{}可以放多个,由下面的传参函数对应 //@PathVariable:获取请求映射中{}的值 public Dept getById(@PathVariable Integer id){ return deptService.findById(id); } @GetMapping("deleteById/{id}") public String deleteById(@PathVariable Integer id){ int i = deptService.deleteById(id); return i>0?"删除成功":"删除失败"; } @GetMapping("insert") public Dept insert(Dept dept){ Dept insert = deptService.insert(dept); return insert; } @GetMapping("update") public Dept update(Dept dept){ Dept update = deptService.update(dept); return update; } }
サービス層対応コード:
@Service public class DeptService { @Resource private DeptMapper deptMapper; //当存储的value类型为对象类型使用redisTemplate //存储的value类型为字符串。StringRedisTemplate @Autowired private RedisTemplate redisTemplate; //业务代码 public Dept findById(Integer id){ ValueOperations forValue = redisTemplate.opsForValue(); //查询缓存 Object o = forValue.get("dept::" + id); //缓存命中 if(o!=null){ return (Dept) o; } Dept dept = deptMapper.selectById(id); if(dept!=null){ //存入缓存中 forValue.set("dept::"+id,dept,24, TimeUnit.HOURS); } return dept; } public int deleteById(Integer id){ redisTemplate.delete("dept::"+id); int i = deptMapper.deleteById(id); return i; } public Dept insert(Dept dept){ int insert = deptMapper.insert(dept); return dept; } public Dept update(Dept dept){ redisTemplate.delete("dept::"+dept.getId()); int i = deptMapper.updateById(dept); return dept; } }
設定ソース:
# データ ソースの構成
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mydb ?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
#sql log
mybatis-plus.configuration.log-impl=org.apache.ibatis .logging.stdout.StdOutImpl
#redis に接続
spring.redis.host=192.168.22*.1**
spring.redis.port=6379
キャッシュを表示: コードの最初の部分は同じ @before 通知であり、コードの 2 番目の部分も同じ post 通知です。 AOP を使用して、キャッシュ コードとビジネス コードを分離できます。
Spring フレームワークでもそれを考えることができるはずです。 --これは注釈を使用して行うことができます。注釈を解析します。
1.3.2 構成クラスを使用する
(1) キャッシュされた構成クラスを追加します
@Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解决乱码的问题),过期时间600秒 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) //缓存过期10分钟 ---- 业务需求。 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置key的序列化方式 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) //设置value的序列化 .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager;
(2) キャッシュ有効化アノテーションを使用します
//业务代码 //使用查询注解:cacheNames表示缓存的名称 key:唯一标志---dept::key //先从缓存中查看key为(cacheNames::key)是否存在,如果存在则不会执行方法体,如果不存在则执行方法体并把方法的返回值存入缓存中 @Cacheable(cacheNames = {"dept"},key="#id") public Dept findById(Integer id){ Dept dept = deptMapper.selectById(id); return dept; } //先删除缓存在执行方法体。 @CacheEvict(cacheNames = {"dept"},key = "#id") public int deleteById(Integer id){ int row = deptMapper.deleteById(id); return row; } //这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。 @CachePut(cacheNames = "dept",key="#dept.id") public Dept update(Dept dept){ int insert = deptMapper.updateById(dept); return dept; }2. 分散ロックストレス テスト ツールを使用して、同時実行性の高さによって引き起こされるスレッドの安全性の問題をテストします2.1 ストレステストツールの使用
##内部構成:
2.2 インベントリ項目
2.2.1 コントローラー層
@RestController @RequestMapping("bucket") public class BucketController { @Autowired private BucketService bucketService; @GetMapping("update/{productId}") public String testUpdate(@PathVariable Integer productId){ String s = bucketService.updateById(productId); return s; } }
2.2.2 dao 層
//此处写就不需要在启动类使用注解 @Mapper public interface BucketMapper extends BaseMapper<Bucket> { public Integer updateBucketById(Integer productId); }
2.2.3 エンティティ層
@Data @AllArgsConstructor @NoArgsConstructor public class Bucket { @TableId(value = "productId",type = IdType.AUTO) private Integer productId; private Integer num; }
2.2.4 サービス層
@Service public class BucketService { @Resource private BucketMapper bucketMapper; public String updateById(Integer productId){ //查看该商品的库存数量 Bucket bucket = bucketMapper.selectById(productId); if(bucket.getNum()>0){ //修改库存每次减1 Integer integer = bucketMapper.updateBucketById(productId); System.out.println("扣减成功!剩余库存数:"+(bucket.getNum()-1)); return "success"; }else { System.out.println("扣减失败!库存数不足"); return "fail"; } } }
2.2.5 マッパー
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.qy151wd.dao.BucketMapper"> <update id="updateBucketById" parameterType="int"> update bucket set num=num-1 where productId=#{productId} </update> </mapper>
2.2 .6 依存関係
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--连接数据源--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--mp的依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.2.7 テスト結果
同じインベントリが n 回使用されていることがわかります。そしてデータベース内の在庫はマイナスです。スレッドの安全性の問題が原因です。
2.3 解決策
2.3.1 同期ロックまたはロック ロックを使用する
対応するサービス レイヤーは
@Service public class BucketService { @Resource private BucketMapper bucketMapper; public String updateById(Integer productId){ //加自动锁 synchronized (this){ //查看该商品的库存数量 Bucket bucket = bucketMapper.selectById(productId); if(bucket.getNum()>0){ //修改库存每次减1 Integer integer = bucketMapper.updateBucketById(productId); System.out.println("扣减成功!剩余库存数:"+(bucket.getNum()-1)); return "success"; }else { System.out.println("扣减失败!库存数不足"); return "fail"; } } } }
に変更されますプロジェクト クラスターが構築されると、ロックが無効です。
#2.3.2 redisTemplate の使用##(1) idea を使用してクラスター プロジェクトを開きます
(4) 解決策
@Service public class BucketService { @Resource private BucketMapper bucketMapper; @Autowired private RedisTemplate redisTemplate; public String updateById(Integer productId){ ValueOperations<String,String> forValue = redisTemplate.opsForValue(); Boolean flag = forValue.setIfAbsent("aaa::" + productId, "-----------------"); if(flag){ try{ //查看该商品的库存数量 Bucket bucket = bucketMapper.selectById(productId); if(bucket.getNum()>0){ //修改库存每次减1 Integer integer = bucketMapper.updateBucketById(productId); System.out.println("扣减成功!剩余库存数:"+(bucket.getNum()-1)); return "success"; }else { System.out.println("扣减失败!库存数不足"); return "fail"; } }finally { redisTemplate.delete("aaa::"+productId); } } return "服务器正忙,请稍后再试......."; } }

圧力テスト後の結果は次のとおりです:
以上がJava Redisの使用シナリオの分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

Javaはプラットフォーム固有の問題をどのように軽減しますか? Javaは、JVMおよび標準ライブラリを通じてプラットフォームに依存します。 1)bytecodeとjvmを使用して、オペレーティングシステムの違いを抽象化します。 2)標準のライブラリは、パスクラス処理ファイルパス、CHARSETクラス処理文字エンコードなど、クロスプラットフォームAPIを提供します。 3)最適化とデバッグのために、実際のプロジェクトで構成ファイルとマルチプラットフォームテストを使用します。

java'splatformentencentenhancesmicroservicesecturectureby byofferingdeploymentflexability、一貫性、スケーラビリティ、およびポート可能性。1)展開の展開の展開は、AllosmicRoserviThajvm.2)deploymentflexibility lowsmicroserviceSjvm.2)一貫性のあるAcrossServicessimplisimpligiessdevelisementand

Graalvmは、Javaのプラットフォームの独立性を3つの方法で強化します。1。言語間の相互運用性、Javaが他の言語とシームレスに相互運用できるようにします。 2。独立したランタイム環境、graalvmnativeimageを介してJavaプログラムをローカル実行可能ファイルにコンパイルします。 3.パフォーマンスの最適化、Graalコンパイラは、Javaプログラムのパフォーマンスと一貫性を改善するための効率的なマシンコードを生成します。

aeffectivelytestjavaapplicationsforformcompativity、followthesesteps:1)setupautomatedacrossmultipleplatformsusingsingcitoolslikejenkinsorgithubactions.2)divivisonmanualtingonrealhardwaretocatissusuessususus.3)

Javaコンパイラは、ソースコードをプラットフォームに依存しないバイトコードに変換することにより、Javaのプラットフォームの独立性を実現し、JVMがインストールされた任意のオペレーティングシステムでJavaプログラムを実行できるようにします。

bytecodeachievesplatformedentencedexedectedbyavirtualMachine(VM)、forexApplev.forexample、javabytecodecanrunrunrunnonydevicewithajvm、writeonce、runany "ferfuctionality.whilebytecodeOffersenhの可能性を承認します

Javaは100%のプラットフォームの独立性を達成することはできませんが、そのプラットフォームの独立性はJVMとBytecodeを通じて実装され、コードが異なるプラットフォームで実行されるようにします。具体的な実装には、次のものが含まれます。1。bytecodeへのコンパイル。 2。JVMの解釈と実行。 3。標準ライブラリの一貫性。ただし、JVMの実装の違い、オペレーティングシステムとハードウェアの違い、およびサードパーティライブラリの互換性は、プラットフォームの独立性に影響を与える可能性があります。

Javaは、「Write onse、Averywhere」を通じてプラットフォームの独立性を実現し、コードの保守性を向上させます。 2。メンテナンスコストが低いため、1つの変更のみが必要です。 3.チームのコラボレーション効率が高く、知識共有に便利です。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 中国語版
中国語版、とても使いやすい

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









