Skip to content

Commit 5d07931

Browse files
committed
refactoring of daos and builders
1 parent 7919531 commit 5d07931

9 files changed

+352
-295
lines changed

src/main/java/info/unterrainer/commons/httpserver/daos/BasicDao.java

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package info.unterrainer.commons.httpserver.daos;
22

3+
import javax.persistence.TypedQuery;
4+
35
import info.unterrainer.commons.httpserver.jsons.ListJson;
46
import info.unterrainer.commons.rdbutils.entities.BasicJpa;
57

@@ -16,25 +18,19 @@ ListJson<P> getList(E em, long offset, long size, String selectClause, String jo
1618

1719
UpsertResult<P> upsert(String whereClause, ParamMap params, P entity);
1820

19-
UpsertResult<P> upsert(Query<P, P> query, P entity);
21+
UpsertResult<P> upsert(TypedQuery<P> query, P entity);
2022

2123
void delete(Long id);
2224

2325
P getById(E em, Long id);
2426

25-
<T> QueryBuilder<P, T> query(Class<T> resultType);
26-
27-
QueryBuilder<P, P> query();
28-
29-
CountQueryBuilder<P> countQuery();
30-
3127
P create(E em, P entity);
3228

3329
P update(E em, P entity);
3430

3531
UpsertResult<P> upsert(E em, String whereClause, ParamMap params, P entity);
3632

37-
UpsertResult<P> upsert(E em, Query<P, P> query, P entity);
33+
UpsertResult<P> upsert(E em, TypedQuery<P> query, P entity);
3834

3935
void delete(E em, Long id);
4036
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
package info.unterrainer.commons.httpserver.daos;
2+
3+
import java.time.LocalDateTime;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.Map.Entry;
7+
import java.util.Set;
8+
9+
import javax.persistence.EntityManager;
10+
import javax.persistence.EntityManagerFactory;
11+
import javax.persistence.LockModeType;
12+
import javax.persistence.NoResultException;
13+
import javax.persistence.Query;
14+
import javax.persistence.TypedQuery;
15+
16+
import info.unterrainer.commons.httpserver.jsons.ListJson;
17+
import info.unterrainer.commons.jreutils.DateUtils;
18+
import info.unterrainer.commons.rdbutils.Transactions;
19+
import info.unterrainer.commons.rdbutils.entities.BasicJpa;
20+
import info.unterrainer.commons.rdbutils.enums.AsyncState;
21+
import lombok.RequiredArgsConstructor;
22+
import lombok.extern.slf4j.Slf4j;
23+
24+
@RequiredArgsConstructor
25+
@Slf4j
26+
public class BasicJpqlDao<P extends BasicJpa> implements BasicDao<P, EntityManager> {
27+
28+
protected final EntityManagerFactory emf;
29+
protected final Class<P> type;
30+
31+
@Override
32+
public P getById(final Long id) {
33+
return Transactions.withNewTransactionReturning(emf, em -> getById(em, id));
34+
}
35+
36+
@Override
37+
public ListJson<P> getList(final EntityManager em, final long offset, final long size, final String selectClause,
38+
final String joinClause, final String whereClause, final ParamMap params, final String orderByClause) {
39+
ListJson<P> r = new ListJson<>();
40+
r.setEntries(getList(em, getQuery(em, selectClause, joinClause, whereClause, params.getParameters(), type,
41+
orderByClause, false, null), offset, size));
42+
r.setCount((Long) getCountQuery(em, selectClause, joinClause, whereClause, params.getParameters(), null)
43+
.getSingleResult());
44+
return r;
45+
}
46+
47+
@Override
48+
public P create(final P entity) {
49+
return Transactions.withNewTransactionReturning(emf, em -> create(em, entity));
50+
}
51+
52+
@Override
53+
public P create(final EntityManager em, final P entity) {
54+
LocalDateTime time = DateUtils.nowUtc();
55+
entity.setCreatedOn(time);
56+
entity.setEditedOn(time);
57+
em.persist(entity);
58+
return entity;
59+
}
60+
61+
@Override
62+
public P update(final P entity) {
63+
return Transactions.withNewTransactionReturning(emf, em -> update(em, entity));
64+
}
65+
66+
@Override
67+
public P update(final EntityManager em, final P entity) {
68+
LocalDateTime time = DateUtils.nowUtc();
69+
entity.setEditedOn(time);
70+
return em.merge(entity);
71+
}
72+
73+
public <T> List<T> getList(final EntityManager em, final TypedQuery<T> query, final long offset, final long size) {
74+
int s = Integer.MAX_VALUE;
75+
if (size < s)
76+
s = (int) size;
77+
int o = Integer.MAX_VALUE;
78+
if (offset < o)
79+
o = (int) offset;
80+
query.setFirstResult(o);
81+
query.setMaxResults(s);
82+
return query.getResultList();
83+
}
84+
85+
@Override
86+
public UpsertResult<P> upsert(final String whereClause, final ParamMap params, final P entity) {
87+
return Transactions.withNewTransactionReturning(emf, em -> upsert(em,
88+
getQuery(em, "o", null, whereClause, params.getParameters(), type, null, false, null), entity));
89+
}
90+
91+
@Override
92+
public UpsertResult<P> upsert(final EntityManager em, final String whereClause, final ParamMap params,
93+
final P entity) {
94+
return upsert(em, getQuery(em, "o", null, whereClause, params.getParameters(), type, null, false, null),
95+
entity);
96+
}
97+
98+
@Override
99+
public UpsertResult<P> upsert(final TypedQuery<P> query, final P entity) {
100+
return Transactions.withNewTransactionReturning(emf, em -> upsert(em, query, entity));
101+
}
102+
103+
private P getFirst(final EntityManager em, final TypedQuery<P> query) {
104+
List<P> r = getList(em, query, 0, 1);
105+
if (r.size() == 1) {
106+
P jpa = r.get(0);
107+
return jpa;
108+
}
109+
return null;
110+
}
111+
112+
@Override
113+
public UpsertResult<P> upsert(final EntityManager em, final TypedQuery<P> query, final P entity) {
114+
boolean wasInserted = false;
115+
boolean wasUpdated = false;
116+
P e = getFirst(em, query);
117+
if (e == null) {
118+
e = create(em, entity);
119+
wasInserted = true;
120+
} else {
121+
entity.setId(e.getId());
122+
entity.setCreatedOn(e.getCreatedOn());
123+
e = update(em, entity);
124+
wasUpdated = true;
125+
}
126+
return UpsertResult.<P>builder().wasInserted(wasInserted).wasUpdated(wasUpdated).jpa(e).build();
127+
}
128+
129+
@Override
130+
public void delete(final Long id) {
131+
Transactions.withNewTransaction(emf, em -> {
132+
delete(em, id);
133+
});
134+
}
135+
136+
@Override
137+
public void delete(final EntityManager em, final Long id) {
138+
em.createQuery(String.format("DELETE FROM %s AS o WHERE o.id = :id", type.getSimpleName()))
139+
.setParameter("id", id)
140+
.executeUpdate();
141+
}
142+
143+
@Override
144+
public P getById(final EntityManager em, final Long id) {
145+
try {
146+
return getQuery(em, "o", null, "o.id = :id", Map.of("id", id), type, null, false, null).getSingleResult();
147+
} catch (NoResultException e) {
148+
return null;
149+
}
150+
}
151+
152+
private boolean isSet(final String str) {
153+
return str != null && !str.isBlank();
154+
}
155+
156+
private boolean isSet(final Set<?> set) {
157+
return set != null && !set.isEmpty();
158+
}
159+
160+
private String buildWhereClause(final String whereClause, final Set<AsyncState> asyncStates) {
161+
String r = "";
162+
if (!isSet(whereClause) && !isSet(asyncStates))
163+
return r;
164+
165+
r = " WHERE ";
166+
if (isSet(whereClause) && !isSet(asyncStates))
167+
r += whereClause;
168+
169+
if (!isSet(whereClause) && isSet(asyncStates))
170+
r += addAsyncStatesToWhereClause(asyncStates);
171+
172+
if (isSet(whereClause) && isSet(asyncStates))
173+
r += "( " + whereClause + " ) AND ( " + addAsyncStatesToWhereClause(asyncStates) + " )";
174+
175+
return r;
176+
}
177+
178+
private String addAsyncStatesToWhereClause(final Set<AsyncState> asyncStates) {
179+
StringBuilder sb = new StringBuilder();
180+
boolean isFirst = true;
181+
182+
for (int i = 0; i < asyncStates.size(); i++) {
183+
if (isFirst)
184+
isFirst = false;
185+
else
186+
sb.append(" OR ");
187+
sb.append("state = :state");
188+
sb.append(i);
189+
}
190+
191+
return sb.toString();
192+
}
193+
194+
private <T> TypedQuery<T> addAsyncStatesParamsToQuery(final Set<AsyncState> asyncStates,
195+
final TypedQuery<T> query) {
196+
197+
if (!isSet(asyncStates))
198+
return query;
199+
200+
int count = 0;
201+
for (AsyncState state : asyncStates)
202+
query.setParameter("state" + count++, state);
203+
204+
return query;
205+
}
206+
207+
private Query addAsyncStatesParamsToQuery(final Set<AsyncState> asyncStates, final Query query) {
208+
209+
if (!isSet(asyncStates))
210+
return query;
211+
212+
int count = 0;
213+
for (AsyncState state : asyncStates)
214+
query.setParameter("state" + count++, state);
215+
216+
return query;
217+
}
218+
219+
<T> TypedQuery<T> getQuery(final EntityManager em, final String selectClause, final String joinClause,
220+
final String whereClause, final Map<String, Object> params, final Class<T> type, final String orderBy,
221+
final boolean lockPessimistic, final Set<AsyncState> asyncStates) {
222+
String query = "SELECT ";
223+
if (selectClause == null || selectClause.isBlank())
224+
query += "o";
225+
else
226+
query += selectClause;
227+
query += " FROM %s AS o";
228+
229+
if (joinClause != null && !joinClause.isBlank())
230+
query += " " + joinClause;
231+
232+
query += buildWhereClause(whereClause, asyncStates);
233+
234+
if (orderBy == null)
235+
query += " ORDER BY o.id ASC";
236+
else if (!orderBy.isBlank())
237+
query += " ORDER BY " + orderBy;
238+
239+
query = String.format(query, this.type.getSimpleName());
240+
241+
String msg = query;
242+
if (params != null)
243+
for (Entry<String, Object> p : params.entrySet())
244+
msg += "\\n " + p.getKey() + ": " + p.getValue();
245+
log.debug(msg);
246+
247+
@SuppressWarnings("unchecked")
248+
Class<T> t = (Class<T>) this.type;
249+
if (type != null)
250+
t = type;
251+
252+
if (query.contains("nullo.id"))
253+
System.out.println("");
254+
TypedQuery<T> q = em.createQuery(query, t);
255+
if (lockPessimistic)
256+
q.setLockMode(LockModeType.PESSIMISTIC_WRITE);
257+
q = addAsyncStatesParamsToQuery(asyncStates, q);
258+
if (params != null)
259+
for (Entry<String, Object> e : params.entrySet())
260+
q.setParameter(e.getKey(), e.getValue());
261+
return q;
262+
}
263+
264+
Query getCountQuery(final EntityManager em, final String selectClause, final String joinClause,
265+
final String whereClause, final Map<String, Object> params, final Set<AsyncState> asyncStates) {
266+
String query = "SELECT COUNT(" + selectClause + ") FROM %s AS o";
267+
if (joinClause != null && !joinClause.isBlank())
268+
query += " " + joinClause;
269+
query += buildWhereClause(whereClause, asyncStates);
270+
271+
Query q = em.createQuery(String.format(query, this.type.getSimpleName()));
272+
273+
q = addAsyncStatesParamsToQuery(asyncStates, q);
274+
if (params != null)
275+
for (Entry<String, Object> e : params.entrySet())
276+
q.setParameter(e.getKey(), e.getValue());
277+
return q;
278+
}
279+
}

src/main/java/info/unterrainer/commons/httpserver/daos/BasicQueryBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
public class BasicQueryBuilder<P extends BasicJpa, T, R extends BasicQueryBuilder<P, T, R>> {
1515

1616
protected final EntityManagerFactory emf;
17-
protected final JpqlDao<P> dao;
17+
protected final BasicJpqlDao<P> dao;
1818
protected final Class<T> resultType;
1919

2020
protected EntityManager entityManager;

src/main/java/info/unterrainer/commons/httpserver/daos/JpqlAsyncDao.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44

55
import info.unterrainer.commons.rdbutils.entities.BasicAsyncJpa;
66

7-
public class JpqlAsyncDao<P extends BasicAsyncJpa> extends JpqlDao<P> {
7+
public class JpqlAsyncDao<P extends BasicAsyncJpa> extends BasicJpqlDao<P> {
88

99
public JpqlAsyncDao(final EntityManagerFactory emf, final Class<P> type) {
1010
super(emf, type);
1111
}
1212

13-
@Override
1413
public QueryAsyncBuilder<P, P> query() {
1514
return new QueryAsyncBuilder<>(emf, this, type);
1615
}
16+
17+
public <T> QueryAsyncBuilder<P, T> query(final Class<T> resultType) {
18+
return new QueryAsyncBuilder<>(emf, this, resultType);
19+
}
1720
}

0 commit comments

Comments
 (0)