目录
Sstring、StringBuffer、StringBuilder三者之间的区别?
目录
Sstring、StringBuffer、StringBuilder三者之间的区别?
java的异常
Throwable是多有Java程序中错误处理的父类,有两种资类:Error和Exception
Error:表示由JVM所侦测到的无法预期的错误,由于这是属于JVM层次的严重错误,导致JVM无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息
Exception:表示可恢复的例外,这是可捕捉到的
常见的异常
NullPointerException ------空指针引用异常
ClassCastException ------类型强制转换异常
IllegalArgumentException ------传递非法参数异常
ArithmeticException ------算术运算异常
ArrayStoreException ------向数组中存放雨声明类型不兼容对象异常
IndexOutOfBoundsException ------下标越界异常
NegativeArraySizeException ------创建一个大小为负数的数组错误异常
NumberFormatException ------数字格式异常
SecurityException -------安全异常
UnsupportedOperationException ------不支持的操作异常
什么是单例模式?有几种?
单例模式:某个类的实例在多线程环境下只会被创建一次出来
单例模式有饿汉式单例模式、懒汉式单例模式和双检锁单例模式三种
饿汉式:线程安全,一开始就初始化
懒汉式:非线程安全,延迟初始化
双检锁:线程安全,延迟初始化
代码块加载顺序、打印含参构造中的值
执行顺序:构造代码块->构造方法->普通方法->局部代码块,分析:
1.当创建对象时,会触发构造函数
2.创建对象时,也会触发构造代码块,并且构造代码块优先于构造方法执行
3.我们创建好对象后才能通过对象调用普通方法
4.如果普通方法里有局部代码块,才会触发对应的局部代码块
需要写this.对应的字段
public class Demo4 { public static void main(String[] args) { Pig p1 = new Pig(); Pig p2 = new Pig("哈哈哈"); Pig p3 = new Pig("气人",23); System.out.println("p1----"+p1.age); System.out.println("p2----"+p2.age); System.out.println("p3----"+p3.age); System.out.println("这个"+p2.food); System.out.println(p3.food); p1.eat(); p2.eat(); p3.eat(); } } class Pig{ String food; int age; { System.out.println("我是一个构造代码块"); System.out.println("黑猪肉"); } public Pig(String food, int age) { this.food = food; this.age = age; System.out.println("我是全参构造"); } public Pig(){ System.out.println("我是无参构造"); } public Pig(String n){ System.out.println("含参构造"); this.food=n; } public void eat(){ System.out.println("小猪爱吃菜叶子"); { System.out.println("我是局部代码块"); int i=100; System.out.println(i); } } }
Sstring、StringBuffer、StringBuilder三者之间的区别?
String 字符串变量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量 (非线程安全)
String中的String类中使用final关键字修饰字符数组来保存字符串,private final char value[],String对象是不可变的,也就可以理解为常量,线程安全
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的
StringBuilder并没有的方法进行同步锁,所以是非线程安全的
小结:1)如果要操作少量数据用String
2)多线程操作字符串缓冲区下操作大量数据用StringBuffer
3)单线程操作字符串缓冲区下操作大量数据用StringBuilder
接口和抽象类的区别是什么?
实现:抽象类的子类使用extends来继承,接口必须用implements来实现接口
构造方法:抽象类可以有构造方法,但是接口不能有
main方法:抽象类可以有main方法,并且可以运行,接口不能有main方法
实现数量:抽象类可以实现多个接口,但是接口只能继承一个抽象类
访问修饰符:接口中方法默认pubilc,抽象类中的方法可以是任意访问修饰符
强引用、软引用、弱引用、虚引用
强引用:通常通过new来创建一个新对象时返回的引用就是一个强引用,若一个对象通过一系列强引用可到达,它就是强可达,那么他就不被回收。
/** * 强引用。当强引用指针不存在时,对象将被回收 * 也能够理解为 ROOT 引用消失时,对象将被回收 */ public class StrongReference { /** * jvm在执行gc时 将回调该方法 * @throws Throwable */ @Override protected void finalize() throws Throwable { System.out.println("gc doing now !"); } public static void main(String[] args) { StrongReference strongReference = new StrongReference(); // 将引用指针移除 strongReference = null; // 手动调用gc System.gc(); } }
软引用:软引用可达的对象在内存不充足时才会被回收,因此软引用要比弱引用“强”一些。
/** * Xmx2oM 设置最大堆内存为20M * 软引用 会在内存空间不够时,进行 gc 操做。 从而 回收 软引用对象 */ public class MySoftReference { public static void main(String[] args) { SoftReference<byte[]> softReference = new SoftReference<byte[]>(new byte[1024*1024*10]); System.out.println("第一次gc前 : byte[]:" + softReference.get()); System.gc(); System.out.println("第一次执行gc后 : byte[]:" + softReference.get()); byte[] bytes = new byte[1024*1024*12]; System.out.println("内存不够后 : byte[]:" + softReference.get()); } }
弱引用:弱引用可达是无论当前内存是否充足它都会被回收。
/** * 弱引用 虚拟机无视该引用。只要gc 必定会被回收(前提该对象没有被强引用) */ public class Test { public static void main(String[] args) { Teacher teacher = new Teacher(); WeakReference<Teacher> weakReference = new WeakReference<Teacher>(teacher); System.out.println(weakReference.get()); // 若不将 teacher 置为null,则还存在一个强引用。不会被gc回收 //teacher = null; System.gc(); System.out.println(weakReference.get()); }
示例二:
/** * User 对象持有 Teacher 对象的强引用。 * 当teacher 被置为null 时。 teacher 的强应用 随之消失。 * 而 User 对 Teacher 的强引用还在。 故 user.getTeacher() 并非null * 因此 teacher 并不会被 gc 回收。 * * 当 user 也被置为null时。 user 对 teacher 的强引用也不存在勒。 * 此时 teacher 将会被gc回收 */ public class Test1 { public static void main(String[] args) { User user = new User(); Teacher teacher = new Teacher(); teacher.setName("zs"); user.setTeacher(teacher); WeakReference<Teacher> weakReference = new WeakReference<Teacher>(teacher); System.out.println(System.identityHashCode(weakReference.get())); System.out.println(System.identityHashCode(teacher)); System.out.println(System.identityHashCode(user.getTeacher())); teacher = null; System.out.println(user.getTeacher().getName()); // 当user 置为null 时, 对teacher 的强引用消失。 此时 teacher 将会被回收。 user = null; System.gc(); System.out.println(weakReference.get()); } }
示例三:
public class People extends WeakReference<Teacher> { public People(Teacher referent) { super(referent); } } /** * People 继承自WeakReference<T> People也是一个虚拟引用对象。 * 因此teacher 被置为null时,强引用指针被清除。 * teacher 就会被gc回收。 */ public class Test2 { public static void main(String[] args) { Teacher teacher = new Teacher(); People people = new People(teacher); teacher = null; System.gc(); System.out.println(people.get()); } }
虚引用:虚引用存在的唯一作用就是当它指向的对象被回收后,虚引用本身会被加入到引用队列中,用作记录它指向的对象已被销毁。
异常
Throwable是所有Java程序中错误处理的父类,有两种资类:Error和Exception
Error:表示JVM所侦测到的无法预期的错误,由于这是属于JVM层次的严重错误,导致无法继续执行,无法采取任何恢复的操作,顶多只能显示。
Exception:表示可恢复的例外,这是可捕捉到的
1.运行时异常:都是RuntimeException类及其子类异常,特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕捉它,也没有用throws子句声明抛出它,也会编译通过。
2.非运行时异常(编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。
常见异常:
NullPointerException - 空指针异常
ClassCastException - 类型强制转换异常
IllegalArgumentException - 转递非法参数异常
ArithmeticException - 算术运算异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsException - 下标越界异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常
BIO、NIO、AIO有什么区别?
BIO:同步阻塞式IO,传统IO,特点是模式简单使用方便,并发处理能力低。
NIO:同步非阻塞IO,传统IO的升级,客户端和服务端通过Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
替换字符
替换字符使用.replace
如:
String str1="java is very good"; // 需要替换的数据 替换成什么 System.out.println(str1.replace("java","aaa"));
栈、堆、常量池
寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制
栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
堆:存放new出来的对象,注意创建出来的对象只包含各自的成员变量,不包含成员方法
常量池:存放常量,如基本类型的包装类(short、integer)和string,注意常量池位于堆中
代码段:用来存放从硬盘上读取的源程序代码
数据段:用来存放static修饰的静态成员
String s1=”china” String s2=”china” String s3=”england” String s4=new String(“china”) String s5=new String(“england”)
List、Map、Set区别
List和Set是存储单例数据的集合,Map是存储键值对这样的双列数据的集合
List中存储的数据是有顺序的,并且值允许重复
Map中存储的数据是无顺序的,它的键是不允许重复的,但是值是允许重复的
Set中存储的数据是无顺序的,并且不允许重复,但元素在集合中的位置是由元素的hashcode决定,即位置是固定的(Set集合是根据hashcode来进行数据存储的,所以位置是固定的,但是这个位置不是用户可以控制的,多以对于用户来时set中的元素还是无顺序)
创建线程有几种方式?
1.继承Thread并重写run方法创建线程,实现简单但不可以继承其他类
2.实现Runnable接口并重写run方法,避免了单继承局限性,编程更加灵活,实现解耦
3.实现Callable接口并重写call方法,创建线程,可以获取线程执行结果的返回值,并且可以抛出异常
4.使用线程池创建(使用java.util.concurrent.Executor接口)
Runnable和Callable的区别?
Runnable接口run方法无返回值;Callable接口call方法有返回值,支持泛型
Runnable接口run方法只能抛出运行时异常,且无法捕获处理;Callable接口call方法允许抛出异常,可以获取异常信息
什么是进程、线程,它们的区别在哪
当使用Java命令启动一个Java应用程序时,就会启动一个JVM进程,在这个进程中多偶的Java程序代码都是以线程来运行的,JVM中到main()方法,然后运行,这样就产生了一个线程,这个线程叫主线程,当main()方法结束后JVM进程也随即退出。
线程是指“进程代码段”的一次顺序执行流程。线程时CPU调度的最小单位。一个进程可以有一个或多个线程,各线程之间共享进程的内存空间、系统资源,进程仍然时操作系统资源分配的最小单位。
Java程序的进程执行过程就是标准的多线程的执行过程。当使用Java命令执行一个class类时,实际上就是启动了一个JVM进程。理论上,在该线程的内部至少回启动两个线程,一个是main线程,另一个是GC(垃圾回收)线程。实际上,执行一个Java程序后,通过Process Explorer来观察,线程数量远远不止两个,达到了18个之多
进程与线程的区别:
-
线程是"进程代码段"的一次顺序执行流程。一个进程由一个或多个线程组成,一个进程至少有一个线程。
-
线程是CPU调度的最小单位,进程是操作系统分配资源的最小单位。线程的划分尺度小于进程,使得多线程程序的并发性高。
-
线程是出于高并发的调度诉求从进程内部演进而来的。线程的出现既充分发挥了CPU的计算性能,又弥补了进程调度过于笨重的问题。
-
进程之间是相互独立的,但进程内部的各个线程之间并不完全独立。各个线程之间共享进程的方法区内存、堆内存、系统资源(文件句柄、系统信号等)。
-
切换速度不同:线程上下文切换比进程上下文切换要快得多。所以,有的时候,线程也称为轻量级进程。
线程有哪几种状态以及各种状态之间的转换?
1.第一是new->新建状态,并没有调用该对象的start方法
2.第二是Runnable->就绪状态,调用了线程对象的start方法
3.第三是Running->运行状态,设置为当前线程,开始运行run函数当中的代码
4.第四是阻塞状态
5.死亡状态
前端
什么是HTTP协议?
客户端和服务器之间数据传输的格式规范,格式简称为”超文本传输协议“是一个基于请求与响应模式的、无状态的、应用层的协议,基于TCP的连接方式
HTTP中重定向和请求转发的区别?
实现
转发:用request的getRequestDispatcher()方法得到ReuqestDispatcher对象,调用forward()方法request.getRequestDispatcher("other.jsp").forward(request,response)
重定向:调用response的sendRedirect()方法response.sendRedirect("other.jsp")
1)重定向2次请求,请求转发1次请求
2)重定向地址栏会变,请求转发地址栏不变
3)重定向是浏览器跳转,请求转发是服务器跳转
4)重定向可以跳转到任意网址,请求转发只能跳转当前项目
Get和Post的区别?
1.Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的
2.Get传送的数据量较小,一般传输数据大小不超过2k-4k(根据浏览器不同,限制不一样,但相差不大这主要是因为受URL长度限制,Post传送的数据量较大,一般被默认为不受限制
3.Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集
4.Get执行效率却比Post方法好。Get是form提交的默认方法
cookie和session的区别?
1.存储位置不同
cookie的数据信息存放在客户端浏览器上
session的数据信息存放在浏览器上
2.存储容量不同
单个cookie保存的数据<=4KB,一个站点最多保存20个cookie
对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制
3.存储方式不同
cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据
session中能够存储任何类型的数据,包括且不限于string、integer、list、map等
4.隐私策略不同
cookie对客户端是可见的别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的
session存储在服务器上,不存在敏感信息泄漏的风险
5.有效期上不同
开发可以通过设置cookie的属性,达到使cookie长期有效的效果
session依赖于名为JSEEEIONID的cookie,而cookieJSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果
6.服务器压力不同
cookie保管在客户端,不占用服务器资源,对于并发用户十分多的网站,cookie是很好的选择
session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存
JVM调优
-Xmx3550m:设置JVM最大可用内存为3550M。
-Xms3550m:设置JVM初始内存为3550m。注意:此值一般设置成和-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2g:设置年轻代大小为2G。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss256k:设置每个线程的栈大小。JDK5.0以后每个线程栈大小为1M,以前每个线程栈大小为256K。根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。
-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4。(该值默认为2)
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4。
TCP/IP网络模型
应用层:负责向用户提供应用程序,比如HTTP、FTP、Telnet、DNS、SMTP等
传输层:对报文进行分组和重组,并以TCP或UDP协议格式封装报文
网络层:路由以及把分组报文发送给目标网络或主机
链路层:封装和解封装IP报文,发送和接受ARP\RARP报文
自己
.jar启动命令
java -jar 文件名
git下载项目命令
git clone -b main 路径
redis启动命令
redis-server.exe redis.windows.conf
递归显示
utils
public class TreeUtil { public static JSONArray listToTree(JSONArray arr,String CODE,String UPCODE,String child){ JSONArray r = new JSONArray(); JSONObject hash = new JSONObject(); //将数组转为Object的形式,key为数组中的id for(int i=0;i<arr.size();i++){ JSONObject json = (JSONObject) arr.get(i); hash.put(json.getString(CODE), json); } //遍历结果集 for(int j=0;j<arr.size();j++){ //单条记录 JSONObject aVal = (JSONObject) arr.get(j); //在hash中取出key为单条记录中pid的值 JSONObject hashVP = (JSONObject) hash.get(aVal.get(UPCODE).toString()); //如果记录的pid存在,则说明它有父节点,将她添加到孩子节点的集合中 if(hashVP!=null){ //检查是否有child属性 if(hashVP.get(child)!=null){ JSONArray ch = (JSONArray) hashVP.get(child); ch.add(aVal); hashVP.put(child, ch); }else{ JSONArray ch = new JSONArray(); ch.add(aVal); hashVP.put(child, ch); } }else{ r.add(aVal); } } return r; }
service
QueryWrapper<ForumInterface> forumInterfaceQueryWrapper = new QueryWrapper<>(); forumInterfaceQueryWrapper.lambda().eq(ForumInterface::getStates,0); List<ForumInterface> forumInterfaces = forumInterfaceMapper.selectList(forumInterfaceQueryWrapper); return TreeUtil.listToTree(JSONArray.parseArray(JSON.toJSONString(forumInterfaces)),"forumId","PId","Children");
图片上传
与前端对接时只需要传file
utils
import java.io.File; import java.io.IOException; /** * 文件上传工具类 * * @author ruoyi */ public class FileUploadUtils { public static File getAbsoluteFile(String uploadDir, String fileName) throws IOException { File desc = new File(uploadDir + File.separator + fileName); if (!desc.exists()) { if (!desc.getParentFile().exists()) { desc.getParentFile().mkdirs(); } } return desc.isAbsolute() ? desc : desc.getAbsoluteFile(); } public static String getPathFileName(String fileName) throws IOException { String pathFileName = "/" + fileName; return pathFileName; } /** * 判断MIME类型是否是允许的MIME类型 * * @param extension 上传文件类型 * @param allowedExtension 允许上传文件类型 * @return true/false */ public static final boolean isAllowedExtension(String extension, String[] allowedExtension) { for (String str : allowedExtension) { if (str.equalsIgnoreCase(extension)) { return true; } } return false; } }
文件上传路径需要到application.yml中进行配置
controller
@PostMapping("/upload") public String upload(MultipartFile[] file) throws IOException { List<String> list = new ArrayList<>(); List<MultipartFile> collect = Arrays.asList(file); for (MultipartFile data : collect) { // 获取文件名称 String s = data.getOriginalFilename(); // 获取文件后缀名 assert s != null; String substring = s.substring(s.lastIndexOf(".")); // 重新生成文件名 保证不重复 String fileName = UUID.randomUUID() + substring; // 返回 文件的整体存放路径 String absolutePath = FileUploadUtils.getAbsoluteFile(fileDir, fileName).getAbsolutePath(); //进行上传 data.transferTo(Paths.get(absolutePath)); list.add(fileName);//仅只有文件名,没有保存路径 } //多张照片用逗号隔开 return StringUtils.join(list,","); }
图片查看
与前端对接时要传图片路径和宽高
utils
import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.text.Convert; /** * 客户端工具类 * * @author ruoyi */ public class ServletUtils { /** * 获取String参数 */ public static String getParameter(String name) { return getRequest().getParameter(name); } /** * 获取String参数 */ public static String getParameter(String name, String defaultValue) { return Convert.toStr(getRequest().getParameter(name), defaultValue); } /** * 获取Integer参数 */ public static Integer getParameterToInt(String name) { return Convert.toInt(getRequest().getParameter(name)); } /** * 获取Integer参数 */ public static Integer getParameterToInt(String name, Integer defaultValue) { return Convert.toInt(getRequest().getParameter(name), defaultValue); } /** * 获取Boolean参数 */ public static Boolean getParameterToBool(String name) { return Convert.toBool(getRequest().getParameter(name)); } /** * 获取Boolean参数 */ public static Boolean getParameterToBool(String name, Boolean defaultValue) { return Convert.toBool(getRequest().getParameter(name), defaultValue); } /** * 获得所有请求参数 * * @param request 请求对象{@link ServletRequest} * @return Map */ public static Map<String, String[]> getParams(ServletRequest request) { final Map<String, String[]> map = request.getParameterMap(); return Collections.unmodifiableMap(map); } /** * 获得所有请求参数 * * @param request 请求对象{@link ServletRequest} * @return Map */ public static Map<String, String> getParamMap(ServletRequest request) { Map<String, String> params = new HashMap<>(); for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) { params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); } return params; } /** * 获取request */ public static HttpServletRequest getRequest() { return getRequestAttributes().getRequest(); } /** * 获取response */ public static HttpServletResponse getResponse() { return getRequestAttributes().getResponse(); } /** * 获取session */ public static HttpSession getSession() { return getRequest().getSession(); } public static ServletRequestAttributes getRequestAttributes() { RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); return (ServletRequestAttributes) attributes; } /** * 将字符串渲染到客户端 * * @param response 渲染对象 * @param string 待渲染的字符串 */ public static void renderString(HttpServletResponse response, String string) { try { response.setStatus(200); response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); response.getWriter().print(string); } catch (IOException e) { e.printStackTrace(); } } /** * 是否是Ajax异步请求 * * @param request */ public static boolean isAjaxRequest(HttpServletRequest request) { String accept = request.getHeader("accept"); if (accept != null && accept.contains("application/json")) { return true; } String xRequestedWith = request.getHeader("X-Requested-With"); if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) { return true; } String uri = request.getRequestURI(); if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) { return true; } String ajax = request.getParameter("__ajax"); return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); } /** * 内容编码 * * @param str 内容 * @return 编码后的内容 */ public static String urlEncode(String str) { try { return URLEncoder.encode(str, Constants.UTF8); } catch (UnsupportedEncodingException e) { return StringUtils.EMPTY; } } /** * 内容解码 * * @param str 内容 * @return 解码后的内容 */ public static String urlDecode(String str) { try { return URLDecoder.decode(str, Constants.UTF8); } catch (UnsupportedEncodingException e) { return StringUtils.EMPTY; } } }
controller
@GetMapping("/show/{fileUrl}") public void show(@PathVariable String fileUrl,Integer w ,Integer h) throws IOException { ServletOutputStream os = ServletUtils.getResponse().getOutputStream(); String contentType = "image/jpeg"; File img = new File(fileDir + File.separator + fileUrl); ServletUtils.getResponse().setContentType(contentType); ServletUtils.getResponse().addHeader("cache-control", "max-age=31536000"); ImgTools.thumbnail_w_h(img, w, h, os); }
文件导出
与前端对接是导出按钮不需要传值
utils
package com.ruoyi.hpv.utils; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import org.apache.commons.io.IOUtils; import org.apache.poi.ss.usermodel.Workbook; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.net.URLEncoder; import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * @Author 文件导出 * @Date 2021/9/14 10:13 * @Version 1.0 */ public class ExcelTemplate { public static void ExcelTemplate(String fileName, String filePath, List list, Map<String, Object> map, HttpServletResponse response) throws Exception { ExcelWriter excelWriter = null; // try { // String fileName = s + DateUtils.getStringDate();//导出的文件名称 response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 String filename = URLEncoder.encode(fileName, "utf-8"); response.setHeader("Content-disposition", "attachment;filename=" + filename + ".xlsx"); //使用response.getOutputStream()下载,并使用项目下的模板填充 excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(filePath).build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); if (map != null) { excelWriter.fill(map, writeSheet);//存入map } if (list != null) { excelWriter.fill(list, writeSheet);//存入list } // 设置强制计算公式:不然公式会以字符串的形式显示在excel中 Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook(); workbook.setForceFormulaRecalculation(true); excelWriter.finish(); // } catch (Exception e) { // // 重置response // response.reset(); // response.setContentType("application/json"); // response.setCharacterEncoding("utf-8"); // return; // // } } /** * 文件压缩的方法 */ public static void zipFile(File inputFile, String fileName, ZipOutputStream zipoutputStream) { try { if (inputFile.exists()) { // 判断文件是否存在 if (inputFile.isFile()) { // 判断是否属于文件,还是文件夹 // 创建输入流读取文件 FileInputStream fis = new FileInputStream(inputFile); // 将文件写入zip内,即将文件进行打包 ZipEntry ze = new ZipEntry(fileName); // 获取文件名 zipoutputStream.putNextEntry(ze); // 写入文件的方法,同上 IOUtils.copy(fis, zipoutputStream); } else { // 如果是文件夹,则使用穷举的方法获取文件,写入zip try { File[] files = inputFile.listFiles(); for (int i = 0; i < files.length; i++) { zipFile(files[i], files[i].getName(), zipoutputStream); } } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } }
controller
@GetMapping("/exportTemplate") public void exportTemplate(HttpServletResponse response, ReservationInterface reservationInterface) throws Exception { // 模拟数据库获取数据 List<ReservationInterface> list = reservationInterfaceService.selectAll(reservationInterface); String fileName = "预约导出"; ExcelTemplate.ExcelTemplate(fileName, fileUrl, list, null, response); }
注意
1.需要在application.yml文件中配置fileUrl
2.需要在对应的文件下添加模板
3.模型下面的字段一定要和查询出来的字段对应,如果俩表连查该实体类中没有那个字段需要在实体类中添加必须做要一一对应
计算两个时间工作日天数差
utile
import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class CalcWorkDays { /** * 计算两个时间工作日天数差。 * 1. 方法忽略法定节假日; * 2. 忽略周末补充上班; * 3. stop当天算入计算天数; * * @param localDateTimeStart * @param localDateTimeStop * @return * @throws ParseException */ public static int getTimeDiffDay (LocalDateTime localDateTimeStart, LocalDateTime localDateTimeStop) { if (localDateTimeStart.isAfter(localDateTimeStop)) { return -1; } System.out.println(localDateTimeStart); Date begin = Date.from(localDateTimeStart.atZone(ZoneId.systemDefault()).toInstant()); Date endTime = Date.from(localDateTimeStop.atZone(ZoneId.systemDefault()).toInstant()); Calendar cEnd = new GregorianCalendar(); cEnd.setTime(endTime); // 计算时算入stop当天 cEnd.add(Calendar.DATE, 1); Date end = cEnd.getTime(); Calendar c = Calendar.getInstance(); c.setTime(begin); int count = 0; while (c.getTime().before(end)) { // 非周末 if (c.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY && c.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) { count++; } c.add(Calendar.DATE, 1); } return count; }
service使用
//循环出所有的预约时间 LocalDateTime time = data.getSpecificTime(); //获取当前时间 LocalDateTime now = LocalDateTime.now(); //俩个时间共有多少天(会自动排除休息日) int timeDiffDay = CalcWorkDays.getTimeDiffDay(time, now);
分页
需要添加配置文件
@Configuration //添加配置类 public class MybatisPlusConfig { // 最新版 // 核心功能: 指定数据库版本,自动生成Sql @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB)); return interceptor; } }
controller层
@RestController @CrossOrigin @RequestMapping("/item") public class ItemController { @Autowired private ItemService itemService; @GetMapping("/getItemList") public SysResult getItemList(PageResult pageResult){//3个 pageResult = itemService.getItemList(pageResult);//+2操作 return SysResult.success(pageResult); //5个 } }
service层
QueryWrapper<User> queryWrapper=new QueryWrapper<>(); //分页条件 queryWrapper.like(StringUtils.hasLength(pageResult.getQuery()),"name",pageResult.getQuery()); queryWrapper.like(StringUtils.hasLength(pageResult.getQuery()),"grade",pageResult.getQuery()); Page<User> page= new Page<>(pageResult.getPageNum(), pageResult.getPageSize()); page = userMapper.selectPage(page, queryWrapper); long total = page.getTotal(); List<User> rows=page.getRecords(); return pageResult.setTotal(total).setRows(rows);
启动前端
找到前端对应的包,cmd后分别执行这两行命令
npm install npm run dev
创建视图
视图:好几张表可以当成一张表用
CREATE VIEW administrative_unit_school AS SELECT m.user_id AS user_name,m.password,'0' AS del_flag, '0' AS STATUS FROM edu_administrative_machinery m UNION SELECT s.user_name,s.password,'0' AS del_flag, '0' AS STATUS FROM edu_school s UNION SELECT o.user_name,o.password,'0' AS del_flag, '0' AS STATUS FROM edu_platform_operation_unit o
MP判断某个字段为不为空
string类型使用:StringUtils.isNotEmpty(对应的字段)
int类型使用:null !=
list对象转list<string>
List<EduGrade> list = new ArrayList<>(); EduGrade eduGrade1 = new EduGrade(); EduGrade eduGrade2 = new EduGrade(); EduGrade eduGrade3 = new EduGrade(); eduGrade1.setGradeCode("大班"); eduGrade2.setGradeCode("小班"); eduGrade3.setGradeCode("中班"); eduGrade1.setGrade("ceshi1"); eduGrade2.setGrade("ceshi2"); eduGrade3.setGrade("ceshi3"); list.add(eduGrade1); list.add(eduGrade2); list.add(eduGrade3); String[] a={"大班","中班","小班"}; List<String> collect1 = list.stream().map(EduGrade::getGradeCode).collect(Collectors.toList());
list用逗号隔开
String collect = collect1.stream().collect(Collectors.joining(","));
自己创建服务时,端口号不能以0开头
MyBatisPlus批量
//批量删除 this.removeByIds(ids); // 批量添加List<对象> this.saveBatch(ids); // 批量 修改 根据主键 this.updateBatchById(ids); // 批量添加或修改 this.saveOrUpdateBatch(ids);
注入service的增删改查
//添加 this.save(ids); this.updateById(); //删除 this.removeById(); //查询 this.getOne(); this.list(); this.getObj();
MyBatisPlus使用sum
使用sum需要起别名同时在实体类中对应
QueryWrapper<LshBuilding> lshDistrictQueryWrapper = new QueryWrapper<>(); lshDistrictQueryWrapper.eq("id", id); lshDistrictQueryWrapper.select("sum(whether_to_rent) as total_number"); LshBuilding lshBuilding1 = lshBuildingMapper.selectOne(lshDistrictQueryWrapper);
改hosts文件
查看dns
ipconfig /displaydns
刷新dns
ipconfig /flushdns
更新时间
pojo
@JsonFormat(pattern="yyyy-mm-dd") private LocalDateTime Time;
service
LocalDateTime now = LocalDateTime.now(); commonProblem1.setUpdateTime(now);
如idea打不开
打不开时卸载,如果还是不行进行idea删除注册表windows彻底删除idea_idea注册表删除_Rsun04551的博客-CSDN博客
怎么向gogs上创建分支并提交代码
1.在文件中找到需要提交代码的项目,cmd
2.git checkout -b liush liush为需要创建新分支的名字
3.git add *
4.git comit -m "行政区划修改" "行政区划修改"为修改或者添加了那些东西,注释的意思
5.git push origin liush
在sql中拼接逗号
select a.receipt_payment_date,
a.actual_money,
listagg(b.finance_num, ',') within group(order by finance_num) as finance_num
from fm_receipt_payment_manage a, fm_receipt_payment_voucher b
where a.kid = ?
and a.kid=b.manage_kid
group by a.receipt_payment_date,
a.actual_money
使用listagg(指定字段,",")