JavaWeb学习的第二十一天(Redis--非关系型数据库)

一、Redis基础知识学习

1.缓存的引入

1.1 当我们直接使用mysql时,要考虑高并发的问题,当很多人同一个时间段内访问数据库时会给数据库造成极大的压力
1.2 缓存:减少数据库访问次数(利用空间换时间)
1.3 使用缓存的出现的问题:数据同步
1.4 可用的解决方式:只要有任何增删改的操作就清空缓冲(但是不建议)
1.5 使用缓存场景:数据经常查询,增删改比较少
1.5 redis作用:用来做缓存用的

2.Redis的概念

Redis(全称:Remote Dictionary Server 远程字典服务)
2.1 开源、免费、高性能、非关系型数据库
2.2 可基于内存亦可持久化的日志型、Key-Value数据库
2.3 Redis的默认端口:6379

关系型数据库(mysql)和非关系型数据库(redis)的区别

关系型数据库:既可以存储数据,又可以存储数据与数据之间的关系
sql:结构化查询语言去操作关系型数据库
  User表
	id|username|password
	1 |  tom   | 123
	2 | jerry  | 456
	3 | color7 | 789
  Order表
	id|money|uid
	1 |1000 | 1
	2 |2000 | 1
	3 |1200 | 2
存储数据关系解释:
1.在User表中,单个的id username password的数据并没有意义,而关系型数据库就可以将这些毫无关系的数据联系起来,变成一个有意义的数据--用户信息
2.在多表连接中,我们可以通过Order表的uid去找到User表的id,然后两种表就可以产生联系
非关系型数据库:只能存储数据,不能存储数据与数据之间的联系
不能使用sql语言去操作这种类型的数据库,只能通过命令行的形式去操作
id:1
username:tom
password:123
二、Redis的安装和启动

1.Redis下载地址

1.1 官网:https://redis.io/
1.2 百度网盘下载地址
	链接:https://pan.baidu.com/s/1LVH3sCE9sMos8EXJ3oHBWg 
	提取码:fwlr 
	复制这段内容后打开百度网盘手机App,操作更方便哦

2.直接解压即可使用

3.点击redis-server.exe启动服务,服务启动后不要关闭窗口


4.点击redis-cli.exe启动客户端

三、Redis的使用

1.Redis的特点

1.1 数据默认都是存储在内存中的 
1.2 以key-value键值对形式存储的

2.Redis通过key-value存储数据

2.1 key是固定的字符串类型   
2.2 value有五种数据类型(数据结构)
	string(字符串)
	hash(哈希)
	list(列表)
	set(集合)
	zset(sorted set:有序集合)

3.Redis文档:https://www.runoob.com/redis/redis-backup.html

4.Redis命令






四、Redis的持久化

1.什么是持久化

redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中(备份)。

2.Redis持久化机制

1. RDB:默认方式,不需要进行配置,默认就使用这种机制
    * 在一定的间隔时间中,检测key的变化情况,然后持久化数据
    1. 编辑redis.windwos.conf文件
        #   after 900 sec (15 min) if at least 1 key changed
        save 900 1
        #   after 300 sec (5 min) if at least 10 keys changed
        save 300 10
        #   after 60 sec if at least 10000 keys changed
        save 60 10000
        
    2. 重新启动redis服务器,并指定配置文件名称
        redis-2.8.9>redis-server.exe redis.windows.conf    
    
2. AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
    1. 编辑redis.windwos.conf文件
        appendonly no(关闭aof) --> appendonly yes (开启aof)
        # appendfsync always : 每一次操作都进行持久化
        # appendfsync everysec : 每隔一秒进行一次持久化
        # appendfsync no     : 不进行持久化

3.Redis的事务命令

redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED
redis 127.0.0.1:6379> GET book-name
QUEUED
redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED
redis 127.0.0.1:6379> SMEMBERS tag
QUEUED

redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
   2) "C++"
   3) "Programming"
五、Jedis:java操作redis的客户端,类似于jdbc

1.导入依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.7.2</version>
</dependency>

2.创建jedis客户端

//1.创建redis的连接对象
	Jedis jedis = new Jedis("localhost",6379);
//2.通过连接操作redis
	jedis.set("name","fox");
	String value = jedis.get("name");
	System.out.println(value);
//3.释放ziyuan
	jedis.close();

3.maven-java项目的redis效果演示


六、Jedis工具类

1.在resources中新建一个jedis.properties

jedis.host=localhost   
jedis.port=6379
jedis.maxIdle=5000
jedis.maxTotal=50
jedis.maxWaitMillis=50

2.新建一个JedisUtils的工具类

package com.bianyiit.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.util.Properties;

/**
 * 获取连接池,直接从连接池中获取连接
 */
