JPA & Java

JAP

  1. @Entity

  2. @Table

  3. @Id

  4. @Query

  5. Sort sort = new Sort(Sort.Direction.DESC, “id”); —→ findAll(sort)

  6. Pageable pageable=PageRequest.of(0,5); 第一页 一页5条

  7. extends JpaRepository<T, ID>

  8. List findByUsername(String username)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    interface PersonRepository extends Repository<User, Long> {
    // and 的查询关系
    List<User> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
    // 包含 distinct 去重,or 的 sql 语法
    List<User> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
    // 根据 lastname 字段查询忽略大小写
    List<User> findByLastnameIgnoreCase(String lastname);
    // 根据 lastname 和 firstname 查询 equal 并且忽略大小写
    List<User> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
    // 对查询结果根据 lastname 排序,正序
    List<User> findByLastnameOrderByFirstnameAsc(String lastname);
    // 对查询结果根据 lastname 排序,倒序
    List<User> findByLastnameOrderByFirstnameDesc(String lastname);
    }

![Untitled](D:\hexo warehouse\myblog\source_posts\Untitled-16690181602452.png)

link: Spring Data JPA - Reference Documentation

(16条消息) SpringDataJpa的使用 – 条件查询、排序查询、分页查询_十⑧的博客-CSDN博客_jpa 条件查询

