Java прочитать текстовый файл sql и выполнить
Эта статья открывает небольшой цикл, посвященный азам взаимодействия с базами данных (БД) в Java и введению в SQL. Многие программы заняты обработкой и модификацией информации, её поддержкой в актуальном состоянии. Поскольку данные — весьма важная часть логики программ, то под них зачастую выделяют отдельное хранилище. Информация в нём структурирована и подчинена специальным правилам, чтобы обеспечить правильность обработки и хранения. Доступ к данным и их изменение осуществляется с помощью специального языка запросов — SQL (Structured Query Language).
Система управления базами данных — это ПО, которое обеспечивает взаимодействие разных внешних программ с данными и дополнительные службы (журналирование, восстановление, резервное копирование и тому подобное), в том числе посредством SQL. То есть программная прослойка между данными и внешними программами с ними работающими. В этой части ответим на вопросы что такое SQL, что такое SQL сервер и создадим первую программу для взаимодействия с СУБД.
Виды СУБД
- Иерархические. Данные организованы в виде древовидной структуры. Пример — файловая система, которая начинается с корня диска и далее прирастает ветвями файлов разных типов и папок разной степени вложенности.
- Сетевые. Видоизменение иерархической, у каждого узла может быть больше одного родителя.
- Объектно-ориентированные. Данные организованы в виде классов/объектов c их атрибутами и принципами взаимодействия согласно ООП.
- Реляционные. Данные этого вида СУБД организованы в таблицах. Таблицы могут быть связаны друг с другом, информация в них структурирована.
- Что такое SQL-Сервер и как он работает? Взаимодействие с СУБД происходит по клиент-серверному принципу. Некая внешняя программа посылает запрос в виде операторов и команд на языке SQL, СУБД его обрабатывает и высылает ответ. Для упрощения примем, что SQL Сервер = СУБД.
- Data Definition Language (DDL) – определения данных. Создание структуры БД и её объектов;
- Data Manipulation Language(DML) – собственно взаимодействие с данными: вставка, удаление, изменение и чтение;
- Transaction Control Language (TCL) – управление транзакциями;
- Data Control Language(DCL) – управление правами доступа к данным и структурам БД.
В 80-е годы прошлого века персональные компьютеры типа PC XT/AT завоевали рынок. Во многом это произошло благодаря модульности их конструкции. Это означает, что пользователь мог довольно просто менять ту или иную составную часть своего компьютера (процессор, видеокарту, диски и тому подобное). Это замечательное свойство сохранилось и поныне: мы меняем видеокарту и обновляем драйвер (иногда он и вовсе обновляется сам, в автоматическом режиме). Чаще всего при таких манипуляциях ничего плохого не происходит, и существующие программы продолжат работать с обновившейся системой без переустановки. Аналогично и для работы в Java с СУБД. Для стандартизации работы с SQL-серверами взаимодействие с ней можно выполнять через единую точку — JDBC (Java DataBase Connectivity). Она представляет собой реализацию пакета java.sql для работы с СУБД. Производители всех популярных SQL-серверов выпускают для них драйверы JDBC. Рассмотрим схему ниже. Приложение использует экземпляры классов из java.sql. Затем мы передаем необходимые команды для получения/модификации данных. Далее java.sql через jdbc-драйвер взаимодействует с СУБД и возвращает нам готовый результат. Для перехода на СУБД другого производителя часто достаточно сменить JDBC и выполнить базовые настройки. Остальные части программы при этом не меняются.
Первая программа
Блок констант:
- DB_Driver: Здесь мы определили имя драйвера, которое можно узнать, например, кликнув мышкой на подключенную библиотеку и развернув её структуру в директории lib текущего проекта.
- DB_URL: Адрес нашей базы данных. Состоит из данных, разделённых двоеточием:
- Протокол=jdbc
- Вендор (производитель/наименование) СУБД=h2
- Расположение СУБД, в нашем случае путь до файла (c:/JavaPrj/SQLDemo/db/stockExchange). Для сетевых СУБД тут дополнительно указываются имена или IP адреса удалённых серверов, TCP/UDP номера портов и так далее.
Обработка ошибок:
Вызов методов нашего кода может вернуть ошибки, на которые следует обратить внимание. На данном этапе мы просто информируем о них в консоли. Заметим, что ошибки при работе с СУБД — это чаще всего SQLException.
I want to execute an SQL script file in Java without reading the entire file content into a big query and executing it.
Is there any other standard way?
Запрос и чтение данных в файле базы данных SQLite с запросом языка Java
1. Средства разработки
2. Конфигурация программного обеспечения
Наконец, чтобы установить соединение между JAVA и базой данных SQLite, вам также необходимо скачать драйвер SQLite JDBC (соединение с базой данных Java, соединение с базой данных Java) с официального сайта gethub. Полное имя JDBC - Java DataBase Connectivity - это Java API (интерфейс прикладного программирования), который можно использовать для выполнения операторов SQL, это связь между базой данных и приложением Java.
Основная цель этой статьи - представить создание проекта JAVA и драйвер jdbc, то есть введение подключения к базе данных java (JDBC).
Шаги следующие:
1. Загрузите последнюю версию sqlite-jdbc-3.23.1.jar на официальном сайте.
2. Откройте Eclipse, создайте проект Java с именем SQLiteTest и создайте его, как показано на рисунке:
3. Добавьте пакет jlbc.jar драйвера sqlite в библиотеки в созданном проекте:
Щелкните правой кнопкой мыши по проекту и выберите: Build Path -> Add Libraries . затем перейдите к следующему шагу, выберите User Library и перейдите к следующему шагу;
4. Нажмите Пользовательские библиотеки . которые появятся в окне, а затем нажмите новый . чтобы создать новый пакет библиотек с его собственным именем, например SQLiteLibrary, и затем нажмите OK, чтобы перейти к следующему шагу;
5. Затем нам нужно ввести пакет sqlite driver-jdbc.jar в пустой созданный нами пакет библиотек, щелкнуть Add External JARs справа . выбрать соответствующий во всплывающем селекторе Адрес загруженного пакета jar драйвера sqlite;
6. После завершения добавления мы можем обнаружить, что в проект добавлено больше пакетов библиотек, которые также содержат пакет jdbc.jar драйвера sqlite, который мы добавили;
3. JAVA подключается к базе данных
Используйте язык программирования Java для подключения к базе данных SQLite, напишите код программы следующим образом:
После выполнения вышеуказанного кода будет создан файл: F: /sqlite/testconn.db, язык java и база данных testconn.db будут подключены.
Такие как:
Имя Пол Возраст
Чжан Сан Мале 23
Ли Си Женщина 18
。。。
1. Запустите SQLite Expert Professional, выберите опцию «Файл», нажмите «Открыть базу данных», откройте установленную базу данных testconn.db, щелкните правой кнопкой мыши базу данных, нажмите «Новая таблица», чтобы создать новую таблицу;
2. Добавить столбцы: нажмите «Дизайн», задайте свойства в диалоговом окне, которое появляется после нажатия «Вставить» в столбце «Столбцы»;
3. Установите первичный ключ: нажмите «Первичный ключ», нажмите «Вставить», выберите имя столбца, который необходимо установить в качестве первичного ключа, в раскрывающемся меню;
4. Нажмите «Общие», введите Имя таблицы, чтобы задать имя таблицы, и нажмите «Применить»;
5. Наконец, установите соответствующие данные в таблице данных.
как показано на рисунке:
После успешного установления соединения между базой данных Java и SQLite вы можете запрашивать таблицы в базе данных и манипулировать ими.
Разбор кода
12 Answers 12
There is great way of executing SQL scripts from Java without reading them yourself as long as you don't mind having a dependency on Ant. In my opinion such a dependency is very well justified in your case. Here is sample code, where SQLExec class lives in ant.jar:
I tried this for few of my Oracle SQL scripts, it works for insert , create table . But for script having create or replace trigger it fails with java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement
There is no portable way of doing that. You can execute a native client as an external program to do that though:
- Code sample was extracted from here and modified to answer question assuming that the user wants to execute a PostgreSQL script file.
Flyway library is really good for this:
This scans the locations for scripts and runs them in order. Scripts can be versioned with V01__name.sql so if just the migrate is called then only those not already run will be run. Uses a table called 'schema_version' to keep track of things. But can do other things too, see the docs: flyway.
The clean call isn't required, but useful to start from a clean DB. Also, be aware of the location (default is "classpath:db/migration"), there is no space after the ':', that one caught me out.
No, you must read the file, split it into separate queries and then execute them individually (or using the batch API of JDBC).
One of the reasons is that every database defines their own way to separate SQL statements (some use ; , others / , some allow both or even to define your own separator).
You cannot do using JDBC as it does not support . Work around would be including iBatis iBATIS is a persistence framework and call the Scriptrunner constructor as shown in iBatis documentation .
Its not good to include a heavy weight persistence framework like ibatis in order to run a simple sql scripts any ways which you can do using command line
Since JDBC doesn't support this option the best way to solve this question is executing command lines via the Java Program. Bellow is an example to postgresql:
For my simple project the user should be able to select SQL-files which get executed. As I was not happy with the other answers and I am using Flyway anyway I took a closer look at the Flyway code. DefaultSqlScriptExecutor is doing the actual execution, so I tried to figure out how to create an instance of DefaultSqlScriptExecutor .
Basically the following snippet loads a String splits it into the single statements and executes one by one. Flyway also provides other LoadableResource s than StringResource e.g. FileSystemResource . But I have not taken a closer look at them.
As DefaultSqlScriptExecutor and the other classes are not officially documented by Flyway use the code-snippet with care.
I used java -classpath lib/jisql-2.0.11.jar:lib/jopt-simple-3.2.jar:lib/javacsv.jar. /ojdbc7.jar com.xigole.util.sql.Jisql -user ecm -password TODO -driver oracle.jdbc.OracleDriver -cstring jdbc:oracle:thin:@localhost:1521:XE -c \; -input myoracle.sql and it worked flawlessly.
The Apache iBatis solution worked like a charm.
The script example I used was exactly the script I was running from MySql workbench.
This is what I did:
Code to execute script:
JDBC does not support this option (although a specific DB driver may offer this). Anyway, there should not be a problem with loading all file contents into memory.
Your example is overly simplistic. A Statement can usually only execute one SQL statement at a time. The question implies there are a large number of queries or insertions involved, and they therefore need to be split up into individual statements by finding the separators.
Я хочу выполнить файл сценария SQL на Java без чтения всего содержимого файла в большой запрос и его выполнения.
есть ли другой стандартный способ?
нет переносимый способ сделать это. Вы можете выполнить собственный клиент как внешнюю программу, чтобы сделать это, хотя:
- пример кода был извлечен из здесь и изменен, чтобы ответить на вопрос, предполагая, что пользователь хочет выполнить файл сценария с PostgreSQL.
существует отличный способ выполнения SQL-скриптов с Java, не читая их самостоятельно, пока вы не возражаете иметь зависимость от Ant. На мой взгляд, такая зависимость очень хорошо оправдана в вашем случае. Вот пример кода, где класс SQLExec живет в ant.jar:
нет, вы должны прочитать файл, разделить его на отдельные запросы, а затем выполнить их по отдельности (или с помощью пакетного API JDBC).
одна из причин заключается в том, что каждая база данных определяет свой собственный способ разделения операторов SQL (некоторые используют ; , другие / , некоторые позволяют одновременно или даже определить свой собственный разделитель).
вы не можете использовать JDBC, поскольку он не поддерживает . Работа вокруг будет включать в себя iBatis iBATIS-это структура персистентности и вызов Scriptrunner конструктор как показано в iBatis документация .
нехорошо включать тяжелую структуру персистентности, такую как ibatis, чтобы запускать простые сценарии sql любыми способами, которые вы можете сделать с помощью командной строки
библиотека Flyway действительно хороша для этого:
это сканирует местоположения для сценариев и запускает их по порядку. Скрипты могут быть версионными с именем V01__.sql, поэтому, если вызывается только миграция, будут выполняться только те, которые еще не запущены. Использует таблицу под названием "schema_version" для отслеживания вещей. Но может делать и другие вещи, см. документы:flyway.
чистый вызов не требуется, но полезно начать с чистого DB. Также следует учитывать местоположение (по умолчанию "classpath: db/migration"), нет места после":", который поймал меня.
поскольку JDBC не поддерживает эту опцию, лучшим способом решить этот вопрос является выполнение командных строк через программу Java. Ниже приведен пример для postgresql:
JDBC не поддерживает эту опцию (хотя конкретный драйвер БД может предложить это). Во всяком случае, не должно быть проблем с загрузкой всего содержимого файла в память.
кажется, есть разные способы чтения и записи данных из файлов в Java.
Я хочу прочитать данные ASCII из файла. Каковы возможные пути и их различия?
ASCII-это текстовый файл, поэтому вы будете использовать читателей для чтения. Java также поддерживает чтение из двоичного файла с помощью InputStreams. Если считываемые файлы огромны, вы захотите использовать командой bufferedreader на FileReader для улучшения производительности.
пройти в этой статье о том, как использовать Reader
Я также рекомендую вам скачать и прочитать эту замечательную (пока бесплатно) забронировать называется Мышление На Java
В Java 7:
В Java 8:
мой любимый способ чтения небольшого файла-использовать BufferedReader и StringBuilder. Это очень просто и по существу (хотя и не особенно эффективно, но достаточно хорошо для большинства случаев):
некоторые указали, что после Java 7 Вы должны использовать try-with-resources (т. е. автоматическое закрытие) особенности:
когда я читаю строки, как это, я обычно хочу сделать некоторую обработку строк в строке в любом случае, поэтому я иду на это реализация.
хотя, если я хочу на самом деле просто прочитать файл в строку, я всегда использую Apache Commons IO С классом IOUtils.метод toString. Вы можете посмотреть на источник здесь:
и еще проще с Java 7:
самый простой способ-использовать Scanner класс в Java и объект FileReader. Простой пример:
Scanner имеет несколько методов для чтения в строках, числах и т. д. Дополнительную информацию об этом можно найти на странице документации Java.
например, чтение всего содержимого в String :
кроме того, если вам нужна конкретная кодировка вы можете использовать это вместо FileReader :
вот простое решение:
вот еще один способ сделать это без использования внешних библиотек:
Я должен был проверить разные способы. Я прокомментирую свои выводы, но, короче говоря, самый быстрый способ-использовать простой старый BufferedInputStream над FileInputStream. Если необходимо прочитать много файлов, то три потока сократят общее время выполнения примерно до половины, но добавление большего количества потоков будет постепенно снижать производительность, пока не займет в три раза больше времени для завершения двадцати потоков, чем только с одним потоком.
предполагается, что вы должны прочитать файл и сделать что-то значимое с его содержанием. В примерах здесь читаются строки из журнала и подсчитываются те, которые содержат значения, превышающие определенный порог. Поэтому я предполагаю, что однострочный Java 8 Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";")) - это не вариант.
Я тестировал на Java 1.8, Windows 7 и SSD и HDD дисках.
Я написал шесть различных реализаций:
rawParse: используйте BufferedInputStream над FileInputStream, а затем вырезать строки чтения байт за байтом. Это превзошло любой другой однопоточный подход, но это может быть очень неудобно для файлов, отличных от ASCII.
lineReaderParse: используйте BufferedReader над FileReader, читайте строку за строкой, разделяйте строки, вызывая строку.расщеплять.)( Это примерно на 20% медленнее, чем rawParse.
lineReaderParseParallel: это то же самое, что lineReaderParse, но он использует несколько потоков. Это самый быстрый вариант в целом случаи.
nioFilesParse: используйте java.НИО.файлы.Файлы.lines ()
nioAsyncParse: используйте асинхронный канал с обработчиком завершения и пулом потоков.
nioMemoryMappedParse: используйте файл, сопоставленный с памятью. Это действительно плохая идея, дающая время выполнения по крайней мере в три раза больше, чем любая другая реализация.
это среднее время для чтения 204 файлов по 4 МБ каждый на четырехъядерный i7 и SSD-накопитель. Файлы создаются на лету, чтобы избежать кэширования диска.
Я нашел разницу меньше, чем я ожидал, между запуском на SSD или жестком диске SSD примерно на 15% быстрее. Это может быть связано с тем, что файлы генерируются на нефрагментированном HDD, и они читаются последовательно, поэтому вращающийся диск может работать почти как SSD.
Я был удивлен низкой производительностью реализации nioAsyncParse. Любой Я реализовал что-то неправильно или многопоточная реализация с использованием NIO, а обработчик завершения выполняет то же самое (или даже хуже), что и однопоточная реализация с java.IO API. Кроме того, асинхронный синтаксический анализ с CompletionHandler намного длиннее в строках кода и сложнее реализовать правильно, чем прямая реализация на старых потоках.
теперь шесть реализаций, за которыми следует класс, содержащий их все, плюс параметризуемый метод main() это позволяет играть с количеством файлов, размером файла и степенью параллелизма. Обратите внимание, что размер файлов варьируется плюс минус 20%. Это позволяет избежать какого-либо эффекта из-за того, что все файлы одинаковы размер.
Читайте также: