Лекция 13. Разное ####################################################################################### Работа с СУБД =========================================================== Рассмотрим работу программы на примере СУБД **MySQL** Разработаем два класса: #. **MysqlConnect** - обслуживание соединения #. **DBTest** - демонстрационная программа Схема работы с СУБД: .. image:: _static/13/jdbc1.png В системе должны быть установлены драйвера коннектора **jdbc-mysql**, которые можно скачать по адресу: http://dev.mysql.com/downloads/connector/j/ Описание класса **MysqlConnect**: Пакеты в заголовке: .. code-block:: java import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; import java.sql.PreparedStatement; import java.sql.ResultSet; .. code-block:: java class MysqlConnect { // данные для работы с СУБД // название драйвера СУБД private static final String DATABASE_DRIVER = "com.mysql.jdbc.Driver"; // адрес MySQL с указанием имени базы private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/test_java?useSSL=false"; // имя пользователя MySQL private static final String USERNAME = "root"; // пароль для доступа к базе private static final String PASSWORD = "123456"; // макс. количество соединений private static final String MAX_POOL = "250"; .. .. code-block:: java .. // объект "соединение" private Connection connection; // объект "свойства соединения" private Properties properties; // метод для формирования записи свойств private Properties getProperties() { if (properties == null) { properties = new Properties(); properties.setProperty("user", USERNAME); properties.setProperty("password", PASSWORD); properties.setProperty("MaxPooledStatements", MAX_POOL); } return properties; } .. Установка соединения: .. code-block:: java // connect database public Connection connect() { if (connection == null) { try { Class.forName(DATABASE_DRIVER); connection = DriverManager.getConnection(DATABASE_URL, getProperties()); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } return connection; } Разрыв соединения с СУБД: .. code-block:: java // disconnect database public void disconnect() { if (connection != null) { try { connection.close(); connection = null; } catch (SQLException e) { e.printStackTrace(); } } } } // конец описания класса В главном классе программы создаем соединение и скачиваем записи из таблицы **months**: .. code-block:: java public class DBTest { public static void main(String[] args) { MysqlConnect mysqlConnect = new MysqlConnect(); String sql = "SELECT * FROM `months`"; try { PreparedStatement statement = mysqlConnect.connect().prepareStatement(sql); ResultSet rs = statement.executeQuery(); .. .. code-block:: java while (rs.next()) { String num = rs.getString("num"); String name = rs.getString("name"); System.out.println("num : " + num); System.out.println("name : " + name); } } catch (SQLException e) { e.printStackTrace(); } finally { mysqlConnect.disconnect(); } } } Для запуска программы нужно подключить архив с пакетами драйвера: .. code-block:: none java -cp mysql-connector-java-5.1.39-bin.jar:. DBTest Элементы ФП =========================================================== **Функциональная парадигма** - это подход к программированию, в центре которого находится понятие функции (в математическом смысле), а сама программа - процесс вычисления некоторой функции. Принципы ФП: * **Объекты неизменяемы** (можно создать новый объект, но нельзя изменить старый). * **Функции** не имеют побочных эффектов (нет указателей, ссылок на глобальные переменные). * **Функции - параметры**. * Широко применяются безымянные **лямбда-функции**. * Используется **выведение типов** компилятором. Поддержка ФП была введена в **Java 8**. Пример с кнопкой: .. code-block:: java // обработчик нажатия на кнопку (стиль ООП) button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.out.println("button clicked"); } }); .. code-block:: java // функциональный стиль button.addActionListener(event -> System.out.println("button clicked")); Различные стили записи лямбда-функций: .. code-block:: java // функция без аргументов Runnable noArguments = () -> System.out.println("Hello World"); // функция с одним аргументом ActionListener oneArgument = event -> System.out.println("button clicked"); // функция с блоком кода Runnable multiStatement = () -> { System.out.print("Hello"); System.out.println(" World"); }; // функция с двумя аргументами BinaryOperator add = (x, y) -> x + y; // явное указание типов аргументов BinaryOperator addExplicit = (Long x, Long y) -> x + y; Пример с обработкой коллекции: .. code-block:: java import java.util.*; public class Example1 { public static void main(String[] args) { List colors = Arrays.asList("Red", "Orange", "Blue", "White", "Black", "Yellow"); // опасный цикл for(int i=0;i System.out.println(color)); // перебор с лямбда-функцией (сокращенная версия) colors.forEach(System.out::println); Вариант с трансформацией списка: .. code-block:: java import java.util.*; public class Example2 { public static void main(String[] args) { List colors = Arrays.asList("Red", "Orange", "Blue", "White", "Black", "Yellow"); List uppercaseColors = new ArrayList(); colors.forEach(color -> uppercaseColors.add(color.toUpperCase())); System.out.println(uppercaseColors); } } .. code-block:: none $ java Example2 [RED, ORANGE, BLUE, WHITE, BLACK, YELLOW] Другой вариант: .. code-block:: java import java.util.*; public class Example3 { public static void main(String[] args) { List colors = Arrays.asList("Red", "Orange", "Blue", "White", "Black", "Yellow"); List uppercaseColors = new ArrayList(); colors.stream() .map(color -> color.toUpperCase()) .forEach(color -> System.out.print(color + " ")); System.out.println(); } } Варианты функций, возвращаемые **stream()**: * **.filter()** - отбирает элементы, для которых лямбда-функция возвращает **true** * **.map()** - применяет лямбда-функцию к каждому элементу коллекции * **.reduce()** - пытается обработать два параметра и отобрать один, затем передать по коллекции дальше * **.collect()** - накопление результата при движении по коллекции Подсчет строк, начинающихся на **B**: .. code-block:: java import java.util.*; public class Example5 { public static void main(String[] args) { List colors = Arrays.asList("Red", "Orange", "Blue", "White", "Black", "Yellow"); List uppercaseColors = new ArrayList(); long count= colors.stream() .filter(color -> color.startsWith("B")) .count(); System.out.println(count); } } .. code-block:: java import java.util.*; public class Example6 { public static void main(String[] args) { List colors = Arrays.asList("Red", "Orange", "Blue", "White", "Black", "Yellow"); List uppercaseColors = new ArrayList(); colors.stream() .map(color -> color.length()) .forEach(color -> System.out.println(color)); System.out.println(); } } Программа выводит длины слов Регулярные выражения =========================================================== Одним из важнейших механизмов поиска и обработки данных являются **регулярные выражения** Для работы подключат пакеты: .. code-block:: java import java.util.regex.Matcher; import java.util.regex.Pattern; Пример использования: .. code-block:: java import java.util.regex.Matcher; import java.util.regex.Pattern; class RegexDemo { public static void main(String[] args) { Pattern p=Pattern.compile(".*(\\d)+ab.*"); Matcher m=p.matcher("qq5abbb"); System.out.println(m.matches()); System.out.println(m.group(1)); } } Взаимодействие с С++ =========================================================== Java и CPP `````````````````````````````````````````````````````````` Для взаимодействия Java-программ с функциями, написанными на С++, используется интерфейс **JNI** Алгоритм построения совместной программы: #. Пишем код Java-класса #. Компилируем Java-программу #. Создаем заголовочный файл для С++ #. Пишем C++файл #. Компилируем C++ файл и получаем динамическую библиотеку #. Запускаем Java-программу Java-класс: .. code-block:: java public class Hello { // функция С++ public native void hello(); public static void main(String[] args) { Hello h=new Hello(); h.hello(); } static { System.loadLibrary("hello"); } } Компиляция Java-программы: .. code-block:: none javac Hello.java Создание заголовочного файла: .. code-block:: none javah -jni Hello Создаем файл **hello.c** с определением функции **hello()**: .. code-block:: cpp JNIEXPORT void JNICALL Java_Hello_hello(JNIEnv *e, jobject o) { printf("Hello from C!"); } Имя вызываемой функции берем из h-файла. Компилируем С-файл и получаем библиотеку: .. code-block:: none g++ -dynamiclib -o libhello.jnilib -I/opt/local/lib/gcc47/gcc/x86_64-apple-darwin13/4.7.4/include hello.c Здесь в параметре **-I** указан путь к заголовочному файлу **jni.h** Запускаем Java-программу: .. code-block:: none java Hello Вопросы для самоконтроля =============================================