首页 > 其他 > 详细

杂项随记

时间:2019-11-03 21:49:53      阅读:78      评论:0      收藏:0      [点我收藏+]

杂项随记

1. System.out.printf

  • System.out.printf("--%s--%s--", arg1, arg2); 可以按指定格式输出参数,%s为占位符,后面跟相同个数个参数

2. try-with-resources

  • jdk1.7对 try-catch-finally 释放资源作了优化,只要是实现了java.lang.AutoCloseable接口的资源(java.io.closeable接口继承了AutoCloseable),都可以自动释放,而不用再写finally释放语句

     1   //try(){}直接在()中定义需要释放的资源,在{}中编写逻辑代码
     2   try(FileReader fr = new FileReader("fr.txt");
     3       FileWriter fw = new FileWriter("fw.txt")){
     4       char[] chars = new char[1024];
     5       int len;
     6       while ((len = fr.read(chars)) != -1){
     7           fw.write(chars,0,len);
     8       }
     9   } catch (IOException e){
    10       e.printStackTrace();
    11   }

3. 日志输出问题

  • 当出现Failed to load class "org.slf4j.impl.StaticLoggerBinder"错误时,需要导入slf4j-nop.jar、 slf4j-simple.jar、 slf4j-log4j12.jar、slf4j-jdk14.jar 或者 logback-classic.jar 其中的一个。

1   <dependency>
2       <groupId>org.slf4j</groupId>
3       <artifactId>slf4j-log4j12</artifactId>
4       <version>1.7.25</version>
5   </dependency>

 

  • springboot从1.4开始只支持log4j2,log4j2的配置文件为log4j2.xml

    1. 依赖导入,需要先排除spring-boot-starter-logging,再引入spring-boot-starter-log4j2

 1    <dependencies>
 2         <dependency>
 3             <groupId>org.springframework.boot</groupId>
 4             <artifactId>spring-boot-starter-amqp</artifactId>
 5             <exclusions>
 6                 <!--排除logging-->
 7                 <exclusion>
 8                     <groupId>org.springframework.boot</groupId>
 9                     <artifactId>spring-boot-starter-logging</artifactId>
10                 </exclusion>
11             </exclusions>
12         </dependency>
13         <!--配置log4j2-->
14         <dependency>
15             <groupId>org.springframework.boot</groupId>
16             <artifactId>spring-boot-starter-log4j2</artifactId>
17         </dependency>
18     </dependencies>

 

 
  1. 配置文件log4j2.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2     <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
 3     <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
 4     <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
 5     <configuration status="INFO" monitorInterval="30">
 6         <!--先定义所有的appender-->
 7         <appenders>
 8             <!--这个输出控制台的配置-->
 9             <console name="Console" target="SYSTEM_OUT">
10                 <!--输出日志的格式-->
11                 <PatternLayout pattern="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
12             </console>
13     
14             <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
15             <File name="Test" fileName="log/test.log" append="false">
16                 <PatternLayout pattern="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
17             </File>
18     
19             <!--设置日志文件会滚更新-->
20             <RollingFile name="RollingFileInfo" fileName="log/log.log" filePattern="log/log.log.%d{yyyy-MM-dd}">
21                 <!-- 只接受level=INFO以上的日志 -->
22                 <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
23                 <PatternLayout pattern="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
24                 <Policies>
25                     <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
26                     <SizeBasedTriggeringPolicy/>
27                 </Policies>
28             </RollingFile>
29     
30             <RollingFile name="RollingFileError" fileName="log/error.log" filePattern="log/error.log.%d{yyyy-MM-dd}">
31                 <!-- 只接受level=WARN以上的日志 -->
32                 <Filters>
33                     <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY" />
34                 </Filters>
35                 <PatternLayout pattern="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
36                 <Policies>
37                     <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
38                     <SizeBasedTriggeringPolicy/>
39                 </Policies>
40             </RollingFile>
41     
42         </appenders>
43     
44         <!--然后定义logger,只有定义了logger并引入了appender,appender才会生效-->
45         <loggers>
46             <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
47             <logger name="org.springframework" level="INFO"></logger>
48             <logger name="org.mybatis" level="INFO"></logger>
49             <root level="all">
50                 <appender-ref ref="Console"/>
51                 <appender-ref ref="Test"/>
52                 <appender-ref ref="RollingFileInfo"/>
53                 <appender-ref ref="RollingFileError"/>
54             </root>
55         </loggers>
56     </configuration>

 

 
  1. 记录日志

private static final Logger logger = LoggerFactory.getLogger(Xxxx.class);

4. 导入项目的语言版本问题

  • 本地新建项目的编译环境都是jdk1.8,但对于导入的项目,可能会出现其他language level,彻底解决办法为pom.xml中添加jdk1.8插件

     1 <plugin>
     2       <groupId>org.apache.maven.plugins</groupId>
     3       <artifactId>maven-compiler-plugin</artifactId>
     4       <version>3.2</version>
     5       <configuration>
     6           <source>1.8</source>
     7           <target>1.8</target>
     8           <encoding>UTF-8</encoding>
     9       </configuration>
    10 </plugin>

5. 集合相关

  • TreeMap

TreeMap中存入的自定义类对象元素必须实现Comparable接口,或者创建TreeMap对象时构造器传入比较器,否则tm.put()直接报错。jdk对String类型、Integer类型等默认实现了Comparable接口

  
1 TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
2       @Override
3       public int compare(Student o1, Student o2) {
4           int num = o1.getAge() - o2.getAge();
5           return num == 0 ? o1.getName().compareTo(o2.getName()) : num;
6       }
7   })
  • Collections工具类常用方法

1   replaceAll(List<T> list, T oldVal, T newVal) //将列表中所有出现的指定值替换为另一个值。
2   reverse(List<?> list) //反转指定列表中元素的顺序。
3   shuffle(List<?> list) //将指定列表随机排序。 
4   sort(List<T> list, Comparator<? super T> c) //根据指定的比较器对列表排序,默认自然排序。
  • Arrays工具类常用方法

1   asList(T... a) //返回由指定数组支持的固定大小的列表。 
2   sort(T[] a, Comparator<? super T> c) //根据指定的比较器对对象数组排序,默认自然排序。 
3   static <T> Stream<T> stream(T[] array) //返回顺序Stream与指定的数组作为源。
  • 并发修改异常

对于List集合,迭代过程中,可以修改元素set,不能增删元素,增删会导致modcount++

1   Iterator<String> it = list.iterator();
2   while (it.hasNext()){
3       String element = it.next();
4       if(element.equals("hello")){
5           list.add("yangxun"); //迭代过程中增加元素会导致并发修改异常
6           list.remove(element);//迭代过程中删除元素会导致并发修改异常
7           list.set(list.indexOf(element),"yangxun");//迭代过程可以修改元素
8       }
9   }
  • HashSet存储元素分析

  1. 调用对象hashCode()方法获取对象的哈希值

  2. 根据哈希值计算对象在哈希表上的存储位置

  3. 如果该位置还未添加元素,就直接添加;如果已存在元素,按下述步骤

  4. 把对象和已存在的元素逐个比较哈希值,如果没有重复的哈希值,就直接添加

  5. 如果存在重复的哈希值,则继续调用equals()方法比较内容,如果内容不相同,则添加,如果内容相同,则不添加

  • ConcurrentHashMap的锁分段技术

HashTable容器在竞争激烈的并发环境下表现出效率低下的原因,是因为所有访问HashTable的线程都必须竞争同一把锁,那假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

 

6. Lambda表达式和方法引用

  1. Lambda表达式(调用接口方法处理参数)

  • Lambda表达式的使用前提

    • 有一个接口

    • 接口中有且仅有一个抽象方法

    • 在另一个方法中调用接口方法

  1. Lambda表达式的省略规则

  • 参数类型可以省略。有多个参数的情况下,全部都要

  • 如果参数有且仅有一个,那么小括号可以省略

  • 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字

 1 //有且仅有一个方法的接口
 2   public interface Addable {
 3       int add(int x, int y);
 4   }
 5   //调用接口方法
 6   public class LambdaDemo {
 7       public static void main(String[] args) {
 8           useEatable((1,2) -> add(1,2));
 9 10 11   //创建线程
12   Thread thread = new Thread(() -> {
13       System.out.print(“利用Lambda创建线程”);
14   });
15   Set set = new TreeSet<Student>((s1, s2) -> s1.getAge() - s2.getAge())
  1. 方法引用(Lambda调用接口方法中的逻辑正好为调用另一个类的方法)

方法引用是Lambda的孪生兄弟,方法引用是在Lambda的基础上使用的,当接口中仅有的一个方法【作用正好和其他类的方法相同】,则可以引用其他类的方法。方法引用符为::

  • 静态方法引用 类名::静态方法 Integer::parseInt

  • 成员方法引用 类名::成员方法 String::substring

  • 构造器引用 类名::new Student::new

 1   
 2   public class Student {
 3       private String name;
 4       private int age;
 5       public Student() {
 6       }
 7       public Student(String name, int age) {
 8           this.name = name;
 9           this.age = age;
10       }
11   }
12   //接口中仅有的一个方法的作用是返回一个Student实例对象,和Student类的构造作用一样
13   public interface StudentBuilder {
14       Student build(String name,int age);
15   }
16   //方法引用
17   public class StudentDemo {
18       public static void main(String[] args) {
19           //Lambda简化写法
20           useStudentBuilder((name,age) -> new Student(name,age));
21           //引用构造器
22           useStudentBuilder(Student::new);
23       }
24   }

 

7. 逻辑(没有变量就新建变量)

  1. 页面:查询显示页面所有的元素 ——》2. 鼠标点击,触发元素状态改变 ——》3. 元素没有变量,则新建变量记录元素状态的变化

  2. 代码:业务代码 ——》2. 业务逻辑改变 ——》3. 建立变量记录业务逻辑状态的改变,两个状态用true/false标记状态;两个以上(n)状态用(i % n)标记状态


 

8. 接口开发规范

  • 8.1 Api请求及响应规范

为了严格按照接口进行开发,提高效率,对请求及响应格式进行规范化。

1、get 请求时,采用key/value格式请求,SpringMVC可采用基本类型的变量接收,也可以采用对象接收。

2、Post请求时,可以提交form表单数据(application/x-www-form-urlencoded)和Json数据(Content-Type=application/json),文件等多部件类型(multipart/form-data)三种数据格式,SpringMVC接收Json数据使用@RequestBody注解解析请求的json数据。

4、响应结果统一信息为:是否成功、操作代码、提示信息及自定义数据。

5、响应结果统一格式为json。

  • 8.2 Api定义约束

Api定义使用SpringMVC来完成,由于此接口后期将作为微服务远程调用使用,在定义接口时有如下限制:

1、@PathVariable 统一指定参数名称,如:@PathVariable("id")

2、@RequestParam统一指定参数名称,如:@RequestParam("id")


9. sql语句书写规则

  1. 确定子查询,求出位置条件

    • 当子查询的结果为单行单列, 可以作为where 字句的拼接条件

    • 当子查询的结果为多行单列, 可以作为 IN() 拼接条件

    • 当子查询的结果是多行多列的, 可以作为一张虚拟表进行复合查询

  2. 罗列表名

  3. 拼接条件(确定是否需要使用外连接:是否需要显示某表未匹配的记录——1. 主表中未参与副表外键约束的记录;2. 副表中外键字段为null的记录)

  4. 罗列笛卡尔积根据条件筛选后需要显示的字段


 

10. 通用响应结果

  1. 通用状态码枚举类

 1 public enum CommonCode {
 2       /**操作成功*/
 3       SUCCESS(10000,true,"操作成功!"),
 4       /**操作失败*/
 5       FAIL(11111,false,"操作失败!"),
 6       /**权限不足*/
 7       UNAUTHENTICATED(10002,false,"权限不足!"),
 8       /**非法参数*/
 9       INVALID_PARAM(10003,false,"非法参数!"),
10       /**系统错误*/
11       SERVER_ERROR(10004,false,"抱歉,系统繁忙!");
12   ?
13       int code;
14       boolean success;
15       String message;
16   ?
17       CommonCode(int code, boolean success, String message) {
18           this.code = code;
19           this.success = success;
20           this.message = message;
21       }
22       public int getCode() {
23           return code;
24       }
25       public boolean isSuccess() {
26           return success;
27       }
28       public String getMessage() {
29           return message;
30       }
31   }
  1. 响应结果,默认操作成功,无返回信息,可自行扩展

 1  public class ResponseResult {
 2       int code = 10000;
 3       boolean success = true;
 4       String message;
 5   ?
 6       public ResponseResult() {
 7       }
 8   ?
 9       public ResponseResult(CommonCode commonCode) {
10           this.code = commonCode.getCode();
11           this.success = commonCode.isSuccess();
12           this.message = commonCode.getMessage();
13       }
14   }
  1. 自定义扩展的分页查询响应结果

 1   
 2   public class QueryPageResult<T> extends ResponseResult {
 3       /**当前页码*/
 4       int pageNum;
 5       /**总记录数*/
 6       long totalCount;
 7       /**每页大小*/
 8       int pageSize;
 9       /**总页数*/
10       int totalPage;
11       /**记录*/
12       List<T> pageList;
13   ?
14       //setter/getter方法略。。。
15   }
  1. 自定义异常响应结果

 //自定义异常类
  public class CustomException extends RuntimeException {
       /**错误状态吗*/
      CommonCode commonCode;
      public CustomException(CommonCode commonCode){
          this.commonCode = commonCode;
      }
      public CommonCode getCommonCode() {
          return commonCode;
      }
  }
  ?
  //统一定义异常抛出类
  public class ExceptionCast {
      public static void cast(CommonCode commonCode){
          throw new CustomException(commonCode);
      }
  }
  ?
  //自定义异常捕获类
  @ControllerAdvice
  @ResponseBody
  public class ExceptionCatch {
      public static final Logger logger = LoggerFactory.getLogger(ExceptionCast.class);
  ?
      /**捕获所有的自定义异常,并响应前端ResponseResult*/
      @ExceptionHandler(CustomException.class)
      public ResponseResult customException(CustomException customException){
          //记录异常日志
          logger.error("catch exception:{}",customException.getCommonCode().getMessage());
          return new ResponseResult(customException.getCommonCode());
      }
  ?
      /**捕获不可预知的系统异常,并响应前端ResponseResult*/
      @ExceptionHandler(Exception.class)
      public ResponseResult exception(Exception exception){
          //记录异常日志
          logger.error("catch exception:{}",exception.getMessage());
          //统一响应99999,系统繁忙异常
          return new ResponseResult(CommonCode.SERVER_ERROR);
      }
  }

11. 输出html页面内容

由于是要输出html页面内容,所以不能用RestController注解,否则输出json数据,而应该直接用Response将页面内容输出

 1   @Controller
 2   public class CmsPagePreviewController extends BaseController {
 3       @Autowired
 4       private PageService pageService;
 5   ?
 6       @GetMapping("/cms/preview/{pageId}")
 7       public void preview(@PathVariable("pageId") String pageId) throws Exception {
 8           //执行静态化
 9           String pageHtml = pageService.getPageHtml(pageId);
10           //通过response将内容输出
11           ServletOutputStream outputStream = response.getOutputStream();
12           outputStream.write(pageHtml.getBytes("utf-8"));
13       }
14   }

 


 

12. 链表、树状结构查询

数据类型递归定义:直接定义节点,节点中嵌套子节点(或者子节点数组),

1 Node extends TargetModel(Node、List<Node>2 
4   @Data
5   @ToString
6   public class TeachplanNode extends Teachplan {
7       List<TeachplanNode> children;
8   }

 

  • 树形结构的sql查询语句

 1  SELECT 
 2     a.id AS one_id,
 3     a.pname AS one_pname,
 4     b.id AS two_id,
 5     b.pname AS two_pname,
 6     c.id AS three_id,
 7     c.pname AS three_pname 
 8   FROM
 9     teachplan a 
10     LEFT JOIN teachplan b 
11       ON a.id = b.parentid 
12     LEFT JOIN teachplan c 
13       ON b.id = c.parentid 
14   WHERE a.parentid = 0 ;

 


13. Mapper.xml异常

Mybatis报 "There is no getter for property named ‘xxxx‘ in ‘class java.lang.String‘",解决方法

 1   <select id="selectList" parameterType="java.lang.String" resultMap="teachplanMap">
 2           SELECT
 3             *
 4           FROM
 5             teachplan a
 6           WHERE a.parentid = 0
 7           <if test="courseId != null and courseId != ‘‘">
 8               and a.courseid = #{courseId}
 9           </if>
10       </select>

 

将sql语句中的courseId改为_parameter传参


14. Spring框架常用工具类

 

15. 页面获取跳转url传参(&name=)

1   //todo 获取静态页面跳转传参的工具
2   function getQueryString(name){
3       let reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
4       let r = window.location.search.substr(1).match(reg);
5       if(r!=null)return unescape(r[2]); return null;
6   }
7   ?
8   //调用方法
9   var name = getQueryString("name");

16. commons.io#IOUtils、FileUtils、FileNameUtils、FileFilterUtils

<dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.3</version>
  </dependency>
  • FileUtils.copyDirectoy():拷贝目录,可以用过滤器对文件进行过滤

1  
2   File srcDir = new File("E:\\IdeaProjects\\ssm\\srcDir");
3   File destDir = new File("E:\\IdeaProjects\\ssm\\destDir");
4   IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
5   //可以接多个过滤器
6   IOFileFilter fileFilters = FileFilterUtils.and(txtSuffixFilter);
7   FileUtils.copyDirectory(srcDir,destDir,fileFilters);

 

  • FileUtils.copyFile(File srcFile, File destFile):拷贝文件

  • FileUtils.copyFileToDirectory(File srcFile, File destDir):拷贝文件到目标目录

  • FileUtils.copyInputStreamToFile(InputStream source, File destination):将一个输入流中的内容拷贝到目标文件

  • IOUtils.copy(InputStream input, OutputStream output):拷贝字节流

  • IOUtils.copy(InputStream input, Writer output, String encoding):拷贝字符流

  • IOUtils.copyLarge(InputStream input, OutputStream output):用于拷贝超过2G的流

  • List<String> IOUtils.readLines(Reader input):按行读取输入流到字符串集合

  • IOUtils.toString(Reader input):读取输入流为字符串

  • IOUtils.write(String data, Writer output):将字符串写为输出流


 

17. 发送消息内容用字符串

  
 Map msgMap = new HashMap<>();
  msgMap.put("pageId",pageId);
  String msg = JSON.toJSONString(msgMap);
  String siteId = cmsPage.getSiteId();
  rabbitTemplate.convertAndSend(RabbitmqConfig.EX_ROUTING_POSTPAGE,siteId,msg);

 

 

18. pagehelper-spring-boot-starter

  
nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration.
Cause: com.github.pagehelper.PageException:java.lang.ClassNotFoundException: mysql

原因是:配置分页插件数据库不在是dialect,而是helperDialect,并且支持自动检测当前的数据库链接,因此不用配置也是 ok 的啦,配置为pagehelper.helperDialect:mysql。


 

19. springMVC配置fastJson

 1   
 2   <!--使用fastjson替换springMVC默认集成的jackson转换器-->
 3   <mvc:annotation-driven>
 4       <mvc:message-converters register-defaults="true">
 5           <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
 6               <property name="supportedMediaTypes" value="application/json"/>
 7               <property name="features">
 8                   <list>
 9                       <value>WriteMapNullValue</value>
10                       <value>WriteDateUseDateFormat</value>
11                   </list>
12               </property>
13           </bean>
14       </mvc:message-converters>
15   </mvc:annotation-driven>

 

 


20. js中日期格式化工具

  
 1 Date.prototype.Format = function(fmt)
 2   { //author: meizz
 3   var o = {
 4   "M+" : this.getMonth()+1,                 //月份
 5   "d+" : this.getDate(),                    //
 6   "h+" : this.getHours(),                   //小时
 7   "m+" : this.getMinutes(),                 //
 8   "s+" : this.getSeconds(),                 //
 9   "q+" : Math.floor((this.getMonth()+3)/3), //季度
10   "S"  : this.getMilliseconds()             //毫秒
11   };
12   if(/(y+)/.test(fmt))
13   fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
14   for(var k in o)
15   if(new RegExp("("+ k +")").test(fmt))
16   fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
17   return fmt;
18   }
19   ?
20   //调用方法
21   var time1 = new Date().Format("yyyy-MM-dd hh:mm:ss"); //2019-09-24 15:30:45
22   var time2 = new Date().Format("yyyy-MM-dd"); //2019-09-24

 


 

21. nginx配置反向代理

  
 1 #定义被代理服务
 2   upstream static_server_pool {
 3       server 127.0.0.1:91 weight=10;
 4   }
 5   ?
 6   server {
 7       listen       80; #主站端口
 8       server_name  www.xuecheng.com; #主站域名
 9       ssi  on; #开启SSI服务端嵌入功能
10       ssi_silent_errors  on;
11       location / { #门户主站的物理路径
12           alias   E:/WebstormProjects/xcEduUI/xc-ui-pc-static-portal/;
13           index  index.html;
14       }
15       
16       #访问路径为www.xuecheng.com/course/detail/....时,跳转至被代理服务路径static_server_pool/course/detail/....
17       location /course/detail/ { 
18           proxy_pass http://static_server_pool;
19       }
20 21   ?
22   server {
23       listener 91;
24       server_name localhost;
25       
26       location /course/detail { #被代理服务访问路径的物理路径
27           alias  E:/WebstormProjects/xcEduUI/xc-ui-pc-static-portal/course/detail/;
28       }
29   }

 

 

22. 通用mapper实现多字段排序

  
1   // 测试通用mapper先按category_id1字段升序,再按count_date降序进行排序查询
2   @Test
3   public void testMultiClauseOrder(){
4       Example example = new Example(CategoryReport.class);
5       example.orderBy("categoryId1").asc().orderBy("countDate").desc();
6       List<CategoryReport> categoryReports = categoryReportMapper.selectByExample(example);
7       System.out.println(categoryReports);
8   }

 


 

23. 通用mapper非单表操作属性映射

对于非单表操作查询结果和实体类属性匹配的情况,或者和自定义实体类属性匹配的情况,必须通过取别名的方式,手动指定表字段与非表对应实体类属性名的映射关系

  
 1 -- 通过别名,指定tb_order和tb_orderitem的查询结果字段与CategoryReport的属性映射
 2   SELECT 
 3     oi.`category_id1` AS categoryId1,
 4     oi.`category_id2` AS categoryId2,
 5     oi.`category_id3` AS categoryId3,
 6     DATE_FORMAT(o.`pay_time`, %Y-%m-%d) AS countDate,
 7     SUM(num) AS num,
 8     SUM(o.`pay_money`) AS money 
 9   FROM
10     tb_order_item AS oi,
11     tb_order AS o 
12   WHERE o.`id` = oi.`order_id` 
13     AND o.`pay_status` = 1 
14     AND o.`is_delete` = 0 
15     AND DATE_FORMAT(o.`pay_time`, %Y-%m-%d) = 2019-08-23 
16   GROUP BY oi.`category_id3` 
17   -- 通过别名,指定tb_category_report和v_category的查询结果字段对应的属性名
18   SELECT 
19     category_id1 AS categoryId1,
20     NAME AS categoryName,
21     count_date AS countDate,
22     SUM(num) AS num,
23     SUM(money) AS money 
24   FROM
25     tb_category_report cr,
26     v_category c 
27   WHERE count_date >= 2019-08-23  -- 对于mysql中的Date类型数据,可以传入Date类型数据操作
28     AND count_date <= 2019-08-24  -- 也可以传入‘yyyy-MM-dd’标准格式的日期字符串操作
29     AND category_id1 = c.id 
30   GROUP BY category_id1 

 


 

24. Hutool Java工具包

  
 <!--Hutool Java工具包-->
  <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>4.5.7</version>
  </dependency>

 

 

 

杂项随记

原文:https://www.cnblogs.com/luboyan2524/p/11788597.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!