Статьи с тэгом «Java»

Hibernate и Spring Boot

20 мая 2018

Ранее мы уже рассматривали, как работать с базой данных через jdbc в статье Работа с БД в Spring Boot на примере postgresql. А сегодня возьмём Hibernate - самый популярный фреймворк для работы с БД - и убедимся, что он значительно облегчает реализацию типовых операций над сущностями.

Предположим, в БД у нас есть две сущности: страна и город. В одной стране может быть несколько городов (отношение «один-ко-многим»). Структура таблиц выглядит примерно так:

CREATE SEQUENCE country_id_seq;

CREATE TABLE country
(
  id integer NOT NULL DEFAULT nextval('country_id_seq'::regclass),
  name character varying(50NOT NULL,
  CONSTRAINT country_id_pk PRIMARY KEY (id)
);

CREATE SEQUENCE city_id_seq;

CREATE TABLE city
(
  id integer NOT NULL DEFAULT nextval('city_id_seq'::regclass),
  name character varying(50NOT NULL,
  country_id integer NOT NULL
);

И мы хотим совершать типовые действия над этими сущностями: просмотр всего списка, поиск по id, добавление, обновление и удаление записей. Для этого создадим типовой Spring Boot проект. В pom-файле нужно прописать следующий parent:

Читать полностью...

Тэги: Hibernate, Java, PostgreSQL, Spring, Spring Boot, maven, rest.


Работа с датой в Spring Boot

12 мая 2018

В предыдущих статьях мы уже создавали rest-приложение (Spring Boot Restful Service, Работа с БД в Spring Boot на примере postgresql). А теперь давайте рассмотрим, как работать с датой и временем в Spring Boot на уровне rest-запросов и на уровне БД.

Предположим, перед нами стоит задача фиксировать в специальной таблице все действия пользователя (регистрация, вход, выход и т.п.) Таблица для СУБД Postgres в самом простом случае будет выглядеть так:

CREATE TABLE user_action
(
   id serial NOT NULL
   action_date timestamp without time zone NOT NULL
   user_id integer NOT NULL
   action_type integer NOT NULL
   CONSTRAINT user_action_pk PRIMARY KEY (id)


Тип serial представляет собой поле, которое автоматически увеличивается на единицу для каждой новой записи, поэтому его удобно использовать в качестве первичного ключа для записи.

Тип timestamp without time zone позволяет хранить метку времени без привязки к часовому поясу.

user_id и action_type представляют собой числовые id пользователя и тип действия соответственно. В реальном приложении каждое из них должно быть внешним ключом на соответствующие таблицы, но в нашем примере для простоты такой привязки нет.

Читать полностью...

Тэги: Java, PostgreSQL, Spring Boot.


Коллекции в Java

8 мая 2018

Под коллекциями в программировании подразумевают объекты, которые хранят внутри себя какой-либо набор значений и предоставляют набор методов для обращения к этим значениям. В Java можно выделить 3 наиболее часто используемых типа коллекций: списки (list), наборы (set) и словари (map). При объявлении коллекции типизируются каким-либо типом, т.е. одна коллекция хранит данные одного типа.

Список (list)

Списки в Java реализуют интерфейс List, который, в свою очередь, расширяет интерфейс Collection. Список позволяет хранить любые значения, в том числе повторяющиеся. Итерация (обход) списка происходит в порядке добавления элементов. Т.е. элемент, добавленный первым, при итерации также будет первым.

List<String> list = new ArrayList<>();
list.add("яблоко");
list.add("ананас");
list.add("яблоко");
System.out.println(list); // На экране увидим: [яблоко, ананас, яблоко]

Две наиболее частые реализации интерфейса List - это ArrayList и LinkedList.

Читать полностью...

Тэги: Collections, Java.


Как получить параметры окружения в Java

7 мая 2018

Метод System.getProperties() возвращает список системных свойств (параметров окружения), доступных для данной виртуальной машины. Свойство представляет из себя пару «ключ-значение». Среди полученных свойств всегда можно обнаружить следующие:

Читать полностью...

Тэги: Java.


Запуск задач по расписанию в Spring Boot

4 мая 2018

Часто в приложениях возникает необходимость выполнять некоторые действия по расписанию, а не по запросу извне. Первое, что приходит на ум - это планировщик cron. Но если вы пишете приложение, используя Spring Boot, то можете реализовать похожий функционал, добавив всего пару аннотаций.

В качестве примера давайте создадим простой maven-проект. Затем пропишем в pom-файле Spring Boot как родителя для данного проекта:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.12.RELEASE</version>
</parent>

Также у вас должна быть секция build со стандартным содержимым:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Теперь добавим стандартный main-класс:

Читать полностью...

Тэги: Java, Spring, Spring Boot, maven.


Создание runnable jar файла с помощью maven

3 мая 2018

Понятие runnable jar или uber jar возникает тогда, когда вы задумываетесь о разворачивании вашего проекта на удалённом сервере. У вас должна быть уверенность в том, что в произвольном окружении, где окажется ваше приложение, в classpath будут все необходимые классы из используемых вами библиотек.

Конечно, никакой проблемы нет, если вы вообще не используете сторонние библиотеки. Но я уверен, что всё-таки используете, если только ваш проект не «Hello World».

Чтобы гарантировать наличие нужных версий всех библиотек, нам проще поставлять их вместе с нашим приложением. Для удобства развёртывания все библиотеки можно поместить в один jar-файл. Подробнее о том, что такое jar-архив и как его получить, мы рассматривали в статье Как скомпилировать исходники java вручную.

Рассмотрим конкретный пример. Пусть имеется приложение, которое использует класс StringUtils из популярного проекта Apache commons-lang3:

package ru.devmark;

import org.apache.commons.lang3.StringUtils;

public class Main {

    public static void main(String[] args) {
        System.out.println(StringUtils.isBlank(""));
    }
}

В pom-файле нашего maven-проекта должно быть прописано следующее:

Читать полностью...

Тэги: Apache, Java, maven.


Как обменять значения двух переменных без буфера

2 мая 2018

Если перед вами встанет задача обменять значения двух числовых переменных a и b между собой, скорее всего, вы сделаете это так:

int buffer = a;
a = b;
b = buffer;

То есть поменять значения одновременно нельзя, ибо одно из них затрётся. Чтобы этого не произошло, мы создаём новую буферную переменную, куда и помещаем на время одно из значений.

А что, если нам нужно обменять значения числовых переменных между собой, не создавая новых переменных?

Читать полностью...

Тэги: Java, головоломки.


Как скомпилировать исходники java вручную

1 мая 2018

В современной разработке многие рутинные процессы автоматизированы достаточно хорошо, поэтому вам не приходится каждый раз компилировать ваши исходники вручную. Я не сомневаюсь, что вы прекрасно знаете, как это делается. А для тех, кто забыл или решил освежить свои знания, рассмотрим небольшой пример.

Наш проект будет состоять всего из двух классов, причём один будет вызывать метод другого.

Класс Other, единственный метод которого выводит строку текста на экран:

package ru.devmark.helper;

public class Other {
    public String getMessage() {
        return "Привет, мир!";
    }
}

Сохраним этот текст как есть в файл, имя которого обязательно должно совпадать с именем класса, т.е. Other.java.

Читать полностью...

Тэги: Java.


Тестирование System.out.print в JUnit

28 апреля 2018

Предположим, что у вас имеется метод, который вместо логов просто выводит какой-то текст через стандартный поток вывода:

public class Example {

    public void doSomeLogic() {
        System.out.print("Test string");
    }
}

И перед вами встаёт задача написать юнит-тест на то, что данный метод действительно выводит данную строку. Для тестирования будем использовать библиотеку JUnit.

Если бы он просто возвращал её как результат своей работы, мы бы проверяли его через Assert.equals(). Но если мы хотим тестировать вывод, то перед началом теста нам надо создать свой собственный поток, подсунуть его как стандартный вывод, выполнить необходимые проверки, а затем вернуть всё обратно.

В качестве реализации потока будем использовать ByteArrayOutputStream, поскольку его можно легко преобразовать в строку. Тестовый класс будет выглядеть так:

Читать полностью...

Тэги: JUnit, Java.


Обновление записи через DELETE-запрос в Spring Boot

26 апреля 2018

В статье Работа с БД в Spring Boot на примере postgresql мы узнали как читать данные из БД. Но чтение данных - это лишь малая часть всех операций, которые встречаются в типичном java-приложении. Теперь попробуем создать полноценный rest-интерфейс для удаления ранее добавленных записей.

За основу возьмём наше приложение из указанной статьи. Оно состоит из трёх слоёв: dao (работа с БД), бизнес-логика приложения (service) и сам rest-интерфейс (controller), который обрабатывает входящий json и генерирует исходящий.

Начнём с доработки dao-слоя (интерфейс ProfileDao).

    void deleteProfileById(int id);

Для удаления нам достаточно знать только id записи.

В реализацию интерфейса dao (ProfileDaoImpl) добавим sql-запрос в виде константы, которую принято размещать в начале класса:

    private static final String SQL_DELETE_PROFILE = "delete from profiles where id = :id";

Читать полностью...

Тэги: Java, SQL, Spring Boot, rest.


Обновление записи через PUT-запрос в Spring Boot

25 апреля 2018

В статье Работа с БД в Spring Boot на примере postgresql мы узнали как читать данные из БД. Но чтение данных - это лишь малая часть всех операций, которые встречаются в типичном java-приложении. Теперь попробуем создать полноценный rest-интерфейс для обновления ранее добавленных записей.

За основу возьмём наше приложение из указанной статьи. Оно состоит из трёх слоёв: dao (работа с БД), бизнес-логика приложения (service) и сам rest-интерфейс (controller), который обрабатывает входящий json и генерирует исходящий.

Начнём с доработки dao-слоя (интерфейс ProfileDao).

    void updateProfile(String firstName, String secondName, int age, int id);

Для обновления нам потребуется указать id записи, а также остальные значимые поля.

В реализацию интерфейса dao (ProfileDaoImpl) добавим sql-запрос в виде константы, которую принято размещать в начале класса:

    private static final String SQL_UPDATE_PROFILE =
            "update profiles set first_name = :firstName, last_name = :lastName, age = :age where id = :id";

Читать полностью...

Тэги: Java, SQL, Spring Boot, rest.


Добавление записи через POST-запрос в Spring Boot

24 апреля 2018

В статье Работа с БД в Spring Boot на примере postgresql мы узнали как читать данные из БД. Но чтение данных - это лишь малая часть всех операций, которые встречаются в типичном java-приложении. Теперь попробуем создать полноценный rest-интерфейс для добавления новых записей, их модификации и удаления.

За основу возьмём наше приложение из указанной статьи. Оно состоит из трёх слоёв: dao (работа с БД), бизнес-логика приложения (service) и сам rest-интерфейс (controller), который обрабатывает входящий json и генерирует исходящий.

Начнём с доработки dao-слоя (интерфейс ProfileDao), где до сих пор был только один метод чтения данных.

    void insertProfile(String firstName, String secondName, int age);

При добавлении новой записи нам достаточно всего три поля. id будет сгенерирован в БД автоматически.

В реализацию интерфейса dao (ProfileDaoImpl) добавим sql-запросы в виде констант, которые принято размещать в начале класса:

    private static final String SQL_INSERT_PROFILE =
            "insert into profiles (first_name, last_name, age) values (:firstName, :lastName, :age)";

Читать полностью...

Тэги: Java, SQL, Spring Boot, rest.


Пример standalone-приложения на Spring

14 января 2018

Рассмотрим базовые возможности dependency injection (внедрения зависимостей), которые открывает нам Spring.

Создадим обычный maven-проект, где в pom.xml добавим сам Spring (артефакт spring-context) и секцию build со стандартным плагином maven-compiler-plugin, в котором указываем версию java в source и target.

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.13.RELEASE</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

Теперь создадим главный класс TestApp, который будет точкой запуска приложения.

Читать полностью...

Тэги: Java, Java 8, Spring, Stream API, maven, ООП.


Выравнивание числа ведущими нулями

12 января 2018

Рассмотрим случай, когда у вас есть некое число, количество цифр в котором заранее неизвестно и вам необходимо, чтобы число всегда составляло 5 знаков, то есть нужно добавить необходимое количество нулей слева. Есть целых два способа сделать это.

Без использования сторонних библиотек

Если у вас небольшой проект и не хочется тянуть лишнюю зависимость, то используйте String.format():

System.out.println(String.format("%05d"42));

В результате мы увидим строку «00042». К недостаткам данного способа можно отнести то, что нужно помнить правила форматирования в методе String.format().

Читать полностью...

Тэги: Apache, Java, maven.


Spring Boot Restful Service

5 января 2018

Что мы получим в результате

Простой сервис на Spring Boot, который при выполнении get-запроса будет возвращать профиль пользователя в формате json в зависимости от id, который передаётся в запросе. При возникновении исключительных ситуаций (например, профиль не найден), пользователь получит соответствующий ответ.

Реализуем обработку get-запроса

Сразу оговорюсь, что здесь рассмотрю только создание самого веб-сервиса. Чаще всего, он будет обращаться к базе для получения профиля пользователя. Мы же этого здесь делать не будем, а только сымитируем загрузку профиля по id. Но всё, что касается взаимодействия по http, будет работать как положено.

Spring Boot позволяет просто и без лишних телодвижений создавать веб-сервисы. При этом конфигурацию служебных бинов он берёт на себя. Вы всегда можете переопределить дефолтное поведение, объявив тот или иной бин явно.

Давайте создадим maven-проект, в котором в качестве родительского проекта укажем spring-boot-starter-parent. Также нам потребуется добавить одну зависимость spring-boot-starter-web. Этого вполне достаточно для нашего проекта.

Читать полностью...

Тэги: Java, Spring, Spring Boot, maven, rest.


Передача null в перегруженный метод

4 января 2018

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

interface MyInterface {
    void doWork();
}

class MyBaseObject implements MyInterface {
    @Override
    public void doWork() {
        System.out.println("Base");
    }
}

class MyChildObject extends MyBaseObject {
    @Override
    public void doWork() {
        System.out.println("Child");
    }
}

Читать полностью...

Тэги: Java, ООП, головоломки.


Генерация строки на основе шаблона

4 января 2018

Предположим, вам нужно генерить текст по определённому шаблону. У вас есть заранее заготовленный текст, куда вы передаёте параметры для подстановки. Например, текст sms для клиента.

Самое первое, что приходит на ум - это воспользоваться методом String.format(). Как известно, он чувствителен к порядку следования элементов. Но что, если сам шаблон лежит у вас где-нибудь в базе данных и может измениться в любое время, а порядок параметров «зашит» в коде самого приложения? Согласитесь, было бы удобнее, чтобы каждый параметр подставлялся по имени, а не по порядку.

И тут первое, что приходит на ум - это метод String.replace(). Но чтобы не писать очередной велосипед, лучше воспользоваться классом org.apache.commons.lang3.text.StrSubstitutor из стандартной библиотеки Apache Common.

Читать полностью...

Тэги: Apache, Java, maven.