рдбреЗрдЯрд╛ рдХреИрд╢рд┐рдВрдЧ - рдЬрд╛рд╡рд╛ рд╕реНрдкреНрд░рд┐рдВрдЧ

рдПрдХ рд╣реА рдбреЗрдЯрд╛ рдХреЛ рдмрд╛рд░-рдмрд╛рд░ рдкрдврд╝рдиреЗ рд╕реЗ рд╕рд╡рд╛рд▓ рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдЙрдарддрд╛ рд╣реИ, рдбреЗрдЯрд╛ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ рдпрд╛ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдмрджрд▓рддрд╛ рд╣реИ, рдпреЗ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрджрд░реНрдн рдкреБрд╕реНрддрдХреЗрдВ рдФрд░ рдЕрдиреНрдп рдЬрд╛рдирдХрд╛рд░реА рд╣реИрдВ, рдЕрд░реНрдерд╛рддреНред рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдирд┐рдпрддрд╛рддреНрдордХ рд╣реИред рдпрд╣рд╛рдБ, рд╢рд╛рдпрдж рд╣рд░ рдХреЛрдИ рд╕рдордЭрддрд╛ рд╣реИ - рд╣рдореЗрдВ рдХреИрд╢ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ! рдЖрдкрдХреЛ рд╣рд░ рдмрд╛рд░ рдбреЗрдЯрд╛ рдЦреЛрдЬ рдпрд╛ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?

рддреЛ рдпрд╣рд╛рдБ рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдЬрд╛рд╡рд╛ рд╕реНрдкреНрд░рд┐рдВрдЧ рдореЗрдВ рдХреИрд╢реЗ рдХреИрд╕реЗ рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЪреВрдБрдХрд┐ рдпрд╣ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдореНрдмрджреНрдз рд╣реИ, рдлрд┐рд░ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдбреАрдмреАрдПрдордПрд╕ рдореЗрдВ рдХреИрд╕реЗ рдХрд░реЗрдВред

рд╕рд╛рдордЧреНрд░реА

  • рд╡рд╕рдВрдд рдореЗрдВ рдХреИрд╢
  • Oracle PL-SQL рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреИрд╢

рд╡рд╕рдВрдд рдореЗрдВ рдХреИрд╢


рдлрд┐рд░ рд╕рдм рдХреБрдЫ рд▓рдЧрднрдЧ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рдЖрддрд╛ рд╣реИ, рдЬрд╛рд╡рд╛ рдореЗрдВ рд╡реЗ рд╡рд┐рднрд┐рдиреНрди рд╣рд╕рдкреИрдХ, рдХреЙрдиреНрдЯреНрд░реИрдХреНрд╢рдирд▓ рдореИрдкреНрд╕ рдЗрддреНрдпрд╛рджрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд╡рд╕рдВрдд рдореЗрдВ рднреА, рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрд╛рдп рд╣реИ, рд╕рд░рд▓, рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ, рдкреНрд░рднрд╛рд╡реАред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред рдФрд░ рдЗрд╕рд▓рд┐рдП, рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХреИрд╢ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░реЗрдВ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдиреЛрдЯреЗрдЯ рдХрд░реЗрдВред

рдХреИрд╢ рдХреЛ рд╕реБрд▓рдн рдмрдирд╛рдирд╛

@SpringBootApplication @EnableCaching public class DemoCacheAbleApplication { public static void main(String[] args) { SpringApplication.run(DemoCacheAbleApplication.class, args); } } 

рдХреИрд╢ рдлрд╝рдВрдХреНрд╢рди рдЦреЛрдЬ рдбреЗрдЯрд╛

  @Cacheable(cacheNames="person") public Person findCacheByName(String name) { //... } 

рдПрдиреЛрдЯреЗрд╢рди рдХреИрд╢ рдХреЗ рдирд╛рдо рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВред рдпрд╣ рдЕрдкреЗрдХреНрд╖рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдкрд╣рд▓реА рдмрд╛рд░ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рдкрд░, рдЦреЛрдЬ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ рдХреИрд╢ рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдирд╛рдо) рдФрд░ рдмрд╛рдж рдХреЗ рдХреЙрд▓ рдЕрдм рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдбреЗрдЯрд╛ рдХреИрд╢ рд╕реЗ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдХреИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ "рд╡реНрдпрдХреНрддрд┐" рднрдВрдбрд╛рд░ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

 @Component public class PersonRepository { private static final Logger logger = LoggerFactory.getLogger(PersonRepository.class); private List<Person> persons = new ArrayList<>(); public void initPersons(List<Person> persons) { this.persons.addAll(persons); } private Person findByName(String name) { Person person = persons.stream() .filter(p -> p.getName().equals(name)) .findFirst() .orElse(null); return person; } @Cacheable(cacheNames="person") public Person findCacheByName(String name) { logger.info("find person ... " + name); final Person person = findByName(name); return person; } } 

рдореИрдВ рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдХреНрдпрд╛ рд╣реБрдЖ рдерд╛

 @RunWith(SpringRunner.class) @SpringBootTest public class DemoCacheAbleApplicationTests { private static final Logger logger = LoggerFactory.getLogger(DemoCacheAbleApplicationTests.class); @Autowired private PersonRepository personRepository; @Before public void before() { personRepository.initPersons(Arrays.asList(new Person("", 22), new Person("", 34), new Person("", 41))); } private Person findCacheByName(String name) { logger.info("begin find " + name); final Person person = personRepository.findCacheByName(name); logger.info("find result = " + person.toString()); return person; } @Test public void findByName() { findCacheByName(""); findCacheByName(""); } } 

рдЯреЗрд╕реНрдЯ рдореЗрдВ рдореИрдВ рджреЛ рдмрд╛рд░ рдлреЛрди рдХрд░рддрд╛ рд╣реВрдВ

 @Test public void findByName() { findCacheByName(""); findCacheByName(""); } 

, рдкрд╣рд▓реА рдмрд╛рд░ рдПрдХ рдХреЙрд▓, рдПрдХ рдЦреЛрдЬ, рджреВрд╕рд░реА рдмрд╛рд░ рдкрд░рд┐рдгрд╛рдо рдХреИрд╢ рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдХрдВрд╕реЛрд▓ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред

рдЫрд╡рд┐

рдЖрд╕рд╛рдиреА рд╕реЗ, рдЖрдк рдореМрдЬреВрджрд╛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдмрд┐рдВрджреБ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рддрд░реНрдХ рд╣реИрдВ, рддреЛ рдЖрдк рдкреИрд░рд╛рдореАрдЯрд░ рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред

  @Cacheable(cacheNames="person", key="#name") public Person findByKeyField(String name, Integer age) { 

рдХреБрдВрдЬреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдпреЛрдЬрдирд╛рдПрдВ рд╣реИрдВ, рдпрд╣ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╣реИред

рд▓реЗрдХрд┐рди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реЛрдЧрд╛ рдХрд┐ рдХреИрд╢ рдореЗрдВ рдбреЗрдЯрд╛ рдХреИрд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдП? рдЗрд╕ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рджреЛ рдПрдиреЛрдЯреЗрд╢рди рд╣реИрдВред

рдкрд╣рд▓рд╛ @CachePut

рдЗрд╕ рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрд╢рд╛ рдХреЛрдб рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛, рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдХреИрд╢ рдореЗрдВ рдбрд╛рд▓ рджреЗрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХреИрд╢ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдореИрдВ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рджреЛ рддрд░реАрдХреЗ рдЬреЛрдбрд╝реВрдВрдЧрд╛: рд╣рдЯрд╛рдПрдВ рдФрд░ рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдЬреЛрдбрд╝реЗрдВ

  public boolean delete(String name) { final Person person = findByName(name); return persons.remove(person); } public boolean add(Person person) { return persons.add(person); } 

рдореИрдВ рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдЦреЛрдЬ рдХрд░реВрдВрдЧрд╛, рд╣рдЯрд╛рдКрдВрдЧрд╛, рдЬреЛрдбрд╝реВрдВрдЧрд╛, рдлрд┐рд░ рд╕реЗ рдЦреЛрдЬ рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рдХреА рддрд░рд╣, рдореБрдЭреЗ рдХреИрд╢ рд╕реЗ рд╡рд╣реА рдЪреЗрд╣рд░рд╛ рдорд┐рд▓реЗрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдореИрдВ "findByNameAndPut" рдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд░рддрд╛

  @CachePut(cacheNames="person") public Person findByNameAndPut(String name) { logger.info("findByName and put person ... " + name); final Person person = findByName(name); logger.info("put in cache person " + person); return person; } 

рдХрд╕реМрдЯреА

  @Test public void findCacheByNameAndPut() { Person person = findCacheByName(""); logger.info("delete " + person); personRepository.delete(""); findCacheByName(""); logger.info("add new person"); person = new Person("", 35); personRepository.add(person); findCacheByName(""); logger.info("put new"); personRepository.findByNameAndPut(""); findCacheByName(""); } 

рдЫрд╡рд┐

рдПрдХ рдФрд░ рдПрдиреЛрдЯреЗрд╢рди рд╣реИ @CacheEvict

рдЖрдкрдХреЛ рди рдХреЗрд╡рд▓ рдХреИрд╢ рд╕рдВрдЧреНрд░рд╣рдг рдкрд░ рдЬрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдмреЗрджрдЦрд▓ рдХрд░рдиреЗ рдХреА рднреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреИрд╢ рд╕реЗ рдЕрдкреНрд░рдЪрд▓рд┐рдд рдпрд╛ рдЕрдкреНрд░рдпреБрдХреНрдд рдбреЗрдЯрд╛ рдХреЛ рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИред

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рд╕реНрдкреНрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ - рдХреИрд╢ рдХреЗ рд▓рд┐рдП рд╕рдорд╡рд░реНрддреА рдХреЗрдмрд┐рди, рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреИрд╢ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдЙрддреНрдХреГрд╖реНрдЯ рд╡рд░реНрдЧ рд╣реИ, рддреЛ рдХреИрд╢реЗрдореИрдирдЧрд░ рдореЗрдВ рдЗрд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ

 @SpringBootApplication @EnableCaching public class DemoCacheAbleApplication { public static void main(String[] args) { SpringApplication.run(DemoCacheAbleApplication.class, args); } @Bean public CacheManager cacheManager() { SimpleCacheManager cacheManager = new SimpleCacheManager(); cacheManager.setCaches(Arrays.asList( new ConcurrentMapCache("person"), new ConcurrentMapCache("addresses"))); return cacheManager; } } 

рдХреИрд╢ рдХреЗ рдирд╛рдо рднреА рд╡рд╣рд╛рдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ, рдХрдИ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред Xml рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ, рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

рд╡рд╕рдВрдд рд╡рд┐рдиреНрдпрд╛рд╕ ред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:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <cache:annotation-driven/> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="person"/> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="addresses"/> </set> </property> </bean> </beans> 


рд╡реНрдпрдХреНрддрд┐ рд╡рд░реНрдЧ
 public 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 Integer getAge() { return age; } @Override public String toString() { return name + ":" + age; } 


рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╕рдВрд░рдЪрдирд╛

рдЫрд╡рд┐

рдпрд╣рд╛рдБ pom.xml
 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demoCacheAble</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>DemoCacheAble</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 


Oracle PL-SQL рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреИрд╢


рдЦреИрд░, рдЕрдВрдд рдореЗрдВ, рдЬреЛ рд▓реЛрдЧ рдбреАрдмреАрдПрдордПрд╕ рдкрд╛рд╡рд░ рдХреА рдЙрдкреЗрдХреНрд╖рд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реНрддрд░ рдкрд░, рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдпрд╛ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╢рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдУрд░реЗрдХрд▓ рдореЗрдВ, рдЖрдк рдкрд░рд┐рдгрд╛рдо рдХреЛ рдХреИрд╢рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдПрдХ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдирд╣реАрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ
RESULT_CACHE

рдПрдХ рдЙрджрд╛рд╣рд░рдг:

 CREATE OR REPLACE FUNCTION GET_COUNTRY_NAME(P_CODE IN VARCHAR2) RETURN VARCHAR2 RESULT_CACHE IS CODE_RESULT VARCHAR2(50); BEGIN SELECT COUNTRY_NAME INTO CODE_RESULT FROM COUNTRIES WHERE COUNTRY_ID = P_CODE; --    dbms_lock.sleep (1); RETURN(CODE_RESULT); END; 

рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдмрджрд▓рдиреЗ рдХреЗ рдмрд╛рдж, рдХреИрд╢ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреИрд╢ рдирд┐рдпрдо рдХреЛ рдареАрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
RELIES_ON (...)
рд╕рд╛рдордЧреНрд░реА
рдХреИрд╢ рдПрдмреНрд╕реНрдЯреНрд░реИрдХреНрд╢рди

Source: https://habr.com/ru/post/hi427187/


All Articles