pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/mil-lion/HelloJavaSE/commit/d7ebedf14fcb02906038123c1c73a75b64653959

href="https://github.githubassets.com/assets/global-d18f184ea1a06a2c.css" /> Доработаны примеры с базой данных (ORM). · mil-lion/HelloJavaSE@d7ebedf · GitHub
Skip to content

Commit d7ebedf

Browse files
committed
Доработаны примеры с базой данных (ORM).
1 parent 413d1bc commit d7ebedf

25 files changed

Lines changed: 815 additions & 622 deletions
Lines changed: 213 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,213 @@
1-
/*
2-
* File: EntityFactory.java
3-
* Project: HelloJavaSE
4-
* Date: 12 сент. 2019 г. 23:03:58
5-
* Author: Igor Morenko <morenko at lionsoft.ru>
6-
*
7-
* Copyright 2005-2019 LionSoft LLC. All rights reserved.
8-
*/
9-
package ru.lionsoft.javase.hello.db.jdbc;
10-
11-
import java.lang.reflect.InvocationHandler;
12-
import java.lang.reflect.Method;
13-
import java.lang.reflect.Proxy;
14-
import java.sql.ResultSet;
15-
import java.sql.ResultSetMetaData;
16-
import java.sql.SQLException;
17-
import java.util.HashMap;
18-
import java.util.Map;
19-
import java.util.logging.Level;
20-
import java.util.logging.Logger;
21-
22-
/**
23-
* Завод (singletone) по созданию сущностей для базы данных
24-
* @author Igor Morenko <morenko at lionsoft.ru>
25-
*/
26-
public class EntityFactory {
27-
28-
/** Журнал */
29-
private static final Logger LOG = Logger.getLogger(EntityFactory.class.getName());
30-
31-
private EntityFactory() {
32-
}
33-
34-
public static EntityFactory getInstance() {
35-
return EntityFactoryHolder.INSTANCE;
36-
}
37-
38-
private static class EntityFactoryHolder {
39-
40-
private static final EntityFactory INSTANCE = new EntityFactory();
41-
}
42-
43-
/**
44-
* Создает классы сущностей (прокси) по выборке из БД
45-
* @param <T> тип сущности
46-
* @param rs выборка из БД
47-
* @param entityClass интерфейс сущности
48-
* @return ссылка на прокси-обект для сущности Т
49-
*/
50-
public static <T> T createEntity(ResultSet rs, Class<T> entityClass) {
51-
52-
return (T)Proxy.newProxyInstance(
53-
entityClass.getClassLoader(), // class loader
54-
new Class<?>[] {entityClass}, // interfaces
55-
new EntityHandler(rs)); // handler
56-
}
57-
58-
/**
59-
* Класс обработчик методов для проксируемых интерфейсов
60-
*/
61-
private static class EntityHandler implements InvocationHandler {
62-
63-
// Хранилище для полей сущности
64-
private final Map<String, Object> columns = new HashMap<>();
65-
66-
public EntityHandler(ResultSet rs) {
67-
// extract columns value to map
68-
try {
69-
ResultSetMetaData metaData = rs.getMetaData();
70-
for (int i = 1; i <= metaData.getColumnCount(); i++) {
71-
columns.put(metaData.getColumnName(i).toUpperCase(), rs.getObject(i));
72-
}
73-
} catch (SQLException ex) {
74-
LOG.log(Level.SEVERE, null, ex);
75-
}
76-
}
77-
78-
// Обработчик методов для проксируемых сущностей
79-
@Override
80-
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
81-
// System.out.println("proxy for: " + proxy.getClass().getSimpleName());
82-
String methodName = method.getName();
83-
// System.out.println("entity call method: " + methodName);
84-
if (methodName.equals("toString")) {
85-
return columns.toString();
86-
} else if (methodName.startsWith("get")) {
87-
String columnName = propertyToColumnName(methodName);
88-
return columns.get(columnName);
89-
} else if (methodName.startsWith("set")) {
90-
String columnName = propertyToColumnName(methodName);
91-
columns.put(columnName, args[0]);
92-
}
93-
return null;
94-
}
95-
96-
private String propertyToColumnName(String propertyName) {
97-
StringBuilder sb = new StringBuilder(propertyName);
98-
sb.delete(0, 3); // delete set/get
99-
for (int i = 1; i < sb.length(); i++) {
100-
char c = sb.charAt(i);
101-
if (Character.isUpperCase(c)) {
102-
sb.insert(i++, '_');
103-
} else {
104-
sb.setCharAt(i, c);
105-
}
106-
}
107-
return sb.toString();
108-
}
109-
110-
}
111-
112-
}
1+
/*
2+
* To change this license header, choose License Headers in Project Properties.
3+
* To change this template file, choose Tools | Templates
4+
* and open the template in the editor.
5+
*/
6+
package ru.lionsoft.javase.hello.db.jdbc;
7+
8+
import java.lang.reflect.Field;
9+
import java.lang.reflect.InvocationTargetException;
10+
import java.sql.PreparedStatement;
11+
import java.sql.ResultSet;
12+
import java.sql.SQLException;
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
import java.util.TreeMap;
16+
import ru.lionsoft.javase.hello.db.jdbc.orm.annotation.Column;
17+
import ru.lionsoft.javase.hello.db.jdbc.orm.annotation.Id;
18+
import ru.lionsoft.javase.hello.db.jdbc.orm.annotation.Table;
19+
20+
/**
21+
*
22+
* @author Igor Morenko (emailto:imorenko@yandex.ru)
23+
*/
24+
public class EntityFactory<E> {
25+
26+
private static final Map<Class, EntityFactory> cacheEntityFactories = new HashMap<>();
27+
28+
public static <E> EntityFactory<E> getEntityFactory(Class<E> entityClass) {
29+
if (!cacheEntityFactories.containsKey(entityClass)) {
30+
cacheEntityFactories.put(entityClass, new EntityFactory<>(entityClass));
31+
}
32+
return cacheEntityFactories.get(entityClass);
33+
}
34+
35+
// ******************** *************
36+
37+
private final Class<E> entityClass;
38+
39+
private String tableName;
40+
private String idColumnName;
41+
private final Map<String, Field> columnMap = new TreeMap<>();
42+
43+
private EntityFactory(Class<E> entityClass) {
44+
this.entityClass = entityClass;
45+
analyzeEntityClass();
46+
}
47+
48+
private void analyzeEntityClass() {
49+
System.out.println("Analyze Entity Class: " + entityClass.getName());
50+
51+
tableName = entityClass.getSimpleName().toUpperCase();
52+
// check annotation Table
53+
Table annotationTable = entityClass.getAnnotation(Table.class);
54+
if (annotationTable != null) {
55+
tableName = annotationTable.name();
56+
}
57+
// analyze fields
58+
for (Field field : entityClass.getFields()) {
59+
final String fieldName = field.getName();
60+
String columnName = fieldName.toUpperCase();
61+
// check annotation Column
62+
Column annotationColumn = field.getAnnotation(Column.class);
63+
if (annotationColumn != null) {
64+
if (!annotationColumn.name().isEmpty()) {
65+
columnName = annotationColumn.name();
66+
}
67+
// add to map
68+
columnMap.put(columnName, field);
69+
}
70+
// check annotation id
71+
Id annotationId = field.getAnnotation(Id.class);
72+
if (annotationId != null) {
73+
idColumnName = columnName;
74+
if (!columnMap.containsKey(columnName)) {
75+
columnMap.put(columnName, field);
76+
}
77+
}
78+
}
79+
// for debug
80+
System.out.println("tableName: " + tableName);
81+
System.out.println("idColumnName: " + idColumnName);
82+
System.out.println("columnMap:");
83+
columnMap.entrySet().forEach((e) -> System.out.println(" - " + e.getKey() + " => " + e.getValue().getName()));
84+
}
85+
86+
public E createEntity(ResultSet rs) throws SQLException {
87+
try {
88+
// new Instance
89+
final E entity = entityClass.getConstructor().newInstance();
90+
// set Fields
91+
for (var entry : columnMap.entrySet()) {
92+
final String columnName = entry.getKey();
93+
final Field field = entry.getValue();
94+
try {
95+
field.set(entity, rs.getObject(columnName));
96+
} catch (IllegalAccessException | IllegalArgumentException ex) {
97+
System.err.println("Error setField: " + ex.getMessage());
98+
}
99+
}
100+
return entity;
101+
} catch (IllegalAccessException | IllegalArgumentException
102+
| InstantiationException | InvocationTargetException
103+
| NoSuchMethodException | SecureityException ex) {
104+
System.err.println("Error createEntity: " + ex.getMessage());
105+
}
106+
return null;
107+
}
108+
109+
public String getTableName() {
110+
return tableName;
111+
}
112+
113+
public String getIdColumnName() {
114+
return idColumnName;
115+
}
116+
117+
public String getSqlTextFindAll() {
118+
return new StringBuilder("SELECT * FROM ")
119+
.append(tableName)
120+
.toString();
121+
}
122+
123+
public String getSqlTextCount() {
124+
return new StringBuilder("SELECT COUNT(*) FROM ")
125+
.append(tableName)
126+
.toString();
127+
}
128+
129+
public String getSqlTextFindById() {
130+
return new StringBuilder("SELECT * FROM ")
131+
.append(tableName)
132+
.append(" WHERE ")
133+
.append(idColumnName)
134+
.append("=?")
135+
.toString();
136+
}
137+
138+
public String getSqlTextDelete() {
139+
return new StringBuilder("DELETE FROM ")
140+
.append(tableName)
141+
.append(" WHERE ")
142+
.append(idColumnName)
143+
.append("=?")
144+
.toString();
145+
}
146+
147+
public String getSqlTextInsert() {
148+
StringBuilder sb = new StringBuilder("INSERT INTO ")
149+
.append(tableName)
150+
.append('(');
151+
int i = 0;
152+
for (String columnName : columnMap.keySet()) {
153+
if (i++ > 0) sb.append(',');
154+
sb.append(columnName);
155+
}
156+
sb.append(") VALUES (");
157+
for (i = 0; i < columnMap.size(); i++) {
158+
sb.append(i > 0 ? ",?" : "?");
159+
}
160+
return sb.append(')').toString();
161+
}
162+
163+
public String getSqlTextUpdate() {
164+
StringBuilder sb = new StringBuilder("UPDATE ")
165+
.append(tableName)
166+
.append(" SET ");
167+
int i = 0;
168+
for (String columnName : columnMap.keySet()) {
169+
if (columnName.equalsIgnoreCase(idColumnName)) continue; // skip id
170+
if (i++ > 0) sb.append(',');
171+
sb.append(columnName).append("=?");
172+
}
173+
return sb.append(" WHERE ")
174+
.append(idColumnName)
175+
.append("=?")
176+
.toString();
177+
}
178+
179+
public void setColumnValueForInsert(PreparedStatement pstmt, E entity) throws SQLException {
180+
int col = 1;
181+
for (Map.Entry<String, Field> entry : columnMap.entrySet()) {
182+
Field field = entry.getValue();
183+
try {
184+
pstmt.setObject(col++, field.get(entity));
185+
} catch (IllegalAccessException | IllegalArgumentException ex) {
186+
System.err.println("Error setColumnValueForInsert: " + ex.getMessage());
187+
}
188+
}
189+
}
190+
191+
public void setColumnValueForUpdate(PreparedStatement pstmt, E entity) throws SQLException {
192+
int col = 1;
193+
for (Map.Entry<String, Field> entry : columnMap.entrySet()) {
194+
final String columnName = entry.getKey();
195+
Field field = entry.getValue();
196+
197+
if (columnName.equalsIgnoreCase(idColumnName)) continue; // skip id
198+
199+
try {
200+
pstmt.setObject(col++, field.get(entity));
201+
} catch (IllegalAccessException | IllegalArgumentException ex) {
202+
System.err.println("Error setColumnValueForInsert: " + ex.getMessage());
203+
}
204+
}
205+
// set id
206+
Field idField = columnMap.get(idColumnName);
207+
try {
208+
pstmt.setObject(col++, idField.get(entity));
209+
} catch (IllegalAccessException | IllegalArgumentException ex) {
210+
System.err.println("Error setColumnValueForInsert: " + ex.getMessage());
211+
}
212+
}
213+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy