Spring MVC 知识点疏理

2017-08-29  本文已影响19人  晨之宁

1. Redis 存储方式

Redis存储机制分成两种Snapshot 和 AOF。无论是那种机制,Redis都是将数据存储在内存中。

Snapshot工作原理: 是将数据先存储在内存,然后当数据累计达到某些设定的伐值的时候,就会触发一次DUMP操作,将变化的数据一次性写入数据文件(RDB文件)。

AOF 工作原理 : 是将数据也是先存在内存,但是在存储的时候会使用调用fsync来完成对本次写操作的日志记录,这个日志揭露文件其实是一个基于Redis网络交互协议的文本文件。AOF调用fsync也不是说全部都是无阻塞的,在某些系统上可能出现fsync阻塞进程的情况,对于这种情况可以通过配置修改,但默认情况不要修改。AOF最关键的配置就是关于调用fsync追加日志文件的平率,有两种预设频率,always每次记录进来都添加,everysecond 每秒添加一次。两个配置各有所长后面分析。由于是采用日志追加的方式来持久话数据,所以引出了第二个日志的概念:rewrite. 后面介绍它的由来。

存储模式性能和安全比较:

1.性能:Snapshot方式的性能是要明显高于AOF方式的,原因有两点:

Snapshot采用2进制方式存储数据,数据文件比较小,加载快速.
存储的时候是按照配置中的save策略来存储,每次都是聚合很多数据批量存储,写入的效率很好

而AOF则一般都是工作在实时存储或者准实时模式下。相对来说存储的频率高,效率却偏低。

2.数据安全:AOL数据安全性高于Snapshot存储,原因:

Snapshot存储是基于累计批量的思想,也就是说在允许的情况下,累计的数据越多那么写入效率也就越高,但数据的累计是靠时间的积累完成的,那么如果在长时间数据不写入RDB,但Redis又遇到了崩溃,那么没有写入的数据就无法恢复了,但是AOF方式偏偏相反,根据AOF配置的存储频率的策略可以做到最少的数据丢失和较高的数据恢复能力。
说完了性能和安全,这里不得不提的就是在Redis中的Rewrite的功能,AOF的存储是按照记录日志的方式去工作的,那么成千上万的数据插入必然导致日志文件的扩大,Redis这个时候会根据配置合理触发Rewrite操作,所谓Rewrite就是将日志文件中的所有数据都重新写到另外一个新的日志文件中,但是不同的是,对于老日志文件中对于Key的多次操作,只保留最终的值的那次操作记录到日志文件中,从而缩小日志文件的大小。这里有两个配置需要注意:

auto-aof-rewrite-percentage 100 (当前写入日志文件的大小占到初始日志文件大小的某个百分比时触发Rewrite)
auto-aof-rewrite-min-size 64mb (本次Rewrite最小的写入数据良)

两个条件需要同时满足。

2.Redis 对于HashMap的存储方式

Redis不支持Java的HashMap,Redis有自己的数据结构
但可以使用Jedis (Jedis是redis的java版本的客户端实现) 来处理HashMap

 /**
  * redis操作Map
  */
 @Test
 public void testMap() {
     //-----添加数据----------  
     Map<String, String> map = new HashMap<String, String>();
     map.put("name", "xinxin");
     map.put("age", "22");
     map.put("qq", "123456");
     jedis.hmset("user",map);
     //取出user中的name,执行结果:[minxr]-->注意结果是一个泛型的List  
     //第一个参数是存入redis中map对象的key,后面跟的是放入map中的对象的key,后面的key可以跟多个,是可变参数  
     List<String> rsmap = jedis.hmget("user", "name", "age", "qq");
     System.out.println(rsmap);  
     //删除map中的某个键值  
     jedis.hdel("user","age");
     System.out.println(jedis.hmget("user", "age")); //因为删除了,所以返回的是null  
     System.out.println(jedis.hlen("user")); //返回key为user的键中存放的值的个数2 
     System.out.println(jedis.exists("user"));//是否存在key为user的记录 返回true  
     System.out.println(jedis.hkeys("user"));//返回map对象中的所有key  
     System.out.println(jedis.hvals("user"));//返回map对象中的所有value 
     Iterator<String> iter=jedis.hkeys("user").iterator();  
     while (iter.hasNext()){  
         String key = iter.next();  
         System.out.println(key+":"+jedis.hmget("user",key));  
     }  
 }
 

3.Redis和Memcached的区别 - extend

所以在选择方面如果有持久方面的需求或对数据类型和处理有要求的应该选择redis。如果简单的key/value 存储应该选择memcached。

3.mysql中order by与group by的顺序

MySQL 中order by 与group by的顺序 是:
select -> from -> where -> group by -> order by

注意:group by 比order by先执行,order by不会对group by 内部进行排序,如果group by后只有一条记录,那么order by 将无效。要查出group by中最大的或最小的某一字段使用 max或min函数。
例:
select
sum(click_num) as totalnum,
max(update_time) as update_time,
count(*) as totalarticle
from
article_detail
where
userid =1
group by
userid
order by
update_time
desc

4.MyBatis和Hibernate相比,优势在哪里?

Hibernate优势

Mybatis优势

MyBatis+MySQL 返回插入对象的主键ID

需求:使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值。

useGeneratedKeys="true":设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。(适用于MySQL、sqlserver数据库,Oracle不能使用,使用selectkey子节点做)

keyProperty="userId":赋值的对象的属性名称。
添加完成后,直接根据对象属性取值

<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="userId"
parameterType="com.chenzhou.mybatis.User">  
    insert into user(userName,password,comment)  
    values(#{userName},#{password},#{comment})  
</insert>  

如上所示,我们在insert中指定了keyProperty="userId",其中userId代表插入的User对象的主键属性。

User.java


public class User {  
    private int userId;  
    private String userName;  
    private String password;  
    private String comment;  
      
    //setter and getter  
}  

UserDao.java

public interface UserDao {  
  
    public int insertAndGetId(User user);  
  
}  

测试:

User user = new User();  
user.setUserName("chenzhou");  
user.setPassword("xxxx");  
user.setComment("测试插入数据返回主键功能");  
  
System.out.println("插入前主键为:"+user.getUserId());  
userDao.insertAndGetId(user);//插入操作  
System.out.println("插入后主键为:"+user.getUserId());  

输出:

插入前主键为:0  
插入后主键为:15  

查询数据库:


如上所示,刚刚插入的记录主键id为15

 <insert 
    id="insertUser"  parameterType="com.entity.user">
     insert into test (name) values (#{name})
<selectKey keyProperty="id" resultType="java.lang.Integer">      
   select LAST_INSERT_ID() as id      
</selectKey>    
</insert>

后台代码不变。
各个数据库获取方式不一样,本例根据mysql为例。其他请各自根据需要查询。

上一篇 下一篇

猜你喜欢

热点阅读