缓存和日志的设置和使用

缓存(cache-面试会问)

什么是缓存:

缓存中存储的是数据,目的是让查询更快

缓存使用总结:

1 每一次查询都先从缓存查询

2 如果查到直接返回

3 如果缓存中没有查到该数据,就建立连接,查询数据库

4 查询完数据库,再放入缓存,再相应给前端

5 后续每一次查询,重复上面步骤

6 增删改都会清空一二级缓存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z2AbdgSB-1663858128223)(day54_mybatis.assets/image-20220922111311472.png)]

缓存的好处:减少数据库查询次数,从而减少响应时间,减少对数据库的查询

mybatis的缓存

mybatis本身是支持缓存,而且提供两种缓存级别,一级缓存二级缓存.默认开启一级缓存.

一级缓存

演示如下: 同一个数据查询两次,第二次直接从缓存拿数据,并没有发生SQL

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4pT0ccij-1663858128224)(D:/%E5%8D%83%E5%B3%B0%E4%B8%8A%E8%AF%BE/Every%20Day%20Stage3/day54/code/day54_mybatis.assets/image-20220922111021040.png)]

一级缓存是SqlSession级别.同一个SqlSession得到mapper中的数据会进入SqlSession级别的缓存.

同一个SqlSession演示,会命中缓存

   @Test
    public void hello() throws IOException {

        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession( );

        // 同一个SQLsession下的mapper,会命中缓存
        UserMapper mapper1 = sqlSession.getMapper(UserMapper.class);
        UserMapper mapper2= sqlSession.getMapper(UserMapper.class);

        // 第一次查询
        User user1 = mapper1.findUserById(29);
        System.out.println(user1 );
        System.out.println("-------------------" );

        // 第二次查询
        User user2 = mapper2.findUserById(29);
        System.out.println(user2 );
    }

不同SqlSession演示

    @Test
    public void hello() throws IOException {

        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 得到1号sessio
        SqlSession sqlSession1 = sqlSessionFactory.openSession( );

        // 得到2号session
        SqlSession sqlSession2 = sqlSessionFactory.openSession( );

        // 同一个SQLsession下的mapper,会命中缓存
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper mapper2= sqlSession2.getMapper(UserMapper.class);

        // 第一次查询
        User user1 = mapper1.findUserById(29);
        System.out.println(user1 );
        System.out.println("-------------------" );

        // 第二次查询
        User user2 = mapper2.findUserById(29);
        System.out.println(user2 );
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fxDfsQHB-1663858128225)(D:/%E5%8D%83%E5%B3%B0%E4%B8%8A%E8%AF%BE/Every%20Day%20Stage3/day54/code/day54_mybatis.assets/image-20220922112015277.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7hu2lXMC-1663858128225)(D:/%E5%8D%83%E5%B3%B0%E4%B8%8A%E8%AF%BE/Every%20Day%20Stage3/day54/code/day54_mybatis.assets/image-20220922112204946.png)]

演示: 增删改后,会清空缓存

    @Test
    public void hello() throws IOException {

        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession1 = sqlSessionFactory.openSession( );

        // 同一个SQLsession下的mapper,会命中缓存
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper mapper2 = sqlSession1.getMapper(UserMapper.class);

        // 第一次查询
        User user1 = mapper1.findUserById(29);
        System.out.println(user1 );
        System.out.println("-------------------" );

        
        User user = new User( );
        user.setId(29);
        user.setUsername("腾飞");
        user.setPassword("123456");
        // 执行一次更新,会清空缓存
        mapper1.updateUserById(user);
        sqlSession1.commit();
        System.out.println("-------------------" );
        // 第二次查询,因为缓存被清空,要重新查数据库
        User user2 = mapper2.findUserById(29);
        System.out.println(user2 );
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wkl4vRXH-1663858128226)(D:/%E5%8D%83%E5%B3%B0%E4%B8%8A%E8%AF%BE/Every%20Day%20Stage3/day54/code/day54_mybatis.assets/image-20220922112704296.png)]

思考题: 缓存是使用什么结构存储的? 存储的key是什么? value是什么?

二级缓存

二级缓存是Mapper级别,比SqlSession级别要大.通过同一个Mapper文件得到SqlSession都可以共享数据.但是需要手动开启.

开启步骤:

1 mybatis-config.xml设置开启缓存

    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

2 Mapper.xml中指定缓存类型

    <!--  设置缓存的实现类  
	 默认是PerpetualCache来实现缓存
        ps: 此处可以指定其他类来实现缓存,例如EHCache
    -->
    <cache />
    @Test
    public void hello() throws IOException {

        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 得到1号SqlSession
        SqlSession sqlSession1 = sqlSessionFactory.openSession( );

        // 得到2号SqlSession
        SqlSession sqlSession2 = sqlSessionFactory.openSession( );

        // 得到3号SqlSession
        SqlSession sqlSession3 = sqlSessionFactory.openSession( );

        // 同一个SQLsession下的mapper,会命中缓存
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
        UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);

        // 第一次查询
        User user1 = mapper1.findUserById(29);
        System.out.println(user1 );
        System.out.println("-------------------" );
        // 关流时,才会将数据放入缓存
        sqlSession1.close();


        System.out.println("-------------------" );
        // 第二次查询
        User user2 = mapper2.findUserById(29);
        System.out.println(user2 );
        // 关流时,才会将数据放入缓存
        sqlSession2.close();


        System.out.println("-------------------" );
        // 第三次查询
        User user3 = mapper3.findUserById(29);
        System.out.println(user3 );
        // 关流时,才会将数据放入缓存
        sqlSession3.close();
    }

注意:二级缓存时要将实体类系列化否则报错

Cause: java.io.NotSerializableException

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cqA5LFJF-1663858128226)(D:/%E5%8D%83%E5%B3%B0%E4%B8%8A%E8%AF%BE/Every%20Day%20Stage3/day54/code/day54_mybatis.assets/image-20220922151013626.png)]

演示: 增删改会清空缓存

    @Test
    public void hello() throws IOException {

        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 得到1号SqlSession
        SqlSession sqlSession1 = sqlSessionFactory.openSession( );

        // 得到2号SqlSession
        SqlSession sqlSession2 = sqlSessionFactory.openSession( );

        // 得到3号SqlSession
        SqlSession sqlSession3 = sqlSessionFactory.openSession( );

        // 同一个SQLsession下的mapper,会命中缓存
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
        UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);

        // 第一次查询
        User user1 = mapper1.findUserById(29);
        System.out.println(user1 );
        System.out.println("-------------------" );
        // 关流时,才会将数据放入缓存
        sqlSession1.close();


        System.out.println("-------------------" );
        // 第二次查询
        User user2 = mapper2.findUserById(29);
        System.out.println(user2 );

        // 执行更新
        User user = new User( );
        user.setId(29);
        user.setUsername("腾飞");
        user.setPassword("123456");

        int i = mapper2.updateUserById2(user);
        System.out.println(i );

        sqlSession2.commit();
        sqlSession2.close();

        System.out.println("-------------------" );
        // 第三次查询
        User user3 = mapper3.findUserById(29);
        System.out.println(user3 );
        // 关流时,才会将数据放入缓存
        sqlSession3.close();
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z0FuFOQq-1663858128227)(D:/%E5%8D%83%E5%B3%B0%E4%B8%8A%E8%AF%BE/Every%20Day%20Stage3/day54/code/day54_mybatis.assets/image-20220922151546984.png)]

面试问:$和#的区别

使用#

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JfRztIRH-1663858128228)(D:/%E5%8D%83%E5%B3%B0%E4%B8%8A%E8%AF%BE/Every%20Day%20Stage3/day54/code/day54_mybatis.assets/image-20220922155116760.png)]

使用$

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fxRJ1io3-1663858128229)(D:/%E5%8D%83%E5%B3%B0%E4%B8%8A%E8%AF%BE/Every%20Day%20Stage3/day54/code/day54_mybatis.assets/image-20220922155245304.png)]

总结:

{} 相当于是预处理语句,会将#换成占位符,字符串等数据赋值时自动拼接引号,可以避免SQL注入

${} 相当于是处理语句,直接原样将数据取出,容易造成SQL注入

复习JDBCSQL注入部分

Log4j使用(了解)

1 使用log4j将日志输出到本地磁盘文件

1 log4j.properties文件中设置输出到本地的磁盘的模板

2 指定使用这套模板

log4j.logger.com.qf.mapper=debug,B

# 将日志输出到本地磁盘
log4j.appender.B = org.apache.log4j.DailyRollingFileAppender
log4j.appender.B.File = E://000_J_A_V_A//Java2212//第三阶段//day54//mybatis.log
log4j.appender.B.Append = true
log4j.appender.B.Threshold = DEBUG 
log4j.appender.B.layout = org.apache.log4j.PatternLayout
log4j.appender.B.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss} method:%l%n%m%n

2 使用log4j将日志输出到mysql表[了解]

准备一张表存储日志,这张表包括但不限于日志级别,线程名,时间,方法名,日志信息等等

CREATE TABLE `log` (
  `log_id` int(11) NOT NULL AUTO_INCREMENT,
  `project_name` varchar(255) DEFAULT NULL COMMENT '目项名',
  `create_date` varchar(255) DEFAULT NULL COMMENT '创建时间',
  `level` varchar(255) DEFAULT NULL COMMENT '优先级',
  `category` varchar(255) DEFAULT NULL COMMENT '所在类的全名',
  `file_name` varchar(255) DEFAULT NULL COMMENT '输出日志消息产生时所在的文件名称 ',
  `thread_name` varchar(255) DEFAULT NULL COMMENT '日志事件的线程名',
  `line` varchar(255) DEFAULT NULL COMMENT '号行',
  `all_category` varchar(255) DEFAULT NULL COMMENT '日志事件的发生位置',
  `message` varchar(4000) DEFAULT NULL COMMENT '输出代码中指定的消息',
  PRIMARY KEY (`log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

设置properties文件,给定一个输出到mysql的模板

log4j.logger.com.qf.mapper=debug,logDB

### 输出到mysql
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver=com.mysql.jdbc.Driver
log4j.appender.logDB.URL=jdbc:mysql://localhost:3306/java2212
log4j.appender.logDB.User=root
log4j.appender.logDB.Password=123456
log4j.appender.logDB.Sql=INSERT INTO log(project_name,create_date,level,category,file_name,thread_name,line,all_category,message) values('day54_mybatis','%d{yyyy-MM-ddHH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

测试使用

3 自己的代码中使用log4j记录日志

以前是写输出语句调试代码,不灵活,只能输出到控制台,格式不固定等等都是毛病.

使用思路: 以前写sout的地方,现在就使用log4j记录

package com.qf;

import org.apache.log4j.Logger;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class UserServiceImpl {

    // 1 获得日志对象
    private static Logger logger = Logger.getLogger(UserServiceImpl.class);

    public void testLog(){

        // 2使用日志对象记录日志
        logger.debug("DEBUG-查询返回对象User");
        logger.info("info-查询返回对象User");
        logger.warn("warn-查询返回对象User");
        
        try {
            
        }catch (Exception e){
            logger.error(e.getMessage());
        }

    }
}

gger(UserServiceImpl.class);

public void testLog(){

    // 2使用日志对象记录日志
    logger.debug("DEBUG-查询返回对象User");
    logger.info("info-查询返回对象User");
    logger.warn("warn-查询返回对象User");
    
    try {
        
    }catch (Exception e){
        logger.error(e.getMessage());
    }

}

}






























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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值