java学习-笔记(1)

目录

知识点一:公共字段填充

知识点二:ThreadLocal类

知识点三:Super关键字

知识点四:MultipartFile工具类

知识点五:Map的6种遍历方式

知识点六:JAVA的流式编程

知识点七:postMapping、putMapping、getMapping、deleteMapping 


 

九月第二周的笔记(1)

知识点一:公共字段填充

问题1:在项目中新增员工时候需要设置创建时间,修改时间,修改人姓名等字段,在编辑员工时需要设置的字段,有的属于公共字段,能不能对公共字段在某一个地方进行统一处理,来简化开发,Mybatis Plus 提供了公共字段填充功能。

实现步骤

步骤1:在实体类的属性上加上@TableField注解,指定自动填充的策略

步骤2:按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要要实现MetaObjectHandler接口

@TableField(fill = FieldFill.INSERT):插入时填充字段

@TableField(fill = FieldFill.INSERT_UPDATE):插入和更新时填充字段

知识点二:ThreadLocal类

问题2:在自动填充createUser和UpdateUser两个字段的时候设置的用户id是固定值,应该动态的获得当天用户固定的值

//这个类是不能获得HttpSession对象的

//客户端发送的每次HTTP请求,对应的在服务器端会分配一个新的线程来处理,在处理过程中设计到下面类中的方法都属于同一个线程

//LgoninCheckFilter的doFilter方法

//EmployeeController的update方法

//MyMetaObjectHandler的updateFill方法

//可以在上面的三个方法中分别加入下面的代码获取当前线程

1.什么是ThreadLocal类?

ThreadLocal — это не поток, а переменная потока. При использовании ThreadLocal для хранения переменных ThreadLocal предоставляет независимую копию переменной для каждого потока, использующего эту переменную, поэтому каждый поток может независимо изменять свою собственную копию, не влияя на копии, соответствующие другим потокам. ThreadLocal предоставляет отдельное пространство для хранения для каждого потока, что обеспечивает эффект изоляции потока. Соответствующее значение можно получить только внутри потока и к нему нельзя получить доступ вне потока.

2. Общие методы ThreadLocal

Public void set(T value) Установить значение локальной переменной текущего потока.

Public T get() возвращает значение локальной переменной потока, соответствующей текущему потоку.

3. Вы можете получить текущий идентификатор вошедшего в систему пользователя в методе doFilter LoginCheckFilter, вызвать метод set ThreadLocal, чтобы установить значение локальной переменной (идентификатор пользователя) текущего потока, а затем вызвать метод get ThreadLocal. в методе updateFill MyMetaObjectHandler, чтобы получить текущий поток.Значение соответствующей локальной переменной потока (идентификатор пользователя).

4. Конкретные методы реализации

Шаг 1. Напишите класс инструмента BaseContext на основе инкапсуляции ThreadLocal.

Шаг 2. Вызовите BaseContext в методе doFiter метода loginCheckFilter, чтобы установить текущий идентификатор пользователя для входа в систему.

Шаг 3. Вызовите BaseContext в методе класса MyMetaObjectHandler, чтобы получить идентификатор входа пользователя.

Пункт знаний третий: ключевое слово Super
  • Вы можете ссылаться на члены родительского класса:
  • Super может получить доступ к свойствам, определенным в родительском классе; super.xxx
  • Suoer может получить доступ к методам-членам, определенным в родительском классе; super.xxx()
  • Super может вызвать метод родительского класса в конструкторе подкласса. super(): конструктор без параметров; super(xxx) имеет конструктор параметров.
  • Меры предосторожности:
  • Если подкласс и родительский класс имеют одинаковое имя атрибута, используйте super, если вы хотите использовать атрибуты родительского класса в подклассе.
  • Super можно применять только к методам-членам и конструкторам и нельзя использовать в статических методах.
  • Если используется в конструкторе, его необходимо разместить в первой строке.
  • Super() и this() не могут одновременно появляться в конструкторе.
Пункт знаний 4: Класс инструмента MultipartFile

String getName возвращает имя параметра

Строка getOriginalFilename возвращает тип содержимого файла.

Строка getContentType

Byte[] getBytes[] throw IOException Преобразовать содержимое файла в массив byte[]

void TransferTo(File var1) выдает исключение IOException, TransferTo копирует файл файла в указанное место (например, на диске D), в противном случае файл исчезнет после выполнения программы. Когда программа запущена, она будет временно хранится во временной папке.

Пункт знаний 5: 6 способов перемещения по карте

Первый способ:

for-each,+keySet()/values()遍历key/Value

KeySet(): получить все ключи Su;

Values(): получить все значения