public class JedisUtils {
    private static JedisPool jedisPool;
    static {
        Properties properties = new Properties();
        try {
            properties.load(JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(Integer.parseInt(properties.getProperty("jedis.maxIdle")));
        jedisPoolConfig.setMaxTotal(Integer.parseInt(properties.getProperty("jedis.maxTotal")));
        jedisPoolConfig.setMaxWaitMillis(Integer.parseInt(properties.getProperty("jedis.maxWaitMillis")));
        String host = properties.getProperty("jedis.host");
        int port = Integer.parseInt(properties.getProperty("jedis.port"));
        jedisPool=new JedisPool(jedisPoolConfig,host,port);
    }

    /**
     * 获取jedis连接池
     * @return
     */
    public static JedisPool getJedisPool(){
        return jedisPool;
    }

    /**
     * 获取jedis连接对象
     * @return
     */
    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

3.测试JedisUtils是否正确


4.注意:Maven的控制台乱码问题解决方案

七、在maven-javaweb项目中使用Redis加快查询速度

1.配置好项目的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.bianyiit</groupId>
    <artifactId>day12_redis_role</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>day12_redis_role Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>

        <!--json转换相关依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
        </dependency>

        <!--jedis依赖-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.7.2</version>
        </dependency>

        <!--jdbcTemplate依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

        <!--druid连接池依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

        <!--数据库驱动依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>


        <!--web相关依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>


        <!--junit依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>day12_redis_role</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <!-- 指定端口 -->
                    <port>8080</port>
                    <!-- 请求路径 -->
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.在src/main/resources下创建两个配置文件

druid.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/login
username=root
password=123
initialSize=5
maxActive=10
maxWait=3000

jedis.properties

jedis.host=localhost
jedis.port=6379
jedis.maxIdle=5000
jedis.maxTotal=50
jedis.maxWaitMillis=5000

3.在src/mian/java下新建五个包

4.在util下新建两个工具类

JdbcUtils

package com.bianyiit.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JdbcUtils {
    private static DataSource dataSource;
    static {
        try {
            Properties properties = new Properties();
            InputStream is = JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            properties.load(is);
            dataSource =  DruidDataSourceFactory.createDataSource(properties);
        }catch (Exception e){

        }
    }
    /**
     * 从连接池中获取连接
     * @return
     */
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取连接池
     * @return
     */
    public static DataSource getDataSource(){
        return dataSource;
    }
}

JedisUtils

package com.bianyiit.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.util.Properties;

public class JedisUtils {
    private static JedisPool jedisPool;
    static {
        Properties properties = new Properties();
        try {
            properties.load(JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(Integer.parseInt(properties.getProperty("jedis.maxIdle")));
        jedisPoolConfig.setMaxTotal(Integer.parseInt(properties.getProperty("jedis.maxTotal")));
        jedisPoolConfig.setMaxWaitMillis(Long.parseLong(properties.getProperty("jedis.maxWaitMillis")));
        String host = properties.getProperty("jedis.host");
        int port = Integer.parseInt(properties.getProperty("jedis.port"));
        
        jedisPool = new JedisPool(jedisPoolConfig,host,port);
    }
    /**
     * 获取jedis连接池
     * @return
     */
    public static JedisPool getJedisPool(){
        return jedisPool;
    }
    /**
     * 获取jedis对象
     * @return
     */
    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

5.在WEB-INF/新建一个register.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>网站注册页面</title>
    <style>
        #contanier{
            border: 0px solid white;
            width: 1300px;
            margin: auto;
        }
        #form{
            height: 500px;
            padding-top: 70px;
            margin-bottom: 10px;
        }
        a{
            text-decoration: none;
        }
       .error{
            font-family:georgia;
            font-size: 15px;
            font-style: normal;
            color: red;
        }
        #father{
            border: 0px solid white;
            padding-left: 307px;
        }
        #form2{
            border: 5px solid gray;
            width: 660px;
            height: 450px;
        }
    </style>
    <script type="text/javascript" src="./js/jquery-1.11.0.min.js" ></script>
    <script>
        /**
         * 校验用户名是否可用
         *  1.给用户名输入框注册失去焦点的事件
         *  2.获取用户输入的用户名
         *  3.将用户输入的用户名传递到服务器
         */
        $(function () {
            $.get("/findAll",{},function (data) {
                for (let i = 0; i < data.length; i++) {
                    var option = "<option>"+data[i].username+"</option>"
                    $("#role_list").append(option)
                }
            });
            $("#btn_form").click(function () {
                for (let j = 0; j < 3000; j++) {
                    $.get("/findAll?time="+new Date().getTime(),{},function (data) {})
                }
            })
        })
    </script>
</head>
<body>
<div id="contanier">
    <div id="form">
        <form action="#" method="get" id="registForm">
            <div id="father">
                <div id="form2">
                    <table border="0px" width="100%" height="100%" align="center" cellpadding="0px" cellspacing="0px" bgcolor="white">
                        <tr align="center">
                            <td colspan="2" >
                                <font size="5">会员注册</font>&nbsp;&nbsp;&nbsp;
                            </td>
                        </tr>
                        <tr align="center" >
                            <td colspan="2" >
                                <div id="error_msg" style="display: none" class="error">错误信息</div>&nbsp;&nbsp;&nbsp;
                            </td>
                        </tr>
                        <tr align="center">
                            <td width="180px">
                                <label for="user" >用户名</label>
                            </td>
                            <td>
                                <em style="color: red;">*</em>&nbsp;&nbsp;&nbsp;
                                <input type="text" name="username" size="35px" id="user"/>
                                <span id="errorMsg_username"></span>
                            </td>
                        </tr>
                        <tr align="center">
                            <td>
                                密码
                            </td>
                            <td>
                                <em style="color: red;">*</em>&nbsp;&nbsp;&nbsp;
                                <input type="password"  name="password" size="35px" id="password" />
                                <span id="errorMsg_password"></span>
                            </td>
                        </tr>
                        <tr align="center">
                            <td>
                                确认密码
                            </td>
                            <td>
                                <em style="color: red;">*</em>&nbsp;&nbsp;&nbsp;
                                <input type="password" name="repassword" size="35px"/>
                            </td>
                        </tr>
                        <tr align="center">
                            <td>
                                Email
                            </td>
                            <td>
                                <em style="color: red;">*</em>&nbsp;&nbsp;&nbsp;
                                <input type="text" name="email" size="35px" id="email"/>
                            </td>
                        </tr>
                        <tr align="center">
                            <td>
                                用户角色
                            </td>
                            <td>
                                <em style="color: red;">*</em>&nbsp;&nbsp;&nbsp;
                                <select id="role_list">
                                    <option>--请求选择--</option>
                                </select>
                            </td>
                        </tr>
                        <tr align="center">
                            <td>
                                姓名
                            </td>
                            <td>
                                <em style="color: red;">*</em>&nbsp;&nbsp;&nbsp;
                                <input type="text" name="username" size="35px"/>
                            </td>
                        </tr>
                        <tr align="center">
                            <td>
                                性别
                            </td>
                            <td>
                                <span style="margin-right: 155px;">
                                    <em style="color: red;">*</em>&nbsp;&nbsp;&nbsp;
                                    <input type="radio" name="sex" value="男"/>男
                                    <input type="radio" name="sex" value="女"/>女<em></em>
                                </span>
                            </td>
                        </tr>
                        <tr  align="center">
                            <td>
                                出生日期
                            </td>
                            <td>
                                <em style="color: red;">*</em>&nbsp;&nbsp;&nbsp;
                                <input type="text" name="birthday"  size="35px"/>
                            </td>
                        </tr>
                        <tr  align="center">
                            <td colspan="2">
                                <input id="btn_form" type="button" value="注      册" height="50px"/>
                            </td>
                        </tr>
                    </table>
                </div>
            </div>
        </form>
    </div>
</div>
</body>
</html>

6.在domain下新建一个Role类

package com.bianyiit.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;

public class Role {
    private int id;
    private String username;
    /*忽略这个字段,在转json字符串的时候,加上这个注解的字段不会被转换到json中*/
    @JsonIgnore
    private String password;
    /*设置当前当前字段转换的一个基本日期格式*/
    @JsonFormat(pattern="yyyy-MM-dd")
    private String birthday;
    private String sex;
    private String email;

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

7.在web下创建FindAllServlet

package com.bianyiit.web;

import com.bianyiit.services.RoleService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/findAll")
public class FindAllServlet extends HttpServlet {
    RoleService roleService  = new RoleService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        String roleList = roleService.findAll();
        response.getWriter().println(roleList);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

8.在service下创建一个RoleService

package com.bianyiit.services;

import com.bianyiit.dao.RoleDao;
import com.bianyiit.domain.Role;
import com.bianyiit.util.JedisUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.Jedis;

import java.util.List;

public class RoleService {

    int i = 0;
    public String findAll() {
        Jedis jedis = JedisUtils.getJedis();
        String roleList_json = jedis.get("roleList");

        if (roleList_json== null || roleList_json.length()==0){
            System.out.println("调用dao从数据库查询所有角色");
            List<Role> roleList = new RoleDao().findAll();

            ObjectMapper mapper = new ObjectMapper();
            try {
                roleList_json = mapper.writeValueAsString(roleList);
                jedis.set("roleList", roleList_json);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }else {
            System.out.println("从redis中获取数据" + i++);
        }
        jedis.close();
        return roleList_json;
    }
}

9.在dao下创建RoleDao类

package com.bianyiit.dao;

import com.bianyiit.domain.Role;
import com.bianyiit.util.JdbcUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

public class RoleDao {
    public List<Role> findAll() {
        JdbcTemplate template = new JdbcTemplate(JdbcUtils.getDataSource());
        String sql = "select * from usermsg";
        List<Role> roleList = template.query(sql, new BeanPropertyRowMapper<Role>(Role.class));
        return roleList;
    }
}

10.模拟2000个用户同时访问的效果





解释:由于redis基于内存的,所以除了在第一次用户需要访问磁盘的数据库内容之外,其它的用户可以直接在内存中的redis中取出数据,而且采用了redis的线程池,它明显比直接访问数据库速度要快的多,而且不会轻易崩溃!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值