Но я наткнулся на другую проблему. Как мне связать объекты и базу данных. Данные в объектах хранятся иначе, чем в реляционной базе данных. Реляционная база данных не поддерживает многие концепции ООП, которые так важны для нашей объектной модели. Поэтому я подумал о том, чтобы создать свои собственные классы для передачи данных из базы данных в объекты и обратно. Но я столкнулся с множеством трудностей и камней преткновения. Затем наступил перерыв! Я натолкнулся на материал Java Persistence, который позволял мне сохранять или сохранять данные объекта по истечении времени жизни программы. Это означает, что теперь вы можете хранить объекты в хранилищах данных, таких как реляционная база данных, файл XML и т. Д., Без необходимости писать сложный код для преобразования форматов и управления операциями CRUD .
Эта небольшая статья познакомит вас с этой замечательной функцией, и вы сможете приступить к внедрению постоянства в своих проектах. Я не хочу вдаваться в сложные темы в этой статье. Поэтому я решил использовать базу данных ObjectDB . Преимущество использования ObjectDB в том, что ему не нужны сложные файлы конфигурации и сопоставления, которые обычно нужны JPA. И мы собираемся использовать популярную Eclipse IDE . Я приведу простой пример программы, которая будет хранить и обрабатывать данные сотрудника (имя и зарплата). Хорошо, давайте начнем ………!
Персистентный сервис предоставляется многими провайдерами, и мы собираемся использовать реализацию ObjectDB. Так что скачивайте их файлы БД и API . Давайте пройдемся по некоторым основам сейчас. И тогда мы увидим, как реализовать их для создания программы …
I. Класс сущности:
Чтобы использовать постоянство, вам нужен класс, чьи объекты вы собираетесь хранить в базе данных. Там классы называются классами сущностей и они такие же, как POJO (простые старые объекты Java), за исключением некоторых дополнительных аннотаций. Вам нужно определить поля внутри этого класса, которые должны быть сохранены (сохранены в БД). Класс Entity должен иметь аннотацию « @Entity » над классом. Теперь определите все поля и методы класса. Вуаля, мы получили класс Entity! Теперь вы можете добавлять дополнительные функции в свой класс сущностей. Например, вы можете указать, какое поле использовать в качестве первичного ключа, используя аннотацию « @Id » над этим полем. Вы также можете заставить ObjectDB генерировать значение первичного ключа для объектов, которые вы сохраняете в базе данных, используя аннотацию « @GeneratedValue (стратегии = GenerationType.AUTO) ». Есть еще много аннотаций и функций и конструкций. Но нам не нужно видеть о них сейчас. Вот класс, который мы будем использовать как класс сущностей…
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package employeeDB; import javax.persistence.*; @Entity publicclass Employee { @Id String name; Double salary; public Employee() { } public Employee (String name, Double Salary) { this .name=name; this .salary=Salary; } publicvoid setSalary(Double Salary) { this .salary=Salary; } publicString toString() { return "Name: " +name+ "\nSalary: " +salary ; } } |
Как видите, у нас есть класс Entity, идентифицируемый аннотацией @Entity . Тогда у нас есть имя сотрудника в качестве первичного ключа. И вам нужно иметь конструктор по умолчанию без параметров в вашем классе сущности.
В других реализациях JPA вам, возможно, придется предоставить подробную информацию о классах сущностей в отдельном файле XML. Но ObjectDB этого не требует.
II. Подключение к базе данных
В JPA соединение с базой данных представлено интерфейсом EntityManager . Чтобы получить доступ к базе данных ObjectDB и работать с ней, нам необходим экземпляр EntityManager. Мы можем получить экземпляр EntityManager, используя экземпляр EntityManagerFactory, который создан с использованием статического метода createEntityManagerFactory класса EntityManagerFactory. Вам необходимо указать, где хранить файл базы данных в качестве аргумента метода createEntityManagerFactory. Пример:
1
2
|
EntityManagerFactory emf=Persistence.createEntityManagerFactory( "empDB.odb" ); EntityManager em=emf.createEntityManager(); |
Теперь у нас есть EntityManager, который подключит наше приложение к базе данных. Обычно в программе создается несколько EntityManager, но создается только один экземпляр EntityManagerfactory. В большинстве реализаций JPA в качестве аргумента для создания экземпляра EntityManagerFactory требуется файл сопоставления XML, называемый «единицей постоянства». Но у ObjectDB есть условия для принятия только местоположения базы данных. Если база данных уже существует, она будет открыта или же для нас будет создана новая БД.
EntityManagerFactory и EntityManager могут быть закрыты следующим образом:
1
2
|
em.close(); emf.close(); |
Хорошей практикой является наличие отдельного EntityManager для каждого класса (который отвечает за некоторую активность в БД) или каждого потока в случае многопоточного приложения. Теперь давайте посмотрим, как совершать транзакции с базой данных …
III. Выполнение транзакций
Для выполнения каких-либо операций с базой данных или над ней мы должны сначала запустить транзакцию. Любая операция может быть выполнена только после запуска транзакции с использованием EntityManager. Мы можем начать транзакцию, используя следующий вызов.
1
|
em.getTransaction().begin(); |
И теперь мы можем выполнять различные транзакции, такие как создание новой записи (объекта), удаление, обновление и получение данных из базы данных. Прежде чем мы сможем выполнить какую-либо из операций CRUD, нам нужно добавить данные в нашу базу данных. В JPA вставка объекта в базу данных называется сохранением объекта. Это можно сделать с помощью метода em.persist (Object) . Теперь этот объект становится «управляемым», но этот EntityManager (em). Это означает, что любые изменения, внесенные в этот объект, будут отражены в его копии в файле базы данных. И чтобы удалить любой объект из базы данных, мы можем использовать метод em.remove (Object) . Мы можем извлечь объект из базы данных, используя первичный ключ объекта, используя метод em.find (Class, primaryKeyValue) . Вам нужно передать экземпляр класса класса Entity и первичный ключ этому методу, и он вернет «объект», который должен быть приведен к классу Entity. Наконец, после выполнения транзакций мы должны завершить транзакцию, используя
1
|
em.getTransaction().commit(); |
Только после фиксации транзакции изменения, внесенные в Объекты в памяти, будут отражены в Объектах в файле базы данных. Следующий код сохраняет объект Employee, а затем ищет объект Employee и изменяет его.
01
02
03
04
05
06
07
08
09
10
11
12
|
Employee emp1= new Employee ( "Gugan" , 50000 ); em.getTransaction().begin(); //Persist (store) emp1 object into Database em.persist(emp1); //Search for Gugan Employee gugan=(Employee) em.find(Employee. class , "Gugan" ); gugan.setSalary( 100000 ); em.getTransaction().commit(); |
Мы также можем использовать SQL-подобные запросы, называемые JPQL, для выполнения операций CRUD.
В JPA есть два типа запросов. Обычные запросы и TypedQueries. Обычные запросы — это не типовые безопасные запросы. (т. е.) запрос не знает тип объекта, который он собирается получить или работать с ним. Но TypedQuery — это типобезопасный запрос. Для создания типизированного запроса необходимо указать тип класса, который будет использоваться, а также передать экземпляр класса Class в качестве параметра вместе со строкой запроса. TypedQueries — это стандартный способ работы с базами данных, поэтому мы будем их использовать только. Они могут быть созданы с использованием следующего синтаксиса,
1
|
TypedQuery q=em.createQuery(queryString,EntityClass. class ); |
Если ваш запрос вернет только один объект или результат, как в случае определения количества записей (количество), то вы можете использовать метод q.getSingleResult () . С другой стороны, если ваш запрос возвратит коллекцию объектов, как в случае извлечения списка сотрудников из базы данных, вы можете использовать метод q.getResultList (), и он вернет объект List типа, указанного при создании TypedQuery. Следующий фрагмент кода сначала определит, сколько существует Employees, а затем извлечет все объекты Employee из базы данных.
01
02
03
04
05
06
07
08
09
10
11
|
em.getTransaction().begin(); //find number of Employees TypedQuery count=em.createQuery( "Select count(emp) from Employee emp" ,Employee. class ); System.out.println( "\n" +count.getSingleResult()+ " employee record(s) Available in Database!\n" ); //Retrieve All Employee Objects in the database TypedQuery e=em.createQuery( "Select emp from Employee emp" , Employee. class ); List employees=e.getResultList(); em.getTransaction().commit(); |
JPQL очень похож на запросы SQL. Единственное отличие состоит в том, что вы используете имена классов и имен объектов вместо имен таблиц. JPQL также поддерживает параметры в запросах. Например, если вы хотите найти сотрудника с именем «Стив» и если вы знаете имя «Стив» только во время выполнения, вы можете использовать следующий стиль запроса.
1
2
3
4
|
String name=scannerObj.nextLine(); TypedQuery<employee> query = em.createQuery( "SELECT e FROM Employee e WHERE e.name = :name" , Employee. class ); query.setParameter( "name" , name); Employee emp=query.getSingleResult(); |
Это заменит параметр «: name» на указанную переменную «name». Помимо этих запросов, есть много других запросов. Для полного руководства по JPQL вы можете прочитать руководство ObjectDB по JPQL .
Внутривенно Использование Eclipse для реализации ObjectDB JPA
Eclipse — лучшая IDE для Java AFAIK. Поэтому я рекомендую использовать Eclipse для разработки ваших приложений. Загрузите последнюю версию Eclipse Indigo здесь . Если у вас уже есть Eclipse Indigo или более старая версия, то это прекрасно. Создайте новый проект Java с помощью меню «Файл». И в новом диалоге проекта введите имя проекта для вашего проекта и выберите каталог, в котором вы хотите сохранить свой проект, и нажмите Далее. После нажатия кнопки «Далее» вам будет предложено несколько вариантов, и теперь в этом окне выберите вкладку «Библиотеки». А затем нажмите кнопку «Добавить внешние банки», чтобы открыть новый диалог. Теперь перейдите в папку, в которую вы извлекли файлы API ObjectDB, и перейдите в папку bin в ней и выберите файл «objectdb.jar». Нажмите open и библиотека будет добавлена. Теперь нажмите Готово, чтобы создать свой проект.
Теперь, когда мы создали наш проект, нам нужно добавить к нему классы. Теперь щелкните правой кнопкой мыши имя вашего проекта в панели Project Explorer в левой части окна Eclipse IDE и выберите New -> Class. Теперь откроется диалоговое окно New Class. В нем введите имя класса, который вы хотите создать, а затем введите имя пакета. Все другие варианты не должны быть связаны с …! В нашем примере программы мы будем использовать два класса. Один для организации сотрудника, а другой для размещения основного метода и основных функций приложения. Убедитесь, что оба класса находятся в одном пакете. Чтобы просмотреть созданные классы, разверните ваш проект в панели Project Explorer и из списка узлов разверните src, и вы увидите там свой пакет. Разверните его, и вы увидите классы.
V. Пример программы
Теперь, когда у вас есть некоторое общее представление о JPA, я представлю консольное приложение-пример, которое будет хранить, изменять и удалять сотрудников из базы данных … Если вы прочитали приведенный выше текст, вы можете легко следовать следующей программе. Я предоставил комментарии там, где это было необходимо, чтобы сделать программу более понятной.
Создайте класс с именем Employee, используя метод, о котором я говорил вам в предыдущем разделе, используя employeeDB в качестве имени вашего пакета, и вставьте код класса Employee Entity, который я дал в разделе I руководства.
Теперь создайте другой класс с именем Main в том же пакете employeeDB и поместите в него следующий код.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
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
|
package employeeDB; import javax.persistence.*; import java.util.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { /** * Displays all Employees in the Database */ private static void displayAll() { em.getTransaction().begin(); TypedQuery e=em.createQuery(displayAllQuery, Employee. class ); List <Employee> employees=e.getResultList(); if (employees.size()> 0 ) { for (Employee temp:employees) { System.out.println(temp); System.out.println(); } System.out.println(employees.size()+ " Employee Records Available...!" ); } else System.out.println( "Database is Empty!" ); em.getTransaction().commit(); } /** * Insets an Employee into the Database. */ private static void insert() { System.out.print( "Enter the number of Employees to be inserted: " ); n=input.nextInt(); em.getTransaction().begin(); for ( int i= 0 ;i<n;i++) { System.out.println( "Enter the details of Employee " +(i+ 1 )+ ": " ); System.out.print( "Name: " ); //I use BufferedReader to read String and hence I need to // Catch the IOException that it may throw try { name=bufferedReader.readLine(); } catch (IOException e) { e.printStackTrace(); } System.out.print( "Salary: " ); Salary=input.nextDouble(); Employee emp= new Employee(name,Salary); em.persist(emp); //Store emp into Database } em.getTransaction().commit(); System.out.println( "\n" +n+ " employee record(s) Created!\n" ); TypedQuery count=em.createQuery(countQuery,Employee. class ); System.out.println( "\n" +count.getSingleResult()+ " employee record(s) Available in Database!\n" ); } /** * Deletes the specified Employee from the database *@param name */ private static void delete(String name) { em.getTransaction().begin(); Employee e=(Employee) em.find(Employee. class , name); //Find Object to be deleted em.remove(e); //Delete the Employee from database System.out.printf( "Employee %s removed from Database...." ,e.name); em.getTransaction().commit(); //Display Number of Employees left TypedQuery count=em.createQuery(countQuery,Employee. class ); System.out.println( "\n" +count.getSingleResult()+ " employee record(s) Available in Database!\n" ); } /** * Changes salary of the specified employee to passed salary *@param name *@param Salary */ private static void modify(String name,Double Salary) { em.getTransaction().begin(); Employee e=(Employee) em.find(Employee. class , name); //Find Employee to be modified e.setSalary(Salary); //Modify the salary em.getTransaction().commit(); System.out.println( "Modification Successful!\n" ); } public static void main(String arg[]) { System.out.println( "Welcome to the Employee Database System!\n\n" ); do { System.out.print( "Menu: \n 1. View DB\n2. Insert \n3. Delete \n4. Modify\n5. Exit\nEnter Choice..." ); int ch=input.nextInt(); try { switch (ch) { case 1 : displayAll(); break ; case 2 : insert(); break ; case 3 : System.out.print( "Name of Employee to be Deleted2: " ); name=bufferedReader.readLine(); delete(name); break ; case 4 : System.out.print( "Name of Employee to be Modified: " ); name=bufferedReader.readLine(); System.out.print( "New Salary: " ); Salary=input.nextDouble(); modify(name,Salary); break ; case 5 : if (em!= null ) em.close(); //Close EntityManager if (emf!= null ) emf.close(); //Close EntityManagerFactory exit= true ; break ; } } catch (IOException e) { e.printStackTrace(); } } while (!exit); } static EntityManagerFactory emf=Persistence.createEntityManagerFactory( "empDB.odb" ); static EntityManager em=emf.createEntityManager(); static Scanner input= new Scanner(System.in); static BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(System.in)); static int n; static String name; static Double Salary; static boolean exit= false ; //Query Repository static String countQuery= "Select count(emp) from Employee emp" ; static String displayAllQuery= "Select emp from Employee emp" ; } |
Теперь сохраните ваш проект и нажмите кнопку запуска или нажмите Ctrl + F11. Теперь программа должна запуститься, и вы можете увидеть вывод в разделе консоли, представленном на нижней панели. Это просто консольное приложение. Я призываю вас разработать графический интерфейс для этого!
VI. Инструмент Проводник ObjectDB
Прежде чем мы закончим, я хотел бы познакомить вас с очень полезным инструментом, предоставляемым ObjectDB. Он называется ObjectDB Explorer, и его можно использовать для просмотра содержимого файлов базы данных. (т.е.) вы можете исследовать свою базу данных без написания кода для доступа к ней. Это может быть очень полезно для понимания вашего приложения и для целей отладки. Вы можете найти проводник в каталоге bin Object DB (где вы извлекли файлы ObjectDB). Запустите explorer.exe. Теперь вы можете открыть БД, используя опцию File-> Open Local. Open Remote выполняется при доступе к базе данных, хранящейся на сервере. Теперь просмотрите и выберите базу данных и откройте ее. Теперь дважды щелкните по вашей базе данных, показанной на панели «Персистентные классы» в левой части. Теперь Object Browser отобразит вашу БД. Вы можете развернуть каждый объект в БД, чтобы просмотреть его содержимое. Довольно аккуратно, да?
Вот как выглядит моя база данных после некоторых вставок …
Этот проводник также предоставляет множество других опций. Не стесняйтесь исследовать их!
Я полагаю, у вас есть яркое представление о JPA. Я объяснил простые основы JPA с использованием реализации ObjectDB. Чтобы понять больше и расширить свои знания, вы можете обратиться к руководству ObjectDB, которое содержит подробный и полный текст о JPA с ObjectDB. Это действительно полезная функция Java, которая вам очень поможет. Мне очень помогли! Поэтому постарайтесь узнать больше об этом.
Вы можете скачать исходный код здесь
Ссылка: Java Persistence API: краткое введение… от нашего партнера по JCG Стива Робинсона из блога Footy ‘n’ Tech .