0
点赞
收藏
分享

微信扫一扫

工作一年后端问题杂录

梅梅的时光 2022-03-12 阅读 83

1,前端请求传Json对象则后端使用@RequestParam;
前端请求传Json对象的字符串则后端使用@RequestBody。

2,@RequestParam 多参数传值
const { data: res } = await this. h t t p . p o s t ( ′ a d d s u b j e c t s ? i d = ′ + t h i s . http.post('addsubjects?id='+this. http.post(addsubjects?id=+this.store.getters.getid, this.course)

约束类型 含义
RESTRICT 拒绝删除或者更新父表。
CASCADE 从父表中删除或更新对应的行,同时自动的删除或更新自表中匹配的行
SET NULL 从父表中删除或更新对应的行,同时将子表中的外键列设为空。注意,这些在外键列没有被设为NOT NULL时才有效。
NO ACTION InnoDB拒绝删除或者更新父表。
3,size()==0和isEmpty()是等价的,都是判断元素是否为空

4,replace into t(id, update_time) values(1, now());

  1. 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。 2. 否则,直接插入新数据。

5,public boolean after( Date when)
当且仅当此 Date 对象表示的瞬间比 when 表示的瞬间晚,才返回 true;否则返回 false。
public boolean before(Date when)
当且仅当此 Date 对象表示的瞬间比 when 表示的瞬间早,才返回
public boolean equals(Object obj)
比较两个日期的相等性。当且仅当参数不为 null,并且是一个表示与此对象相同的时间点(到毫秒)的

6,file.getOriginalFilename()是得到上传时的文件名。
1、java io包中File类中并没有getFileName()方法,这里应该是指getName()方法,此方法仅返回文件名,并不会包含路径。如果需要完整路径+文件名,应该使用getPath()取得路径后再组合使用getName(),拼出一个完整路径+文件名的字符串。
2、File类中常用方法如下,下文中file是File类的一个实例取得文件名称的方法: file.getName()取得文件路径的方法:file.getPath()。
3、判断文件是否绝对路径: file.isAbsolute(),取得文件的根目录: file.getParent(),判断文件是否存在: file.exists(),判断是否是目录: file.isDirectory(),判断是否是文件: file.isFile(),判断是否是隐藏文件: file.isHidden(),判断是否可读:file.canRead(),判断是否可写: file.canWrite()。

7,endsWith() 方法用于测试字符串是否以指定的后缀结束。

8,UUID.randomUUID()
UUID
UUID(Universally Unique IDentifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的

8,@NoArgsConstructor
注解在类上,为类提供一个无参的构造方法。
9,String 类别中已经提供了将基本数据型态转换成 String 的 static 方法 ,也就是 String.valueOf() 这个参数多载的方法

10,!StringUtil.isEmpty(f_ad_cd) 字符串不为空

11,Calendar类

https://blog.csdn.net/ytasdfg/article/details/81086118
abstract void add(int field,int amount) 按照日历的规则,给指定字段添加或减少时间量。

public void setTime(Date date) 使用给定的Date设置此日历的时间。Date------Calendar
public Date getTime() 返回一个Date表示此日历的时间。Calendar-----Date

12,日期转化格式DateUtil工具类
https://blog.csdn.net/xzp_12345/article/details/79438006
方法:1. 根据Date时间,转化成上面各种日期格式;
2. 解析两个日期之间的所有月份
3. 解析两个日期之间的所有日期
4. 获取当下年份指定前后数量的年份集合
5. 获取当前日期是一年中的第几周
6. 获取某一年各星期的始终时间
7. 获取某一年的总周数
8. 获取指定日期所在周的第一天或者最后一天
9. 获取某个日期是星期几
10. 验证字符串是否是日期
11. 获得指定日期前后时间段的时间
12. 获得两个日期的时间戳之差
13. 判段两个时间是否为同年同月
14. 判断两个时间的时间差(结果按照格式化输出)
13,
而不同页面间传值使用request.setAttribute(position, nameOfObj)时,只会从a.jsp到b.jsp一次传递,之后这个request就会失去它的作用范围,再传就要再设一个 request.setAttribute()。而使用session.setAttribute()会在一个过程中始终保有这个值。

14,concat() 方法用于将指定的字符串参数连接到字符串上。

15,

15,sql语句?传值 query.setInteger(项, 值);

16
sql.append(" and to_char(a.report_date, ‘yyyy-MM-dd’) >= ‘" + DateUtil.d2s(pageInfo.getF_report_date()) +"’");

17,@JsonIgnore注解
作用:在json序列化时将pojo中的一些属性忽略掉,标记在属性或者方法上,返回的json数据即不包含该属性。

https://www.cnblogs.com/mr-wuxiansheng/p/7787296.html
//当前时间
Date date = DateUtil.date();
//当前时间
Date date2 = DateUtil.date(Calendar.getInstance());
//当前时间
Date date3 = DateUtil.date(System.currentTimeMillis());
//当前时间字符串,格式:yyyy-MM-dd HH:mm:ss
String now = DateUtil.now();
//当前日期字符串,格式:yyyy-MM-dd
String today= DateUtil.today();
//常用日期格式的格式化
String dateStr = “2017-03-01”;
Date date = DateUtil.parse(dateStr);

https://www.cnblogs.com/diandianquanquan/p/10606960.html
时间格式化对象
SimpleDateFormat
当前时间
Calendar startdate=Calendar.getInstance();
startdate.set(calendar.DATE 8); // 直接修改时间值
startdate.add(calendar.DATE_DAY, 8);// 加减时间值
String visitdate=DateUtil.d2s(startdate.getTime());

日期
Calendar now = Calendar.getInstance();
System.out.println("年: " + now.get(Calendar.YEAR));
System.out.println("月: " + (now.get(Calendar.MONTH) + 1) + “”);
System.out.println("日: " + now.get(Calendar.DAY_OF_MONTH));
System.out.println("时: " + now.get(Calendar.HOUR_OF_DAY));
System.out.println("分: " + now.get(Calendar.MINUTE));
System.out.println("秒: " + now.get(Calendar.SECOND));
System.out.println(“当前时间毫秒数:” + now.getTimeInMillis());
System.out.println(now.getTime());

	Date d = new Date();
	System.out.println(d);
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	String dateNowStr = sdf.format(d);
	System.out.println("格式化后的日期:" + dateNowStr);
	
	String str = "2012-1-13 17:26:33";	//要跟上面sdf定义的格式一样
	Date today = sdf.parse(str);
	System.out.println("字符串转成日期:" + today);

时区不一致
long l = new Date().getTime() + 8 * 60 * 60 * 1000;
new Date(l)
去重代码
if (!tempList.contains(object)) {
tempList.add(object);
}

判断字符串是否为空
StringUtils.isNotBlank()和StringUtils.isNotEmpty()

判断list是否为空
list!=null && !list.isEmpty()

判断某字符串是否为空,为空的标准是 str==null 或 str.length()==0
https://blog.csdn.net/hezuo1181/article/details/100535812

  1. public static boolean isEmpty(String str)

MultiValueMap
https://zhuanlan.zhihu.com/p/151022117?from_voters_page=true

百分数
DecimalFormat decimalFormat = new DecimalFormat("##.00%");
System.out.println(decimalFormat.format(1 / 3.0));

方法一:向上取整Math.ceil();
举例:Math.ceil(11.4)=12; Math.ceil(-11.6)=-11;
方法二:向下取整Math.floor();
举例:Math.floor(11.7)=11;Math.floor(-11.2)=-12;
方法三:四舍五入Math.round();
顾名思义,四舍五入后取整,其算法为Math.round(x+0.5),即原来的数字加上0.5后再想下取整即可。
举例:Math.round(11.5)=12;
Math.round(-11.5)=-11;

字符串为null和为" “判断
StringUtil.isEmpty(” ")

Integer 判断为 null

手动抛出异常
throw new RuntimeException(“不能为负数”);

判断数组不为空
!CollectionUtils.isEmpty()

实体类存在多关联
cannot simultaneously fetch multiple bags异常是由于持久层实时加载太多异同对象而致。例如用户登录时,同步实时加载用户的角色对象、权限对象,而往往这些关系都是多对多关系,就单一列内容来看存在重复的值,从而引起multiple bags。将List变为Set

return Optional.ofNullable(service.A()).orElse(service.B())
功能显而易见,service.A()如果返回值是null,则返回service.B(),否则直接返回service.A()。

接口参数非必要必需必须
@RequestParam(required = false)

mysql数据库,以0开头char字段
substr(字段名,1) 。1表示所有

java字符串分割数组split
StringUtils.split(String, “,”);
String[] sArray= String.split(",");

ActionContext
ActionContext是Action的上下文,Struts2自动在其中保存了一些在Action执行过程中所需的对象,比如session, parameters, locale等。Struts2会根据每个执行HTTP请求的线程来创建对应的ActionContext,即一个线程有一个唯一的ActionContext。因此,使用者可以使用静态方法ActionContext.getContext()来获取当前线程的ActionContext,也正是由于这个原因,使用者不用去操心让Action是线程安全的。

无论如何,ActionContext都是用来存放数据的。Struts2本身会在其中放入不少数据,而使用者也可以放入自己想要的数据。ActionContext本身的数据结构是映射结构,即一个Map,用key来映射value。所以使用者完全可以像使用Map一样来使用它,或者直接使用Action.getContextMap()方法来对Map进行操作。

Struts2本身在其中放入的数据有ActionInvocation、application(即ServletContext)、conversionErrors、Locale、action的name、request的参数、HTTP的Session以及值栈等。完整的列表请参考它的Javadoc(本文附录有对它包含内容的讨论)。

由于ActionContext的线程唯一和静态方法就能获得的特性,使得在非Action类中可以直接获得它,而不需要等待Action传入或注入。需要注意的是,它仅在由于request而创建的线程中有效(因为request时才创建对应的ActionContext),而在服务器启动的线程中

具体: https://blog.csdn.net/sunqing0316/article/details/47176601

jdk8日期时间方法
https://www.cnblogs.com/huanshilang/p/12013386.html

Lambda表达式的语法:类似于JS的箭头函数
([Lambda参数列表,即形参列表]) -> {Lambda体,即方法体}
new Thread(() -> 方法体)
Lambda 表达式实例
Lambda 表达式的简单例子:
// 1. 不需要参数,返回值为 5
() -> 5

// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x

// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y

// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y

// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)

ArrayList的截取集合方法
注意ArrayList 的 subList方法,结果不可强转成 ArrayList

ArrayList集合转数组
String[] array = list.toArray(new String[0]);

ArrayList集合添加一个新集合
lodList.addAll(newList)) // 要对添加集合进行非空判定

数组转ArrayList集合的方法
ArrayList list = Array.asList() // 转换集合之后,不能使用其修改集合相关的方法,它的add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

Map集合遍历
for(Entry<String, Integer> item: Map.entrySet()) {
System.out.print(item);
} // Entry固定类型, item是值没有键

Math.random() 这个方法返回是 double 类型,注意取值的范围 0≤x<1(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法

日志
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Test.class);

异常不要继承Exception,而是继承RuntimeException,否则到时候从头改到尾就为了加个异 常声明你就觉得很无聊

直接使用toArray()无参方法返回值只能是Object[]类,若强转成其它类型数组将会抛出异常。
解决方案:使用 T[] toArray(T[] a);有参数这个方法,代码如下:

数据库小数类型为 decimal

List 转换为 String数组
List list = new ArrayList();
list.add(“a”);
list.add(“b”);
String[] arr = list.toArray(new String[list.size()]);

String 数组转换为 List
String[] arr = ((String) item.get(“keyvalue”)).split(",");;
List list = Arrays.asList(arr); //此集合无法操作添加元素
List list1 = new ArrayList(list); //此集合可操作元素

获取系统当前时间
https://blog.csdn.net/weixin_42447373/article/details/88814221
https://www.cnblogs.com/cnblogszs/p/5508223.html

Map判断key值是否存在对应的value
Map.containsKey(“key”)

Map判断为空
Map.isEmpty()

异常处理通用写法
log.error("{} /drapi/data/org/tree->查询组织机构失败,异常 ->: "+back.get(“errormsg”), DateUtil.dt2s(new Date()));

MangGodb 包含 / 不包含 某个字段,排序
query.fields().include(“fields”); //包含该字段
query.fields().exclude(“fields”);//不包含该字段
query.with(new Sort(new Sort.Order(Sort.Direction.DESC,"_id")));//排序

Spring boot配置定时任务
@Scheduled(cron = “${fixedRate.mi-timer}”)

UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。

那么@Builder内部帮我们做了什么?
创建一个名为ThisClassBuilder的内部静态类,并具有和实体类形同的属性(称为构建器)。
在构建器中:对于目标类中的所有的属性和未初始化的final字段,都会在构建器中创建对应属性。
在构建器中:创建一个无参的default构造函数。
在构建器中:对于实体类中的每个参数,都会对应创建类似于setter的方法,只不过方法名与该参数名相同。 并且返回值是构建器本身(便于链式调用),如上例所示。
在构建器中:一个build()方法,调用此方法,就会根据设置的值进行创建实体对象。
在构建器中:同时也会生成一个toString()方法。
在实体类中:会创建一个builder()方法,它的目的是用来创建构建器。

数据库日期字段
DATE_FORMAT(b.createtime,’%Y-%m-%d’) createtime

实体类转List
List data = JSON.parseArray(JSON.toJSONString(edits), TagEditModel.class);

实体类转Map

  1. 在 pom.xml 中引入依赖包

    com.alibaba
    fastjson
    1.2.54
  2. 在控制类中引入
    import com.alibaba.fastjson.JSON;
  3. 实体类类型转换
    JSON.parseObject(JSON.toJSONString(源数据), 转换后数据类型.class);
    // 将 Map 转换为 实体类
    User user = JSON.parseObject(JSON.toJSONString(user01), User.class);
    System.out.println(user);
    // 将 实体类 转换为 Map
    Map map = JSON.parseObject(JSON.toJSONString(user), Map.class);
    System.out.println(map);
    // 实体类转List
    List body = JSON.parseArray(JSON.toJSONString(attrs), CustomerAttributeSearchBody.class);
    List data = JSON.parseArray(back.getString(“result”), OrgListResult.class);

Integer比较
Integer作为常量时,对于-128到127之间的数,会进行缓存,也就是说int a1 = 127时,在范围之内,这个时候就存放在缓存中,当再创建a2时,java发现缓存中存在127这个数了,就直接取出来赋值给a2,所以a1 == a2的。当超过范围就是new Integer()来new一个对象了,所以a、b都是new Integer(128)出来的变量,所以它们不等。

互斥锁
  缓存击穿后,多个线程会同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它。
  其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。

CGI 仅仅是众多网关技术中的一种, 后续又发展出了 Servlet、FastCGI 等更为高效的网关技术。

Redis(全称:Remote Dictionary Server 远程字典服务),是一个key-value存储系统, 缓存中的数据其实就是数据库数据的备份,缓存机制就是有效的降低用户访问真是物理设备频次。

悲观锁思路
解决线程安全的思路很多,可以从“悲观锁”的方向开始讨论。
悲观锁,也就是在修改数据的时候,采用锁定状态,排斥外部请求的修改。遇到加锁的状态,就必须等待。
虽然上述的方案的确解决了线程安全的问题,但是,别忘记,我们的场景是“高并发”。也就是说,会很多这样的修改请求,每个请求都需要等待“锁”,某些线程可能永远都没有机会抢到这个“锁”,这种请求就会死在那里。同时,这种请求会很多,瞬间增大系统的平均响应时间,结果是可用连接数被耗尽,系统陷入异常。

乐观锁思路
这个时候,我们就可以讨论一下“乐观锁”的思路了。乐观锁,是相对于“悲观锁”采用更为宽松的加锁机制,大都是采用带版本号(Version)更新。实现就是,这个数据所有请求都有资格去修改,但会获得一个该数据的版本号,只有版本号符合的才能更新成功,其他的返回抢购失败。这样的话,我们就不需要考虑队列的问题,不过,它会增大CPU的计算开销。但是,综合来说,这是一个比较好的解决方案。

缓存服务器
Redis分布式要保证数据都能能够平均的缓存到每一台机器,首先想到的做法是对数据进行分片,因为Redis是key-value存储的,首先想到的是Hash分片,可能的做法是对key进行哈希运算,得到一个long值对分布式的数量取模会得到一个一个对应数据库的一个映射,没有读取就可以定位到这台数据库

并发解决方案
a.应用层面:读写分离、缓存、队列、集群、令牌、系统拆分、隔离、系统升级(可水平扩容方向)。
b.时间换空间:降低单次请求时间,这样在单位时间内系统并发就会提升。
c.空间换时间:拉长整体处理业务时间,换取后台系统容量空间。

Java中的volatile关键字:
volatile关键字可以保证直接从主存中读取一个变量,如果这个变量被修改后,总是会被写回到主存中去。Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方式来实现可见性的,无论是普通变量还是volatile变量都是如此,普通变量与volatile变量的区别是:volatile的特殊规则保证了新值能立即同步到主内存,以及每个线程在每次使用volatile变量前都立即从主内存刷新。因此我们可以说volatile保证了多线程操作时变量的可见性,而普通变量则不能保证这一点。

JMM: 用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果
https://zhuanlan.zhihu.com/p/29881777

Java设计模式
http://c.biancheng.net/view/8462.html

cron表达式
0 0 0 */1 * ? 每日凌晨0点
0 */1 * * * ? 每分钟

后端调用接口包含中文参数

java同目录下文件相对路径
WorkflowController.class.getResource(“test.form”).getPath()

Map遍历键值
https://www.cnblogs.com/bingyimeiling/p/10741761.html

StringUtils.isBlank()的使用
在校验一个String类型的变量是否为空时,通常存在3中情况
是否为 null
是否为 “”
是否为空字符串(引号中间有空格) 如: " "。
制表符、换行符、换页符和回车

JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别
关于获取类的字段有两种方式:getFields()和getDeclaredFields()。我们先来看看这两者的区别吧:
getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
同样类似的还有getConstructors()和getDeclaredConstructors()、getMethods()和getDeclaredMethods(),这两者分别表示获取某个类的方法、构造函数。

endsWith()
方法用于测试字符串是否以指定的后缀结束。

Java 中 Pattern用法(正则表达式)
https://blog.csdn.net/lengdaochuqiao/article/details/81289104
在给用户发送消息时通常情况会有相同的消息模板,但其中部分信息跟用户相关,因此需要对消息模板中的变量部分进行替换。而对于一个系统而言可能有很多套完全不同的模板。因此需要一个通用的根据实际信息替换消息模板中变量的方法。消息模板的变量与velcity中的变量规范相同。

java反射之Method的invoke方法实现
https://blog.csdn.net/wenyuan65/article/details/81145900

在框架中经常会会用到method.invoke()方法,用来执行某个的对象的目标方法。以前写代码用到反射时,总是获取先获取Method,然后传入对应的Class实例对象执行方法。然而前段时间研究invoke方法时,发现invoke方法居然包含多态的特性,这是以前没有考虑过的一个问题。那么Method.invoke()方法的执行过程是怎么实现的?它的多态又是如何实现的呢?

Java toUpperCase() 方法
toUpperCase() 方法将字符串小写字符转换为大写。

Java反射使用总结
https://zhuanlan.zhihu.com/p/80519709

动态代理
https://www.zhihu.com/question/20794107/answer/658139129
可以这样说:接口拥有代理对象和目标对象共同的类信息。所以,我们可以从接口那得到理应由代理类提供的信息。但是别忘了,接口是无法创建对象的,怎么办?
JDK提供了java.lang.reflect.InvocationHandler接口和 java.lang.reflect.Proxy类,这两个类相互配合,入口是Proxy,所以我们先聊它。
Proxy有个静态方法:getProxyClass(ClassLoader, interfaces),只要你给它传入类加载器和一组接口,它就给你返回代理Class对象。
用通俗的话说,getProxyClass()这个方法,会从你传入的接口Class中,“拷贝”类结构信息到一个新的Class对象中,但新的Class对象带有构造器,是可以创建对象的。打个比方,一个大内太监(接口Class),空有一身武艺(类信息),但是无法传给后人。现在江湖上有个妙手神医(Proxy类),发明了克隆大法(getProxyClass),不仅能克隆太监的一身武艺,还保留了小DD(构造器)…(这到底是道德の沦丧,还是人性的扭曲,欢迎走进动态代理)

Http文件流操作 HttpServletResponse

LinkedHashSet去重
ArrayList numbersList = new ArrayList<>(Arrays.asList(1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 6, 7, 8));
LinkedHashSet hashSet = new LinkedHashSet<>(numbersList);
ArrayList listWithoutDuplicates = new ArrayList<>(hashSet);
System.out.println(listWithoutDuplicates);

布尔类型实体类取值
Boolean用get boolean 直接is

String… fields
该种参数为不定个数的参数,这些参数以string数组的方式组织。

如何使用@RequestBody传输数组
@RequestBody接收的是一个Json对象的字符串,而不是一个Json对象。然而在ajax请求往往传的都是Json对象,后来发现用 JSON.stringify(data)的方式就能将对象变成字符串。同时ajax请求的时候也要指定dataType: “json”,contentType:“application/json” 这样就可以轻易的将一个对象或者List传到Java端,使用@RequestBody即可绑定对象或者List.

Java Url编码
URLEncoder.encode(body.getName(), “utf-8”)

接口多继承
所以,我们可以得到一个结论,当编译器在实现接口的时候会依然检查接口InterfaceMultiInheritance.java、TestInterfaceA.java和TestInterfaceB.java中的方法声明,如果后两者有与前者相冲突的方法声明,编译器将只要求类实现前者的声明,而后两者中相同的方法声明将自动被忽略。而当只有后两者中有相同的方法声明时,编译器将实现其中的一个即可。就好像是编译器中有一个专门存储方法声明的Set一样,在有继承关系的接口中,只保存一次相同的方法声明。

java类单继承,多实现。 接口多继承
extends A, B
implements A,B //多实现

Java中isAssignableFrom的用法
class1.isAssignableFrom(class2) 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回 true;否则返回 false。如果该 Class 表示一个基本类型,且指定的 Class 参数正是该 Class 对象,则该方法返回 true;否则返回 false。

readonly
readonly关键字是可以在字段上使用的修饰符,当字段声明包括readonly,该声明引入的字段赋值只能作为声明的一部分出现,或者出现在同一类的构造函数中;
我个人觉得上面一句话就是限定了你用readonly修饰的字段的赋值操作的范围;可以看到加了readonly限制的字段,其只能在声明的初始化时候或者在同一个类的构造函数中修改其值;在其他情况下都是只读字段;
与const的区别在于:
1.const只能在该字段的声明中初始化;readonly则是两种手段,一个是在字段声明时,此外还多了在构造函数中的声明;
2.const字段是在编译时为常数,readonly修饰的字段可用于运行时的常数;
至此,readonly用法和const区别都已经解释清楚了

后端使用缓存
/**
* 内容发布缓存对象
*/
private Cache<String, List<Mob_articleComment>> commentCache = CacheBuilder.newBuilder()
// 设置缓存最后一次访问三十分钟后失效
.expireAfterAccess(60, TimeUnit.MINUTES)
.maximumSize(10000)
.build();

// 使用
if (isCache != null && isCache) {
// 有缓存读缓存
list = this.commentCache.get(contentid, new Callable<List<Mob_articleComment>>() {
@Override
public List<Mob_articleComment> call() throws Exception {
return dao.findCommentList(contentid, corpid, pageInfo);
}
});
} else {
list = dao.findCommentList(contentid, corpid, pageInfo);
}

// 清除缓存
// 清除该条内容发布的缓存
this.commentCache.invalidate(comment.getArticlecontentid());

接口多实现情况指定实现类
@Resource(name = “pos_stdnormalDaoMysql”)
接口参数非必须
@RequestParam(required = false)
springboot配置文件加载配置动态值
@Value("${testenv}")

举报

相关推荐

0 条评论