mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1351 - ENH: Add named DtoQuery
Merge branch 'feature/namedDtoQuery' of https://github.com/hexagonframework/ebean into hexagonframework-feature/namedDtoQuery
This commit is contained in:
@@ -8,12 +8,6 @@ import io.ebean.plugin.Property;
|
||||
import io.ebean.plugin.SpiServer;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -22,6 +16,11 @@ import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
/**
|
||||
* Provides the API for fetching and saving beans to a particular DataSource.
|
||||
@@ -105,6 +104,7 @@ public interface EbeanServer {
|
||||
*
|
||||
* @param shutdownDataSource if true then shutdown the underlying DataSource if it is the EbeanORM
|
||||
* DataSource implementation.
|
||||
* DataSource implementation.
|
||||
* @param deregisterDriver if true then deregister the JDBC driver if it is the EbeanORM
|
||||
* DataSource implementation.
|
||||
*/
|
||||
@@ -437,6 +437,19 @@ public interface EbeanServer {
|
||||
*/
|
||||
<T> DtoQuery<T> findDto(Class<T> dtoType, String sql);
|
||||
|
||||
/**
|
||||
* Create a named Query for DTO beans.
|
||||
* <p>
|
||||
* DTO beans are just normal bean like classes with public constructor(s) and setters.
|
||||
* They do not need to be registered with Ebean before use.
|
||||
* </p>
|
||||
*
|
||||
* @param dtoType The type of the DTO bean the rows will be mapped into.
|
||||
* @param namedQuery The name of the query
|
||||
* @param <T> The type of the DTO bean.
|
||||
*/
|
||||
<T> DtoQuery<T> createNamedDtoQuery(Class<T> dtoType, String namedQuery);
|
||||
|
||||
/**
|
||||
* Create a SqlQuery for executing native sql
|
||||
* query statements.
|
||||
|
||||
@@ -489,8 +489,7 @@ public class ServerConfig {
|
||||
private boolean defaultOrderById = false;
|
||||
|
||||
/**
|
||||
* The mappingLocations for searching xml mapping. Only used when
|
||||
* mappingLocations is empty/not explicitly specified.
|
||||
* The mappingLocations for searching xml mapping.
|
||||
*/
|
||||
private List<String> mappingLocations = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -105,13 +105,6 @@ import io.ebeaninternal.server.transaction.TransactionManager;
|
||||
import io.ebeaninternal.util.ParamTypeHelper;
|
||||
import io.ebeaninternal.util.ParamTypeHelper.TypeInfo;
|
||||
import io.ebeanservice.docstore.api.DocStoreIntegration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -126,6 +119,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The default server side implementation of EbeanServer.
|
||||
@@ -966,7 +965,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Query<T> createQuery(Class<T> beanType, String eql) {
|
||||
public <T> DefaultOrmQuery<T> createQuery(Class<T> beanType, String eql) {
|
||||
DefaultOrmQuery<T> query = createQuery(beanType);
|
||||
EqlParser.parse(eql, query);
|
||||
return query;
|
||||
@@ -999,6 +998,16 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
return new DefaultDtoQuery<>(this, descriptor, sql.trim());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DtoQuery<T> createNamedDtoQuery(Class<T> dtoType, String namedQuery) {
|
||||
DtoBeanDescriptor<T> descriptor = dtoBeanManager.getDescriptor(dtoType);
|
||||
SpiRawSql rawSql = descriptor.getNamedRawSql(namedQuery);
|
||||
if (rawSql != null) {
|
||||
return new DefaultDtoQuery<>(this, descriptor, rawSql.getSql().getUnparsedSql());
|
||||
}
|
||||
throw new PersistenceException("No named query called " + namedQuery + " for bean:" + dtoType.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DtoQuery<T> findDto(Class<T> dtoType, SpiQuery<?> ormQuery) {
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebeaninternal.xmlmapping.XmlMappingReader;
|
||||
import io.ebeaninternal.xmlmapping.model.XmEbean;
|
||||
import org.avaje.classpath.scanner.ClassPathScanner;
|
||||
import org.avaje.classpath.scanner.Resource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class InternalConfigXmlRead {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(InternalConfigXmlRead.class);
|
||||
|
||||
private final ServerConfig serverConfig;
|
||||
|
||||
InternalConfigXmlRead(ServerConfig serverConfig) {
|
||||
this.serverConfig = serverConfig;
|
||||
}
|
||||
|
||||
List<XmEbean> build() {
|
||||
|
||||
ClassLoader classLoader = serverConfig.getClassLoadConfig().getClassLoader();
|
||||
List<XmEbean> xmlEbeanList = XmlMappingReader.readByResourceName(classLoader, "ebean.xml");
|
||||
|
||||
List<Resource> resources = searchXmlMapping();
|
||||
xmlEbeanList.addAll(XmlMappingReader.readByResourceList(resources));
|
||||
|
||||
return xmlEbeanList;
|
||||
}
|
||||
|
||||
|
||||
private List<Resource> searchXmlMapping() {
|
||||
List<ClassPathScanner> scanners = ClassPathScanners.find(serverConfig);
|
||||
List<String> mappingLocations = serverConfig.getMappingLocations();
|
||||
List<Resource> resourceList = new ArrayList<>();
|
||||
|
||||
long st = System.currentTimeMillis();
|
||||
if (mappingLocations != null && !mappingLocations.isEmpty()) {
|
||||
for (ClassPathScanner finder : scanners) {
|
||||
for (String mappingLocation : mappingLocations) {
|
||||
resourceList.addAll(finder.scanForResources(mappingLocation, resourceName -> resourceName.endsWith(".xml")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long searchTime = System.currentTimeMillis() - st;
|
||||
log.debug("Classpath search mappings[{}] searchTime[{}]", resourceList.size(), searchTime);
|
||||
return resourceList;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -69,19 +69,23 @@ import io.ebeaninternal.server.transaction.TransactionManagerOptions;
|
||||
import io.ebeaninternal.server.transaction.TransactionScopeManager;
|
||||
import io.ebeaninternal.server.type.DefaultTypeManager;
|
||||
import io.ebeaninternal.server.type.TypeManager;
|
||||
import io.ebeaninternal.xmlmapping.XmlMappingReader;
|
||||
import io.ebeaninternal.xmlmapping.model.XmEbean;
|
||||
import io.ebeanservice.docstore.api.DocStoreFactory;
|
||||
import io.ebeanservice.docstore.api.DocStoreIntegration;
|
||||
import io.ebeanservice.docstore.api.DocStoreUpdateProcessor;
|
||||
import io.ebeanservice.docstore.none.NoneDocStoreFactory;
|
||||
import org.avaje.datasource.DataSourcePool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import javax.sql.DataSource;
|
||||
import org.avaje.classpath.scanner.ClassPathScanner;
|
||||
import org.avaje.classpath.scanner.Resource;
|
||||
import org.avaje.classpath.scanner.ResourceFilter;
|
||||
import org.avaje.datasource.DataSourcePool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Used to extend the ServerConfig with additional objects used to configure and
|
||||
@@ -134,6 +138,8 @@ public class InternalConfiguration {
|
||||
|
||||
private final MultiValueBind multiValueBind;
|
||||
|
||||
private List<XmEbean> xmlEbeanList = new ArrayList<>();
|
||||
|
||||
public InternalConfiguration(ClusterManager clusterManager,
|
||||
SpiCacheManager cacheManager, SpiBackgroundExecutor backgroundExecutor,
|
||||
ServerConfig serverConfig, BootupClasses bootupClasses) {
|
||||
@@ -153,12 +159,20 @@ public class InternalConfiguration {
|
||||
this.multiValueBind = createMultiValueBind(databasePlatform.getPlatform());
|
||||
this.deployInherit = new DeployInherit(bootupClasses);
|
||||
|
||||
xmlEbeanList = XmlMappingReader.readByResourceName(serverConfig.getClassLoadConfig().getClassLoader(),
|
||||
"ebean.xml");
|
||||
List<Resource> searchXmlMapping = searchXmlMapping();
|
||||
xmlEbeanList.addAll(XmlMappingReader.readByResourceList(serverConfig.getClassLoadConfig().getClassLoader(),
|
||||
searchXmlMapping));
|
||||
|
||||
this.deployCreateProperties = new DeployCreateProperties(typeManager);
|
||||
this.deployUtil = new DeployUtil(typeManager, serverConfig);
|
||||
this.dtoBeanManager = new DtoBeanManager(typeManager);
|
||||
dtoBeanManager.readXmlMapping(serverConfig.getClassLoadConfig().getClassLoader(),
|
||||
xmlEbeanList);
|
||||
|
||||
this.beanDescriptorManager = new BeanDescriptorManager(this);
|
||||
Map<String, String> asOfTableMapping = beanDescriptorManager.deploy();
|
||||
Map<String, String> asOfTableMapping = beanDescriptorManager.deploy(xmlEbeanList);
|
||||
Map<String, String> draftTableMap = beanDescriptorManager.getDraftTableMap();
|
||||
beanDescriptorManager.scheduleBackgroundTrim();
|
||||
|
||||
@@ -167,6 +181,31 @@ public class InternalConfiguration {
|
||||
this.cQueryEngine = new CQueryEngine(serverConfig, databasePlatform, binder, asOfTableMapping, draftTableMap);
|
||||
}
|
||||
|
||||
private List<Resource> searchXmlMapping() {
|
||||
List<ClassPathScanner> scanners = ClassPathScanners.find(serverConfig);
|
||||
List<String> mappingLocations = serverConfig.getMappingLocations();
|
||||
List<Resource> resourceList = new ArrayList<>();
|
||||
|
||||
long st = System.currentTimeMillis();
|
||||
if (mappingLocations != null && !mappingLocations.isEmpty()) {
|
||||
for (ClassPathScanner finder : scanners) {
|
||||
for (String mappingLocation : mappingLocations) {
|
||||
resourceList.addAll(finder.scanForResources(mappingLocation, new ResourceFilter() {
|
||||
|
||||
@Override
|
||||
public boolean isMatch(String resourceName) {
|
||||
return resourceName.endsWith(".xml");
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long searchTime = System.currentTimeMillis() - st;
|
||||
logger.debug("Classpath search mappings[{}] searchTime[{}]", resourceList.size(), searchTime);
|
||||
return resourceList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return the ExpressionFactory based on configuration and database platform.
|
||||
*/
|
||||
|
||||
@@ -367,12 +367,12 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
/**
|
||||
* Deploy returning the asOfTableMap (which is required by the SQL builders).
|
||||
*/
|
||||
public Map<String, String> deploy() {
|
||||
public Map<String, String> deploy(List<XmEbean> mappings) {
|
||||
|
||||
try {
|
||||
createListeners();
|
||||
readEntityDeploymentInitial();
|
||||
readXmlMapping();
|
||||
readXmlMapping(mappings);
|
||||
readEmbeddedDeployment();
|
||||
readEntityBeanTable();
|
||||
readEntityDeploymentAssociations();
|
||||
@@ -403,63 +403,15 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
}
|
||||
}
|
||||
|
||||
private void readXmlMapping() {
|
||||
private void readXmlMapping(List<XmEbean> mappings) {
|
||||
ClassLoader classLoader = serverConfig.getClassLoadConfig().getClassLoader();
|
||||
|
||||
try {
|
||||
ClassLoader classLoader = serverConfig.getClassLoadConfig().getClassLoader();
|
||||
|
||||
Enumeration<URL> resources = classLoader.getResources("ebean.xml");
|
||||
|
||||
List<XmEbean> mappings = new ArrayList<>();
|
||||
while (resources.hasMoreElements()) {
|
||||
URL url = resources.nextElement();
|
||||
try (InputStream is = url.openStream()) {
|
||||
mappings.add(XmlMappingReader.read(is));
|
||||
}
|
||||
}
|
||||
|
||||
List<Resource> xmlMappingResources = searchXmlMapping();
|
||||
for (Resource xmlMappingRes : xmlMappingResources) {
|
||||
try (InputStream is = new FileInputStream(xmlMappingRes.getLocationOnDisk())) {
|
||||
mappings.add(XmlMappingReader.read(is));
|
||||
}
|
||||
}
|
||||
|
||||
for (XmEbean mapping : mappings) {
|
||||
List<XmEntity> entityDeploy = mapping.getEntity();
|
||||
for (XmEntity deploy : entityDeploy) {
|
||||
readEntityMapping(classLoader, deploy);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading ebean xml mapping", e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Resource> searchXmlMapping() {
|
||||
List<ClassPathScanner> scanners = ClassPathScanners.find(serverConfig);
|
||||
List<String> mappingLocations = serverConfig.getMappingLocations();
|
||||
List<Resource> resourceList = new ArrayList<>();
|
||||
|
||||
long st = System.currentTimeMillis();
|
||||
if (mappingLocations != null && !mappingLocations.isEmpty()) {
|
||||
for (ClassPathScanner finder : scanners) {
|
||||
for (String mappingLocation : mappingLocations) {
|
||||
resourceList.addAll(finder.scanForResources(mappingLocation, new ResourceFilter() {
|
||||
|
||||
@Override
|
||||
public boolean isMatch(String resourceName) {
|
||||
return resourceName.endsWith(".xml");
|
||||
}
|
||||
}));
|
||||
}
|
||||
for (XmEbean mapping : mappings) {
|
||||
List<XmEntity> entityDeploy = mapping.getEntity();
|
||||
for (XmEntity deploy : entityDeploy) {
|
||||
readEntityMapping(classLoader, deploy);
|
||||
}
|
||||
}
|
||||
|
||||
long searchTime = System.currentTimeMillis() - st;
|
||||
logger.debug("Classpath search mappings[{}] searchTime[{}]", resourceList.size(), searchTime);
|
||||
return resourceList;
|
||||
}
|
||||
|
||||
private void readEntityMapping(ClassLoader classLoader, XmEntity entityDeploy) {
|
||||
@@ -1112,6 +1064,11 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
unidirectional.setDbRead(true);
|
||||
unidirectional.setDbInsertable(true);
|
||||
unidirectional.setDbUpdateable(false);
|
||||
|
||||
targetDesc.setUnidirectional(unidirectional);
|
||||
|
||||
// specify table and table alias...
|
||||
BeanTable beanTable = getBeanTable(owningType);
|
||||
unidirectional.setBeanTable(beanTable);
|
||||
unidirectional.setName(beanTable.getBaseTable());
|
||||
unidirectional.setJoinType(true);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package io.ebeaninternal.server.dto;
|
||||
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -10,15 +12,25 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
public class DtoBeanDescriptor<T> {
|
||||
|
||||
private static final Map<String, String> EMPTY_NAMED_QUERY = new HashMap<>();
|
||||
|
||||
private static final Map<String, SpiRawSql> EMPTY_RAW_MAP = new HashMap<>();
|
||||
|
||||
private final Map<Object, DtoQueryPlan> plans = new ConcurrentHashMap<>();
|
||||
|
||||
private final Class<T> dtoType;
|
||||
|
||||
private final DtoMeta meta;
|
||||
|
||||
private Map<String, SpiRawSql> namedRawSql;
|
||||
|
||||
private Map<String, String> namedQuery;
|
||||
|
||||
DtoBeanDescriptor(Class<T> dtoType, DtoMeta meta) {
|
||||
this.dtoType = dtoType;
|
||||
this.meta = meta;
|
||||
this.namedQuery = getNamedQuery();
|
||||
this.namedRawSql = getNamedRawSql();
|
||||
}
|
||||
|
||||
public Class<T> getType() {
|
||||
@@ -42,4 +54,52 @@ public class DtoBeanDescriptor<T> {
|
||||
plan.visit(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the named ORM query.
|
||||
*/
|
||||
public String getNamedQuery(String name) {
|
||||
return namedQuery.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the named RawSql query.
|
||||
*/
|
||||
public SpiRawSql getNamedRawSql(String named) {
|
||||
return namedRawSql.get(named);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the named ORM queries.
|
||||
*/
|
||||
public Map<String, String> getNamedQuery() {
|
||||
return (namedQuery != null) ? namedQuery : EMPTY_NAMED_QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a named query.
|
||||
*/
|
||||
public void addNamedQuery(String name, String query) {
|
||||
if (namedQuery == null) {
|
||||
namedQuery = new LinkedHashMap<>();
|
||||
}
|
||||
namedQuery.put(name, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the named RawSql queries.
|
||||
*/
|
||||
public Map<String, SpiRawSql> getNamedRawSql() {
|
||||
return (namedRawSql != null) ? namedRawSql : EMPTY_RAW_MAP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a named RawSql from ebean.xml file.
|
||||
*/
|
||||
public void addRawSql(String name, SpiRawSql rawSql) {
|
||||
if (namedRawSql == null) {
|
||||
namedRawSql = new HashMap<>();
|
||||
}
|
||||
namedRawSql.put(name, rawSql);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
package io.ebeaninternal.server.dto;
|
||||
|
||||
import io.ebean.RawSqlBuilder;
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
import io.ebeaninternal.server.type.TypeManager;
|
||||
|
||||
import io.ebeaninternal.xmlmapping.model.XmAliasMapping;
|
||||
import io.ebeaninternal.xmlmapping.model.XmColumnMapping;
|
||||
import io.ebeaninternal.xmlmapping.model.XmDto;
|
||||
import io.ebeaninternal.xmlmapping.model.XmEbean;
|
||||
import io.ebeaninternal.xmlmapping.model.XmNamedQuery;
|
||||
import io.ebeaninternal.xmlmapping.model.XmRawSql;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Manages all the DTO bean descriptors.
|
||||
*/
|
||||
public class DtoBeanManager {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DtoBeanManager.class);
|
||||
|
||||
private final TypeManager typeManager;
|
||||
|
||||
private final Map<Class, DtoBeanDescriptor> descriptorMap = new ConcurrentHashMap<>();
|
||||
@@ -43,4 +55,45 @@ public class DtoBeanManager {
|
||||
value.visit(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
public void readXmlMapping(ClassLoader classLoader, List<XmEbean> mappings) {
|
||||
for (XmEbean mapping : mappings) {
|
||||
List<XmDto> dtoList = mapping.getDto();
|
||||
for (XmDto dto : dtoList) {
|
||||
readDtoMapping(classLoader, dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readDtoMapping(ClassLoader classLoader, XmDto dto) {
|
||||
String dtoClassName = dto.getClazz();
|
||||
Class<?> dtoClass;
|
||||
try {
|
||||
dtoClass = Class.forName(dtoClassName, false, classLoader);
|
||||
} catch (Exception e) {
|
||||
logger.error("Could not load dto bean class " + dtoClassName + " for ebean xml entry");
|
||||
return;
|
||||
}
|
||||
|
||||
DtoBeanDescriptor<?> dtoBeanDescriptor = getDescriptor(dtoClass);
|
||||
if (dtoBeanDescriptor == null) {
|
||||
logger.error("No dto bean for ebean xml entry " + dtoClass);
|
||||
|
||||
} else {
|
||||
for (XmRawSql sql : dto.getRawSql()) {
|
||||
RawSqlBuilder builder = RawSqlBuilder.parse(sql.getQuery().getValue());
|
||||
for (XmColumnMapping columnMapping : sql.getColumnMapping()) {
|
||||
builder.columnMapping(columnMapping.getColumn(), columnMapping.getProperty());
|
||||
}
|
||||
for (XmAliasMapping aliasMapping : sql.getAliasMapping()) {
|
||||
builder.tableAliasMapping(aliasMapping.getAlias(), aliasMapping.getProperty());
|
||||
}
|
||||
dtoBeanDescriptor.addRawSql(sql.getName(), (SpiRawSql)builder.create());
|
||||
}
|
||||
|
||||
for (XmNamedQuery namedQuery : dto.getNamedQuery()) {
|
||||
dtoBeanDescriptor.addNamedQuery(namedQuery.getName(), namedQuery.getQuery().getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.ebeaninternal.server.dto;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Collection of named queries for a single Dto bean type.
|
||||
*/
|
||||
public class DtoNamedQueries {
|
||||
|
||||
private Map<String, String> namedRawSql = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Add the named query from deployment XML.
|
||||
*/
|
||||
public void addRawSql(String name, String query) {
|
||||
namedRawSql.put(name, query);
|
||||
}
|
||||
|
||||
Map<String, String> map() {
|
||||
return namedRawSql;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
package io.ebeaninternal.xmlmapping;
|
||||
|
||||
import io.ebeaninternal.xmlmapping.model.XmEbean;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import java.io.InputStream;
|
||||
import org.avaje.classpath.scanner.Resource;
|
||||
|
||||
public class XmlMappingReader {
|
||||
|
||||
@@ -24,4 +30,34 @@ public class XmlMappingReader {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<XmEbean> readByResourceName(ClassLoader classLoader, String resourceName){
|
||||
try {
|
||||
Enumeration<URL> resources = classLoader.getResources(resourceName);
|
||||
List<XmEbean> mappings = new ArrayList<>();
|
||||
while (resources.hasMoreElements()) {
|
||||
URL url = resources.nextElement();
|
||||
try (InputStream is = url.openStream()) {
|
||||
mappings.add(XmlMappingReader.read(is));
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading ebean xml mapping", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<XmEbean> readByResourceList(ClassLoader classLoader, List<Resource> resourceList){
|
||||
try {
|
||||
List<XmEbean> mappings = new ArrayList<>();
|
||||
for (Resource xmlMappingRes : resourceList) {
|
||||
try (InputStream is = new FileInputStream(xmlMappingRes.getLocationOnDisk())) {
|
||||
mappings.add(XmlMappingReader.read(is));
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading ebean xml mapping", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package io.ebeaninternal.xmlmapping.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
* <p>
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/ebean}named-query" maxOccurs="unbounded"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/ebean}raw-sql" maxOccurs="unbounded"/>
|
||||
* </sequence>
|
||||
* <attribute name="class" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"namedQuery",
|
||||
"rawSql"
|
||||
})
|
||||
@XmlRootElement(name = "dto")
|
||||
public class XmDto {
|
||||
|
||||
@XmlElement(name = "named-query", required = true)
|
||||
protected List<XmNamedQuery> namedQuery;
|
||||
@XmlElement(name = "raw-sql", required = true)
|
||||
protected List<XmRawSql> rawSql;
|
||||
@XmlAttribute(name = "class", required = true)
|
||||
protected String clazz;
|
||||
|
||||
/**
|
||||
* Gets the value of the namedQuery property.
|
||||
* <p>
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the namedQuery property.
|
||||
* <p>
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getNamedQuery().add(newItem);
|
||||
* </pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link XmNamedQuery }
|
||||
*/
|
||||
public List<XmNamedQuery> getNamedQuery() {
|
||||
if (namedQuery == null) {
|
||||
namedQuery = new ArrayList<>();
|
||||
}
|
||||
return this.namedQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the rawSql property.
|
||||
* <p>
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the rawSql property.
|
||||
* <p>
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getRawSql().add(newItem);
|
||||
* </pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link XmRawSql }
|
||||
*/
|
||||
public List<XmRawSql> getRawSql() {
|
||||
if (rawSql == null) {
|
||||
rawSql = new ArrayList<>();
|
||||
}
|
||||
return this.rawSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the clazz property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the clazz property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setClazz(String value) {
|
||||
this.clazz = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
package io.ebeaninternal.xmlmapping.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
@@ -28,14 +28,18 @@ import java.util.List;
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"entity"
|
||||
"entity",
|
||||
"dto"
|
||||
})
|
||||
@XmlRootElement(name = "ebean")
|
||||
public class XmEbean {
|
||||
|
||||
@XmlElement(required = true)
|
||||
@XmlElement(required = false)
|
||||
protected List<XmEntity> entity;
|
||||
|
||||
@XmlElement(required = false)
|
||||
protected List<XmDto> dto;
|
||||
|
||||
/**
|
||||
* Gets the value of the entity property.
|
||||
* <p>
|
||||
@@ -63,4 +67,11 @@ public class XmEbean {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
public List<XmDto> getDto() {
|
||||
if (dto == null) {
|
||||
dto = new ArrayList<>();
|
||||
}
|
||||
return this.dto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user