stream

  1. list.stream().map(People::getAge)
  2. filter(i -> i > 5)
  3. count()
  4. collect(Collectors.toList()
  5. People::getAge

tree

  1. code parent_code (queryProcessTree)

    1. 找父节点
    2. 遍历寻找子节点
    3. 递归
    4. 封装数据返回
  2. queryLazyProcessTree 懒加载去除孩子节点数据(估计前端点击展开后继续往下查询)

    1. 找父节点
    2. 找所有ChildNode
    3. isleaf = ChildNode.getParentCode.equals(ParentsCode).count==0 ? false : true
    4. 封装返回
  3. recursive sql

1
2
3
4
5
6
with recursive temp(id,username,pid,pname) AS (
SELECT k.id,k.username,k.pid,k.username from t_parent_kid k WHERE k.username='B'
UNION ALL
SELECT k.id,k.username,t.id,t.username from temp t,t_parent_kid k WHERE t.id=k.pid
)
SELECT * from temp

![Untitled 1](D:\hexo warehouse\myblog\source_posts\Untitled 1-16690181860235.png)

![Untitled 2](D:\hexo warehouse\myblog\source_posts\Untitled 2-16690181910378.png)

union all / union

uniall 整合两张表 上下连接,去重

uniall all 整合两张表 上下连接,列出全部

学习并发

学习并发

  1. 创建线程的方式

    • 继承Thread类创建

      • 已经继承的类无法使用

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        public class ExtendThread extends Thread {

        }

        @Test
        void test1() {
        ExtendThread extendThread = new ExtendThread();
        log.info("threadId:{}", extendThread.getId());
        log.info("threadName:{}", extendThread.getName());
        log.info("threadState:{}", extendThread.getState());
        log.info("threadPriority:{}", extendThread.getPriority());
        }
    • 实现Runnable接口

      • 可以使用匿名对象来进行实现,减少代码

        1
        2
        3
        4
        5
        6
        7
        @Test
        void test4(){
        Thread thread = new Thread(()->{
        System.out.println("lambda+匿名对象类");
        },"threadName");
        thread.start();
        }
    • 利用Callable和FutureTask创建

      • 异步?
    • 通过线程池创建

      • 减少线程创建、销毁时间

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        private static ExecutorServicepool= Executors.newFixedThreadPool(3);

        static class DemoThread implements Runnable{
        @SneakyThrows
        @Override
        public void run() {
        for (int i = 0; i < 10; i++) {
        log.info("execute times of runnable thread:{}",i);
        }
        }
        }

        static class ReturnableTask implements Callable<Long>{
        public Long call() throws Exception{
        long startTime = System.currentTimeMillis();
        for (int i = 0; i <10; i++) {
        log.info("execute times of Callable Thread:{}",i);
        }
        long used = System.currentTimeMillis() - startTime;
        return used;
        }
        }

        @Test
        public void test5() throws ExecutionException, InterruptedException {
        pool.execute(new DemoThread());
        // 无返回值

        Future future =pool.submit(new ReturnableTask());
        Long result = (Long) future.get();
        log.info("异步的结果为:{}",result);
        // 有返回值
        }
  2. 线程池

    1. 创建线程池

      1. 固定数量线程池

        1. ExecutorService pool = Executors.newFixedThreadPool(3);
      2. 缓存线程池

        1. ExecutorService pool = Executors.newCachedThreadPool();
      3. 定时执行线程池

        1. ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
      4. 线程池标准创建方式

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        public class ThreadPoolExecutor{
        // 核心线程数,即使线程空闲(Idle),也不会回收;
        int corePoolSize;

        // 线程数的上限;
        int maximumPoolSize;

        // 线程最大空闲(Idle)时长
        long keepAliveTime;

        //单位?
        TimeUnit unit;

        // 任务的排队队列
        BlockingQueue<Runnable> workQueue;

        // 新线程的产生方式
        ThreadFactory threadFactory;

        // 拒绝策略
        RejectedExecutionHandler handler;
        }
    2. 向线程池提交的方式

      1. execute
        1. 只能接收Runnable类型的参数
        2. 没有返回值
        3. 不利于异常捕获
      2. submit
        1. 能接受Runnable 和 Callable
        2. 有返回值
        3. 可以通过返回的Future(异步执行实例)对象来进行异常捕获
    3. 线程工厂

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void test9() {
    ExecutorService my_pool = Executors.newFixedThreadPool(2, new My_thread_factory());

    for (int i = 0; i < 5; i++) {
    my_pool.execute(new Task());
    }
    pool.shutdown();
    }
  3. 线程安全

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    package com.example.jc_demo.ThreadTest;

    import lombok.extern.slf4j.Slf4j;
    import org.junit.jupiter.api.Test;

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;

    /**
    *@AUTHOR:gao_quansui
    *@USER:ASUS
    *@DATE:2022/10/13 - 15:43
    *@PROJECT_NAME:jc_demo
    */

    @Slf4j
    public class ThreadSecurity {

    private static intcount= 0;

    class increaseVariable implements Runnable {
    @Override
    public void run() {
    plus();
    }
    }

    // synchronized 关键字设置同步方法 为粗粒度 整个方法都保护为一个线程执行
    // 相反 synchronized 代码块为细粒度 只保证代码块中的被一个线程执行
    public synchronized void plus() {
    count++;
    }

    @Test
    public void test1() throws InterruptedException {
    ExecutorService pool = Executors.newFixedThreadPool(30);
    for (int i = 0; i < 10000; i++) {
    pool.submit(new increaseVariable());
    }

    Thread.sleep(500);

    pool.shutdown();

    log.info(String.valueOf(count));
    }

    }

Guava相关操作

Guava相关操作

Description

(12条消息) Guava的基础功能与集合_鲲鹏飞九万里的博客-CSDN博客_guava

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
package com.example.jc_demo;

import cn.hutool.core.date.DateUtil;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.*;

@Slf4j
public class GuavaTest {
@Data
@AllArgsConstructor
@NoArgsConstructor
class User {
String name;
}

@Test
public void my_Optional() {
Optional<Integer> op = Optional.ofNullable(new Integer(123));
log.info(op.get().toString());
}

@Test
public void returnUser() {
User u = new User();
u = null;
// 如果不用ofNullable会有空指针异常 用ofNullable能够在get()的时候报出空元素异常
Optional<User> op = Optional.ofNullable(u);
User u1 = op.get();
log.info(u1.toString());
}

@Test
public void orElse() {
// ???防止空指针 备用值??? IFNULL???
Optional<String> op = Optional.of("aaa");
log.info(String.valueOf(op.isPresent()));
log.info(op.orElse(null));
}

@Test
public void isPresent() {
Optional<String> op = Optional.of("2322");
log.info(String.valueOf(op.isPresent()));

Optional<String> op1 = Optional.ofNullable(null);
log.info(String.valueOf(op1.isPresent()));
}

//

@Test
public void my_Preconditions() {
int i = -1;
int j = 10;
String k = null;
// Preconditions.checkArgument(i > j, "%s is not bigger than %s", i, j);
// Preconditions.checkNotNull(k,"k is null");
// Preconditions.checkArgument("1".equals("2"),"1 is not equals 2");

// int[] arr = new int[10];
// Preconditions.checkElementIndex(20,arr.length);
}

@Test
public void myImmutableSet() {
/**
* 三种方式创建 只读数组
* 1.of
* 2.builder
* 3.copy
*
* 注意:不可放入null
*/
ImmutableSet<String> immutableSet = ImmutableSet.of("a", "b", "c");
immutableSet.forEach(e->{
log.info(e);
});
// java.lang.UnsupportedOperationException 不允许操作数组, 只读
// immutableSet.add("d");

ImmutableSet<String> immutableSet1 = ImmutableSet.<String>builder()
.add("a")
.add("b")
.add("c")
.build();

immutableSet1.forEach(e->{
log.info(e);
});
// java.lang.UnsupportedOperationException 不允许操作数组, 只读
// immutableSet1.add("d");

// ImmutableSet<String> immutableSet3 = ImmutableSet.copyOf(arrayList);

}

@Data
@AllArgsConstructor
@NoArgsConstructor
private class Device {
Date CreatTime;
Date UpdateTime;
}

@Test
public void my_Order() {
Ordering ordering = new Ordering<String>() {
// order by length
@Override
public int compare(String s, String t1) {
return s.length() > t1.length() ? new Integer(1) : new Integer(-1);
}
};

ArrayList<String> list = new ArrayList<>();
list.add("sadewf");
list.add("sadewfsda");
list.add("sadewfsdaasdfeao");
list.add("aadewfsdaasdfea");
list.add("zoad");
list.add("zoadnas");
list.add("doadn");
list.add("doadnsadasda");
list.add("zoadnasodnaosndaosd");

//ascii ?
Collections.sort(list);
My_ForEach(list);

Collections.sort(list, ordering);
My_ForEach(list);

Collections.reverse(list);
My_ForEach(list);

}

@Test
public void order2() {
// 链式调用 从右往左调用,先orderBy XXX 将Null放最前或最后 对剩下的自然排序
Ordering<Device> ordering1 = Ordering.natural().nullsFirst().onResultOf((Device device) -> device.CreatTime);
Ordering<Device> ordering2 = Ordering.natural().nullsLast().onResultOf((Device device) -> device.CreatTime);
List<Device> list1 = new ArrayList<>();
list1.add(new Device(DateUtil.parse("2022-1-1", "yyyy-MM-dd"), null));
list1.add(new Device(null, null));
list1.add(new Device(DateUtil.parse("2022-1-8", "yyyy-MM-dd"), null));
list1.add(new Device(DateUtil.parse("2021-1-7", "yyyy-MM-dd"), null));
list1.add(new Device(DateUtil.parse("2022-5-1", "yyyy-MM-dd"), null));
list1.add(new Device(DateUtil.parse("2022-1-7", "yyyy-MM-dd"), null));
list1.add(new Device(DateUtil.parse("2022-3-1", "yyyy-MM-dd"), null));
list1.add(new Device(DateUtil.parse("2022-6-1", "yyyy-MM-dd"), null));

Collections.sort(list1, ordering2);

My_ForEach(list1);
}

@Test
public void isOrder() {
List<String> list = new ArrayList<>(Arrays.asList("a", "asd", "b", "asdve"));

// 返回降序前两个
List<String> list1 = Ordering.natural().greatestOf(list, 2);
// 返回升序后两个
List<String> list2 = Ordering.natural().leastOf(list, 2);

My_ForEach(list1);
My_ForEach(list2);
}

public void My_ForEach(List list) {
if (list.size() > 0) {
list.forEach(e -> {
log.info(e.toString());
});
} else {
log.error("空集合");
}
log.info("=======================================================");
}
}