HashMap<String, Integer> map1 = new HashMap<>();
map1.put("小明", 1);
map1.put("小红", 2);
map1.put("小张", 3);
//for-each + keySet()遍历key
for (String key : map1.keySet()) { //遍历key
    System.out.println("key = " + key);
}	
//for-each + values()遍历value
for (Integer value : map1.values()) { //遍历value
    System.out.println("value = " + value);

Второй способ:

Для каждого обхода +entrySet()

метод enterSet(): получить все объекты пары ключ-значение

for (Map.Entry<String, Integer> entry : map1.entrySet()) { 
    System.out.print("key = " + entry.getKey());
    System.out.println(", value = " + entry.getValue());
}

Третий способ:

обход метода for-each +KeySet()+get()

Метод Get(): передать значение ключа и вернуть соответствующее значение;

Обычно не рекомендуется, поскольку дополнительный этап поиска значения на основе значения ключа будет относительно медленным.

Базовая реализация метода map.get(key):

Сначала вызовите метод Hashcode для Key, чтобы получить хэш-значение, получить соответствующий индекс массива с помощью алгоритма хеширования и быстро найти определенную позицию с помощью индекса массива. Если в этой позиции ничего нет, верните ноль. Если эта позиция Если есть является односторонним связным списком, то параметр k будет сравниваться с k каждого узла в односвязном списке (equals()). Если все узлы возвращают false, то метод в конечном итоге вернет значение null. Если есть узел k соответствует нашему k, то значение, соответствующее узлу k, является искомым значением.

for (String key : map1.keySet()) {
    Integer value = map1.get(key);
    System.out.print("key = " + key);
    System.out.println(", value = " + value);
}

Четвертый способ:

Обход Iterator+entrySet()

Метод iterator(): возвращает итератор для обхода текущей коллекции.

Iterator<Map.Entry<String, Integer>> iter = map1.entrySet().iterator();
while (iter.hasNext()) {
    Map.Entry<String, Integer> entry = iter.next();
    System.out.print("key = " + entry.getKey());
    System.out.println(", value = " + entry.getValue());
}

Пятый способ:

обход лямбда-выражения

Метод Foreach перебирает каждый элемент массива и выполняет операции.

//lambda表达式遍历
map1.forEach((key, value) -> {
    System.out.print("key = " + key);
    System.out.println(", value = " + value);
});

Шестой способ:

Поток потока для прохождения

Роль Stream: отличие от потока ввода-вывода, используемого для упрощения написания контейнеров.

map1.entrySet().stream().forEach((Map.Entry<String, Integer> entry) -> {
    System.out.print("key = " + 	entry.getKey());
    System.out.println(", value = " + entry.getValue());
});
Пункт знаний 6: Программирование потоков JAVA

 Введение в потоковое программирование:

Stream API — это новый метод обработки данных, представленный в Java. Он обеспечивает эффективный и простой в использовании способ работы с коллекциями данных. Stream API поддерживает функциональное программирование, которое позволяет нам выполнять операции с данными лаконично и элегантно. Есть две основные причины для использования Stream:

1. В большинстве случаев целью хранения объектов в коллекциях является их обработка, поэтому вы обнаружите, что основной фокус программирования смещается с коллекций на потоки.

2. Когда лямбда-выражения используются в сочетании со ссылками на методы и потоками, люди чувствуют себя автономно и плавно.

Общие промежуточные операции:

1.filter(Predicate<T> predicate): фильтровать элементы в потоке на основе заданного предиката.

2.map(Function<T, R> mapper): преобразовать каждый элемент в потоке в другой тип в соответствии с заданной функцией сопоставления.

3.flatMap(Function<T, Stream<R>> mapper):Преобразуйте каждый элемент в другой поток, а затем объедините все эти потоки в один поток.

4.distinct(): возвращает дедуплицированный поток, в котором каждый элемент появляется только один раз.

5.sorted(): Возвращает поток, отсортированный в естественном порядке.

6.sorted(Comparator<T> comparator): Возвращает отсортированный поток на основе заданного компаратора.

7.peek(Consumer<T> action): выполняет указанную операцию над каждым элементом в потоке, но не изменяет элементы в потоке. Обычно используется в целях отладки

 Изучите несколько распространенных операций, основанных на объекте User:

 static class User {
 
        private Integer id;
 
        private String name;
 
 
        public User(Integer id, String name) {
            this.id = id;
            this.name = name;
        }
 
        public Integer getId() {
            return id;
        }
 
        public void setId(Integer id) {
            this.id = id;
        }
 
        public String getName() {
            return name;
        }
 
        public void setName(String name) {
            this.name = name;
        }
 
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

1. для цикла

Используйте выражение foreach+Lambda;

        userList.forEach(user -> System.out.println(user.getId()));

2. Фильтр-фильтр соответствует условиям

 Используйте метод .stream ().filter(), чтобы отфильтровать объекты, соответствующие условиям, и, наконец, вернуть отфильтрованный список.

如下只获取到集合中用户id>2的所有用户:
Stream<User> satisfy = userList.stream().filter(user -> user.getId() > 2);
System.out.println("满足条件用户列表:" + satisfy.collect(Collectors.toList()));

3. Вы можете использовать .map для получения всех значений атрибутов пройденного объекта. После получения значений атрибутов мы можем переназначить атрибуты объекту или базовому типу объекта. Обычно он используется в сочетании с функцией Collect( ) метод.

 List<Integer> users = userList.stream().map(User::getId).collect(Collectors.toList());
System.out.println("用户id列表:" + users);

4. Метод Collect(): toList() и toSet(), toMap().

 Методы toList() и toSet() преобразуют сопоставленный поток в объект списка. toSet() удалит повторяющиеся объекты. Метод .map() необходим для сопоставления атрибутов объекта в списке.

// toList用法
List<Integer> list = userList.stream().map(User::getId).collect(Collectors.toList());
System.out.println("用户列表为: " + list);

  toMap() преобразует поток непосредственно в карту и не требует поддержки метода .map().

Map<Integer, String> map = userList.stream().collect(Collectors.toMap(User::getId, User::getName));System.out.println("用户map为: " + map);
Пункт знаний седьмой: postMapping, putMapping, getMapping, deleteMapping. 

HTTP предоставляет четыре способа взаимодействия с сервером: получение, публикацию, размещение и удаление.

  • get: эквивалент операции выбора запроса и не изменяет и не влияет на какую-либо информацию о содержимом на стороне сервера; getMapping
  • post: эквивалент операции вставки, которая добавляет данные и сохраняет их на сервере; postMapping
  • put: эквивалент операции обновления. Он не добавляет данные, а только изменяет информацию на стороне сервера; putMapping
  • delete: эквивалент операции удаления и используется для удаления ресурсов; deleteMapping

@RequestParam : назначает указанные параметры запроса формальным параметрам метода.

@RequestParam(required = false/true, value = «имя параметра», defaultValue = «») имя и значение эквивалентны, здесь используется значение, а значение рекомендуется;

1.value : имя параметра, внешний запрос должен использовать указанное имя параметра, иначе проект сообщит об ошибке ;

2.required : интерфейс запрашивает, содержит ли метод этот параметр. По умолчанию установлено значение true, что означает, что путь запроса должен содержать этот параметр. Если он не включен, будет сообщено об ошибке .

3. defaultValue : значение параметра по умолчанию. Если это значение установлено, require=true будет недействительным и автоматически будет установлено значение false. Если этот параметр не передан, будет использоваться значение по умолчанию.

Например, блоги?blogId=1.

 @PathVariable

Параметры-заполнители в URL-адресе  могут   быть привязаны к формальным параметрам метода обработки контроллера через @PathVariable  : { xxx } заполнители в URL-адресе могут быть привязаны к методу операции через @PathVariable(" xxx ") в формальных параметрах.

1. Строковое значение : вы можете указать имя параметра в заполнителе { }. Если вы указываете только атрибут значения, вы можете опустить имя атрибута. Если имя параметра в заполнителе совпадает с именем параметра в методе обработки , вы можете опустить этот атрибут. .

2. Имя строки : эквивалентно значению, существенной разницы между ним и значением нет. Просто укажите один из двух атрибутов.

3. требуется логическое значение : требуется ли оно, по умолчанию установлено значение true, то есть параметр должен быть включен в запрос, если он не включен, будет выдано исключение (необязательная конфигурация).

Например /блоги/1

@RequestBody

1. @RequestBody в основном используется для получения данных в строке json, передаваемой из внешнего интерфейса в серверный (данные в теле запроса); метод GET не имеет тела запроса, поэтому при использовании @RequestBody для получения данных интерфейсная часть не может использовать метод GET для отправки данных, но отправляет их с помощью POST и других методов.

2. Когда класс, соответствующий внутренней аннотации @RequestBody, собирает входной поток HTTP (включая тело запроса) в целевой класс (т. е. класс, стоящий за @RequestBody), он будет соответствовать соответствующему классу сущности на основе ключа в строка json.Атрибут, если совпадение согласовано и значение, соответствующее ключу в json, соответствует (или может быть преобразовано), когда требование типа соответствующего атрибута класса сущности выполняется, метод установки класса сущности будет вызван для присвоения значения атрибуту.
3. В строке json, если значение равно "", если соответствующий атрибут серверной части имеет тип String, то полученный атрибут имеет значение "". Если тип атрибута серверной части — Integer, Double и т. д., то полученное значение равно нулю.
4. Если в строке json указано значение NULL, серверная часть получит значение NULL.
5. Если параметр не имеет значения, то при передаче json-строки на бэкенд либо поле вообще не будет записываться в json-строку, либо при записи значения должно быть значение либо null, либо "" Сделаю.
 

Используйте заполнитель { } в аннотации @RequestMapping, чтобы идентифицировать переменную часть URL-адреса.
Используйте аннотацию @PathVariable в формальных параметрах метода обработки в контроллере, чтобы получить значение, переданное в { } в @RequestMapping, и привяжите его к Метод обработки определяется формальным параметром. 


//请求路径:http://127.0.0.1/user/tom
@RequestMapping(value="/user/{name}")
public String username(@PathVariable(value="name") String username) {
    return username;
}

 

おすすめ

転載: blog.csdn.net/m0_74890428/article/details/132855253