# Caching

Caching queries in my ORM system can significantly improve application performance by reducing the load on the database by caching the results of frequent queries. This is especially useful for queries that are executed multiple times with the same parameters.

**Enable caching**

Before using caching, you need to activate it in the `databaseManager`. To do this, configure the `cache` parameter in your configuration:

```typescript
const databaseManager = new DatabaseManager({
    cache: {
        type: "redis",
    },
});
```

**Example of using caching for the `users` table:**

The first query is always cached, so it takes more time than usual (especially if no cache key is specified), but subsequent queries are read from the cache, providing better performance compared to regular queries.

1. **Executing a cached query:**

   Initially, the query is executed and the result is stored in the cache with the key `users_list`. Subsequent queries with the same key will retrieve data from the cache, which speeds up performance.

```typescript
const selectUsersQueryCached = await databaseManager.queryBuilder<Users[]>()
    .select(['user_id', 'username', 'email'])
    .from('users')
    .orderBy('username', 'ASC')
    .cache({ ttl: 60000, key: 'users_list' });
```

In this example, the query is cached for 60 seconds (60000 milliseconds) with the key `users_list`.

2. **Caching without specifying a key:**

   If you do not specify a key for caching, the system automatically generates one based on the query. This provides an easy way to cache without needing unique keys.

```typescript
const selectUserQueryAutoCached = await databaseManager.queryBuilder<Users[]>()
    .select(['user_id', 'username', 'email'])
    .from('users')
    .orderBy('user_id', 'ASC')
    .cache({ ttl: 60000 });
```

In this example, we cache users without specifying a caching key.

3. **Removing a key from the cache:**

   If data in the `users` table has been changed and you need to update the cache, you can remove the key `users_list`:

```typescript
await databaseManager.eventManager.cache.clearCache('users_list');
```

This method will remove the data cached under the key `'users_list'`.

**Caching Parameters**

The caching configuration in `databaseManager` includes the following parameters:

```typescript
cache?: {
    type: CacheType;
    options: CacheOptions;
};
```

**CacheType**

Defines the type of cache supported, which in this case is `'redis'`.

**CacheOptions**

Options for connecting to Redis include:

* `url?: string` — URL to the Redis server.
* `username?: string` — Username for connecting to Redis.
* `password?: string` — Password for connecting to Redis.
* `name?: string` — Name of the Redis database.
* `database?: number` — Number of the Redis database.
* `socket?:` — Socket settings for connecting to Redis:
  * `connectTimeout?: number` — Connection timeout duration.
  * `noDelay?: boolean` — Disables delays in sending data.
  * `keepAlive?: number | false` — Settings for keeping the connection alive.
  * `reconnectStrategy?: false | number | ((retries: number, cause: Error) => false | Error | number)` — Reconnection strategy.
  * `tls?: any` — TLS settings for secure connection.

These parameters allow you to configure the connection to Redis according to your needs.

Query caching in my ORM helps effectively reduce database load and improve query execution speed. Configuring caching through Redis involves setting TTL and keys for storing results. There is also an option to cache without specifying a cache key. With clearly defined parameters for connecting to Redis, you can easily manage the cache and ensure optimal performance for your system.
