学习项目中用到的技术
Jedis、JedisCluster的使用
引入依赖包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
Jedis的使用
创建jedis对象,set方法存储key-value的值,get方法获取key对应的值,主要用于单个redis
Jedis jedis = new Jedis("192.168.56.180", 6379);
jedis.set("Jedis", "Hello Work!");
System.out.println(jedis.get("Jedis"));
jedis.close();
可以看出jedis继承BinaryJedis,实现多个接口
每个接口都代表一类redis命令,例如jedisCommands中包含了SET GET等命令,MultikeyCommands中包含了针对多个key的MSET MGET等命令
JedisCluster的使用
Jediscluster类图和jedis类图大致一样,不过jedisCluster有一些命令是不可用的。比如BinaryJedisCluster类被作废的命令。主要是用在集群中。
单个redis中API的测试
package com.xfgg.demo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;
import java.sql.Time;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@SpringBootTest
public class Standalone {
private static Jedis jedis;
static {
jedis = new Jedis("127.0.0.1",6379);
}
/**
* 测试key—value的值
*/
@Test
public void testKey() throws InterruptedException{
System.out.println("清空数据:"+jedis.flushDB());
System.out.println("判断某个key是否存在:"+jedis.exists("username"));
System.out.println("新增键值对:"+jedis.set("username","working"));
System.out.println("是否存在:"+jedis.exists("name"));
System.out.println("新增<'password','password'>的键值对:"+jedis.set("password", "password"));
Set<String> keys = jedis.keys("*");
System.out.println("系统中所有建如下:"+keys);
System.out.println("删除键password:"+jedis.del("password"));
System.out.println("判断键password是否存在:"+jedis.exists("password"));
System.out.println("设置键username的过期时间为5s:"+jedis.expire("username",5));
TimeUnit.SECONDS.sleep(2);
System.out.println("查看键username的剩余生存时间:"+jedis.ttl("username"));
System.out.println("移除键username的生存时间:"+jedis.persist("username"));
System.out.println("查看键username的剩余生存时间:"+jedis.ttl("username"));
System.out.println("查看键username所存储的值的类型:"+jedis.type("username"));
}
/**
* 字符串操作
*/
@Test
public void testString() throws InterruptedException{
System.out.println("===========增加数据===========");
System.out.println(jedis.set("key1","value1"));
System.out.println(jedis.set("key2","value2"));
System.out.println(jedis.set("key3", "value3"));
System.out.println("删除键key2:"+jedis.del("key2"));
System.out.println("获取键key2:"+jedis.get("key2"));
System.out.println("修改key1:"+jedis.set("key1", "value1Changed"));
System.out.println("获取key1的值:"+jedis.get("key1"));
System.out.println("在key3后面加入值:"+jedis.append("key3", "End"));
System.out.println("key3的值:"+jedis.get("key3"));
System.out.println("增加多个键值对:"+jedis.mset("key01","value01","key02","value02","key03","value03"));
System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03","key04"));
System.out.println("删除多个键值对:"+jedis.del(new String[]{"key01","key02"}));
System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
jedis.flushDB();
System.out.println("===========新增键值对防止覆盖原先值==============");
System.out.println(jedis.setnx("key1", "value1"));
System.out.println(jedis.setnx("key2", "value2"));
System.out.println(jedis.setnx("key2", "value2-new"));
System.out.println(jedis.get("key1"));
System.out.println(jedis.get("key2"));
System.out.println("===========新增键值对并设置有效时间=============");
System.out.println(jedis.setex("key3", 2, "value3"));
System.out.println(jedis.get("key3"));
TimeUnit.SECONDS.sleep(3);
System.out.println(jedis.get("key3"));
System.out.println("===========获取原值,更新为新值==========");//GETSET is an atomic set this value and return the old value command.
System.out.println(jedis.getSet("key2", "key2GetSet"));
System.out.println(jedis.get("key2"));
System.out.println("获得key2的值的字串:"+jedis.getrange("key2", 2, 4));
}
/***
* 整数和浮点数
*/
@Test
public void testNumber() {
jedis.flushDB();
jedis.set("key1", "1");
jedis.set("key2", "2");
jedis.set("key3", "2.3");
System.out.println("key1的值:"+jedis.get("key1"));
System.out.println("key2的值:"+jedis.get("key2"));
System.out.println("key1的值加1:"+jedis.incr("key1"));
System.out.println("获取key1的值:"+jedis.get("key1"));
System.out.println("key2的值减1:"+jedis.decr("key2"));
System.out.println("获取key2的值:"+jedis.get("key2"));
System.out.println("将key1的值加上整数5:"+jedis.incrBy("key1", 5));
System.out.println("获取key1的值:"+jedis.get("key1"));
System.out.println("将key2的值减去整数5:"+jedis.decrBy("key2", 5));
System.out.println("获取key2的值:"+jedis.get("key2"));
}
/**
* 列表
*/
@Test
public void testList() {
jedis.flushDB();
System.out.println("===========添加一个list===========");
jedis.lpush("collections", "ArrayList", "Vector", "Stack", "HashMap", "WeakHashMap", "LinkedHashMap");
jedis.lpush("collections", "HashSet");
jedis.lpush("collections", "TreeSet");
jedis.lpush("collections", "TreeMap");
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));//-1代表倒数第一个元素,-2代表倒数第二个元素
System.out.println("collections区间0-3的元素:"+jedis.lrange("collections",0,3));
System.out.println("===============================");
// 删除列表指定的值 ,第二个参数为删除的个数(有重复时),后add进去的值先被删,类似于出栈
System.out.println("删除指定元素个数:"+jedis.lrem("collections", 2, "HashMap"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("删除下表0-3区间之外的元素:"+jedis.ltrim("collections", 0, 3));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("collections列表出栈(左端):"+jedis.lpop("collections"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("collections添加元素,从列表右端,与lpush相对应:"+jedis.rpush("collections", "EnumMap"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("collections列表出栈(右端):"+jedis.rpop("collections"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("修改collections指定下标1的内容:"+jedis.lset("collections", 1, "LinkedArrayList"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("===============================");
System.out.println("collections的长度:"+jedis.llen("collections"));
System.out.println("获取collections下标为2的元素:"+jedis.lindex("collections", 2));
System.out.println("===============================");
jedis.lpush("sortedList", "3","6","2","0","7","4");
System.out.println("sortedList排序前:"+jedis.lrange("sortedList", 0, -1));
System.out.println(jedis.sort("sortedList"));
System.out.println("sortedList排序后:"+jedis.lrange("sortedList", 0, -1));
}
/***
* set集合
*/
@Test
public void testSet() {
jedis.flushDB();
System.out.println("============向集合中添加元素============");
System.out.println(jedis.sadd("eleSet", "e1","e2","e4","e3","e0","e8","e7","e5"));
System.out.println(jedis.sadd("eleSet", "e6"));
System.out.println(jedis.sadd("eleSet", "e6"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
System.out.println("删除一个元素e0:"+jedis.srem("eleSet", "e0"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
System.out.println("删除两个元素e7和e6:"+jedis.srem("eleSet", "e7","e6"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
System.out.println("随机的移除集合中的一个元素:"+jedis.spop("eleSet"));
System.out.println("随机的移除集合中的一个元素:"+jedis.spop("eleSet"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
System.out.println("eleSet中包含元素的个数:"+jedis.scard("eleSet"));
System.out.println("e3是否在eleSet中:"+jedis.sismember("eleSet", "e3"));
System.out.println("e1是否在eleSet中:"+jedis.sismember("eleSet", "e1"));
System.out.println("e1是否在eleSet中:"+jedis.sismember("eleSet", "e5"));
System.out.println("=================================");
System.out.println(jedis.sadd("eleSet1", "e1","e2","e4","e3","e0","e8","e7","e5"));
System.out.println(jedis.sadd("eleSet2", "e1","e2","e4","e3","e0","e8"));
System.out.println("将eleSet1中删除e1并存入eleSet3中:"+jedis.smove("eleSet1", "eleSet3", "e1"));
System.out.println("将eleSet1中删除e2并存入eleSet3中:"+jedis.smove("eleSet1", "eleSet3", "e2"));
System.out.println("eleSet1中的元素:"+jedis.smembers("eleSet1"));
System.out.println("eleSet3中的元素:"+jedis.smembers("eleSet3"));
System.out.println("============集合运算=================");
System.out.println("eleSet1中的元素:"+jedis.smembers("eleSet1"));
System.out.println("eleSet2中的元素:"+jedis.smembers("eleSet2"));
System.out.println("eleSet1和eleSet2的交集:"+jedis.sinter("eleSet1","eleSet2"));
System.out.println("eleSet1和eleSet2的并集:"+jedis.sunion("eleSet1","eleSet2"));
System.out.println("eleSet1和eleSet2的差集:"+jedis.sdiff("eleSet1","eleSet2"));//eleSet1中有,eleSet2中没有
}
}
运行截图
Mybatis-Plus的BaseMapper的用法
MP通用的CRUD
- insert操作
@Autowired
private EmplopyeeDao emplopyeeDao;
@Test
public void testInsert(){
Employee employee = new Employee();
employee.setLastName("东方不败");
employee.setEmail("dfbb@163.com");
employee.setGender(1);
employee.setAge(20);
emplopyeeDao.insert(employee);
//mybatisplus会自动把当前插入对象在数据库中的id写回到该实体中
System.out.println(employee.getId());
- update操作
@Test
public void testUpdate(){
Employee employee = new Employee();
employee.setId(1);
employee.setLastName("更新测试");
//emplopyeeDao.updateById(employee);//根据id进行更新,没有传值的属性就不会更新
emplopyeeDao.updateAllColumnById(employee);//根据id进行更新,没传值的属性就更新为null
注意两个update操作的区别,update方法,没有传值的字段不会进行更新,比如只传入了lastName。那么age,gender等属性就会保留原来的值,updateAllColumnById方法,顾名思义就会更新所有的列,没有传值的列会更新为null
- select操作
(1)根据id查询
Employee employee = emplopyeeDao.selectById(1);
(2)根据条件查询一条数据
Employee employeeCondition = new Employee();
employeeCondition.setId(1);
employeeCondition.setLastName("更新测试");
//若是数据库中符合传入的条件的记录有多条,那就不能用这个方法,会报错
Employee employee = emplopyeeDao.selectOne(employeeCondition);
(3)根据查询条件返回多条数据
Map<String,Object> columnMap = new HashMap<>();
columnMap.put("last_name","东方不败");//写表中的列名
columnMap.put("gender","1");
List<Employee> employees = emplopyeeDao.selectByMap(columnMap);
System.out.println(employees.size());
(4)通过id批量查询:
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
idList.add(3);
List<Employee> employees = emplopyeeDao.selectBatchIds(idList);
System.out.println(employees);
(5)分页查询
List<Employee> employees = emplopyeeDao.selectPage(new Page<>(1,2),null);
System.out.println(employees);
- delete操作
(1)根据id删除
emplopyeeDao.deleteById(1);
(2)根据条件删除
Map<String,Object> columnMap = new HashMap<>();
columnMap.put("gender",0);
columnMap.put("age",18);
emplopyeeDao.deleteByMap(columnMap);
(3)根据id批量删除
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
emplopyeeDao.deleteBatchIds(idList);
Java Calendar类
Calendar:它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
构造方法
protected Calendar() :由于修饰符是protected,所以无法直接创建该对象。需要通过别的途径生成该对象。
成员方法
static Calendar getInstance() | 使用默认时区和区域设置获取日历。通过该方法生成Calendar对象。如下所示:Calendar cr=Calendar.getInstance(); |
---|---|
public void set(int year,int month,int date,int hourofday,int minute,int second) | 设置日历的年、月、日、时、分、秒。 |
public int get(int field) | 返回给定日历字段的值。所谓字段就是年、月、日等等。 |
public void setTime(Date date) | 使用给定的Date设置此日历的时间。Date------Calendar |
public Date getTime() | 返回一个Date表示此日历的时间。Calendar-----Date |
abstract void add(int field,int amount) | 按照日历的规则,给指定字段添加或减少时间量。 |
public long getTimeInMillies() | 以毫秒为单位返回该日历的时间值。 |
日历字段
日历字段包含以下两种:一种是表示时间的单位,例如年、月、日等等。另一种是具体的日期,例如一月、二月、三月、一日、二日、三日、一点钟、两点钟等等具体的时间。前一种一般时获取的时候使用,后一种一般判断的时候使用。
时间字段
YEAR 年 MINUTE 分 DAY_OF_WEEK_IN_MONTH 某月中第几周
MONTH 月 SECOND/MILLISECOND 秒/毫秒 WEEK_OF_MONTH 日历式的第几周
DATE 日 DAY_OF_MONTH 和DATE一样 DAY_OF_YEAR 一年的第多少天
HOUR_OF_DAY 时 DAY_OF_WEEK 周几 WEEK_OF_YEAR 一年的第多少周
例子
public class CalendarDemo {
public static void main(String[] args) {
// 其日历字段已由当前日期和时间初始化:
Calendar rightNow = Calendar.getInstance(); // 子类对象
// 获取年
int year = rightNow.get(Calendar.YEAR);
// 获取月
int month = rightNow.get(Calendar.MONTH);
// 获取日
int date = rightNow.get(Calendar.DATE);
//获取几点
int hour=rightNow.get(Calendar.HOUR_OF_DAY);
//获取上午下午
int moa=rightNow.get(Calendar.AM_PM);
if(moa==1)
System.out.println("下午");
else
System.out.println("上午");
System.out.println(year + "年" + (month + 1) + "月" + date + "日"+hour+"时");
rightNow.add(Calendar.YEAR,5);
rightNow.add(Calendar.DATE, -10);
int year1 = rightNow.get(Calendar.YEAR);
int date1 = rightNow.get(Calendar.DATE);
System.out.println(year1 + "年" + (month + 1) + "月" + date1 + "日"+hour+"时");
}
}
注意:month是从0开始的,而月份是从1开始的,所以month需要加一。
String.format()的详细用法
String.format()字符串常规类格式化的两种重载方式
format(String format, Object… args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字符串。
format(Locale locale, String format, Object… args) 使用指定的语言环境,制定字符串格式和参数生成格式化的字符串。
例子
String str=null;
str=String.format("Hi,%s", "小明");
System.out.println(str); //Hi,小明
str=String.format("Hi,%s %s %s", "小明","是个","大帅哥");
System.out.println(str); //Hi,小明 是个 大帅哥
System.out.printf("字母c的大写是:%c %n", 'C'); //字母c的大写是:C
System.out.printf("布尔结果是:%b %n", "小明".equal("帅哥")); //布尔的结果是:false
System.out.printf("100的一半是:%d %n", 100/2); //100的一半是:50
System.out.printf("100的16进制数是:%x %n", 100); // 100的16进制数是:64
System.out.printf("100的8进制数是:%o %n", 100); //100的8进制数是:144
System.out.printf("50元的书打8.5折扣是:%f 元%n", 50*0.85); //50元的书打8.5折扣是:42.500000 元
System.out.printf("上面价格的16进制数是:%a %n", 50*0.85); //上面价格的16进制数是:0x1.54p5
System.out.printf("上面价格的指数表示:%e %n", 50*0.85); //上面价格的指数表示:4.250000e+01
System.out.printf("上面价格的指数和浮点数结果的长度较短的是:%g %n", 50*0.85); //上面价格的指数和浮点数结果的长度较短的是:42.5000
System.out.printf("上面的折扣是%d%% %n", 85); //上面的折扣是85%
System.out.printf("字母A的散列码是:%h %n", 'A');//字母A的散列码是:41
搭配转换符
日期的格式化输出
例子
Date date=new Date();
//c的使用
System.out.printf("全部日期和时间信息:%tc%n",date);//全部日期和时间信息:星期三 九月 21 22:43:36 CST 2016
//f的使用
System.out.printf("年-月-日格式:%tF%n",date);//年-月-日格式:2016-09-21
//d的使用
System.out.printf("月/日/年格式:%tD%n",date);//月/日/年格式:16/10/21
//r的使用
System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date);//HH:MM:SS PM格式(12时制):10:43:36 下午
//t的使用
System.out.printf("HH:MM:SS格式(24时制):%tT%n",date); //HH:MM:SS格式(24时制):22:43:36
//R的使用
System.out.printf("HH:MM格式(24时制):%tR",date); //HH:MM格式(24时制):22:43
小知识点
-
@Value("#{}")与@Value("KaTeX parse error: Expected 'EOF', got '#' at position 17: …}")的区别 @Value("#̲{}")表示SpEl表达式通常…{}")从配置文件中读值的用法
-
stream.map(…::new)
Java 8 允许你使用 :: 关键字来引用构造函数
public class LambdaTest4 {
public static void main(String[] args) {
//Lambda表达式引用构造函数
//根据构造器的参数来自动匹配使用哪一个构造器
Action4Creater creater = Action4::new;
Action4 a4 = creater.create("zhangsan");
a4.say();
}
}
- 基于jedis.setnx(key,value)实现分布式锁
SETNX :SET if Not eXists (如果不存在,则 SET)的简写;
隐藏的意思是:key存在的情况下,不操作redis内存;也就是返回值是0
具体java代码要依赖于:jedis的jar包
Long result = jedis.setnx(key, value);
返回值result :设置成功,返回 1 。设置失败,返回 0
在做定时任务前;判定一下能否在redis中做setnx;如果返回1,继续执行;返回0,不执行;
也就是执行者始终都是单实例的
- redis expire命令
redisExpire命令用于设置key的过期时间,key过期后将不再可用,单位以秒计
语法
Expire kEY_NAME TIME_IN_SECONDS
返回值
设置成功返回1,当key不存在或者不能为key设置过期时间