14 changed files with 222 additions and 182 deletions
@ -1,51 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.relation; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.data.jpa.repository.Modifying; |
|||
import org.thingsboard.server.dao.model.sql.RelationEntity; |
|||
|
|||
import javax.persistence.EntityManager; |
|||
import javax.persistence.PersistenceContext; |
|||
import javax.persistence.Query; |
|||
|
|||
@Slf4j |
|||
public abstract class AbstractRelationInsertRepository implements RelationInsertRepository { |
|||
|
|||
@PersistenceContext |
|||
protected EntityManager entityManager; |
|||
|
|||
protected Query getQuery(RelationEntity entity, String query) { |
|||
Query nativeQuery = entityManager.createNativeQuery(query, RelationEntity.class); |
|||
if (entity.getAdditionalInfo() == null) { |
|||
nativeQuery.setParameter("additionalInfo", null); |
|||
} else { |
|||
nativeQuery.setParameter("additionalInfo", entity.getAdditionalInfo().toString()); |
|||
} |
|||
return nativeQuery |
|||
.setParameter("fromId", entity.getFromId()) |
|||
.setParameter("fromType", entity.getFromType()) |
|||
.setParameter("toId", entity.getToId()) |
|||
.setParameter("toType", entity.getToType()) |
|||
.setParameter("relationTypeGroup", entity.getRelationTypeGroup()) |
|||
.setParameter("relationType", entity.getRelationType()); |
|||
} |
|||
|
|||
@Modifying |
|||
protected abstract RelationEntity processSaveOrUpdate(RelationEntity entity); |
|||
|
|||
} |
|||
@ -1,63 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.relation; |
|||
|
|||
import org.springframework.stereotype.Repository; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.thingsboard.server.dao.model.sql.RelationCompositeKey; |
|||
import org.thingsboard.server.dao.model.sql.RelationEntity; |
|||
import org.thingsboard.server.dao.util.HsqlDao; |
|||
|
|||
import javax.persistence.Query; |
|||
|
|||
@HsqlDao |
|||
@Repository |
|||
@Transactional |
|||
public class HsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository { |
|||
|
|||
private static final String INSERT_ON_CONFLICT_DO_UPDATE = "MERGE INTO relation USING (VALUES :fromId, :fromType, :toId, :toType, :relationTypeGroup, :relationType, :additionalInfo) R " + |
|||
"(from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info) " + |
|||
"ON (relation.from_id = UUID(R.from_id) AND relation.from_type = R.from_type AND relation.relation_type_group = R.relation_type_group AND relation.relation_type = R.relation_type AND relation.to_id = UUID(R.to_id) AND relation.to_type = R.to_type) " + |
|||
"WHEN MATCHED THEN UPDATE SET relation.additional_info = R.additional_info " + |
|||
"WHEN NOT MATCHED THEN INSERT (from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info) VALUES (UUID(R.from_id), R.from_type, UUID(R.to_id), R.to_type, R.relation_type_group, R.relation_type, R.additional_info)"; |
|||
|
|||
protected Query getQuery(RelationEntity entity, String query) { |
|||
Query nativeQuery = entityManager.createNativeQuery(query, RelationEntity.class); |
|||
if (entity.getAdditionalInfo() == null) { |
|||
nativeQuery.setParameter("additionalInfo", null); |
|||
} else { |
|||
nativeQuery.setParameter("additionalInfo", entity.getAdditionalInfo().toString()); |
|||
} |
|||
return nativeQuery |
|||
.setParameter("fromId", entity.getFromId().toString()) |
|||
.setParameter("fromType", entity.getFromType()) |
|||
.setParameter("toId", entity.getToId().toString()) |
|||
.setParameter("toType", entity.getToType()) |
|||
.setParameter("relationTypeGroup", entity.getRelationTypeGroup()) |
|||
.setParameter("relationType", entity.getRelationType()); |
|||
} |
|||
|
|||
@Override |
|||
public RelationEntity saveOrUpdate(RelationEntity entity) { |
|||
return processSaveOrUpdate(entity); |
|||
} |
|||
|
|||
@Override |
|||
protected RelationEntity processSaveOrUpdate(RelationEntity entity) { |
|||
getQuery(entity, INSERT_ON_CONFLICT_DO_UPDATE).executeUpdate(); |
|||
return entityManager.find(RelationEntity.class, new RelationCompositeKey(entity.toData())); |
|||
} |
|||
} |
|||
@ -1,41 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.relation; |
|||
|
|||
import org.springframework.stereotype.Repository; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.thingsboard.server.dao.model.sql.RelationEntity; |
|||
import org.thingsboard.server.dao.util.PsqlDao; |
|||
|
|||
@PsqlDao |
|||
@Repository |
|||
@Transactional |
|||
public class PsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository { |
|||
|
|||
private static final String INSERT_ON_CONFLICT_DO_UPDATE = "INSERT INTO relation (from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info)" + |
|||
" VALUES (:fromId, :fromType, :toId, :toType, :relationTypeGroup, :relationType, :additionalInfo) " + |
|||
"ON CONFLICT (from_id, from_type, relation_type_group, relation_type, to_id, to_type) DO UPDATE SET additional_info = :additionalInfo returning *"; |
|||
|
|||
@Override |
|||
public RelationEntity saveOrUpdate(RelationEntity entity) { |
|||
return processSaveOrUpdate(entity); |
|||
} |
|||
|
|||
@Override |
|||
protected RelationEntity processSaveOrUpdate(RelationEntity entity) { |
|||
return (RelationEntity) getQuery(entity, INSERT_ON_CONFLICT_DO_UPDATE).getSingleResult(); |
|||
} |
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.relation; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.jdbc.core.BatchPreparedStatementSetter; |
|||
import org.springframework.jdbc.core.JdbcTemplate; |
|||
import org.springframework.stereotype.Repository; |
|||
import org.springframework.transaction.TransactionStatus; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.transaction.support.TransactionCallbackWithoutResult; |
|||
import org.springframework.transaction.support.TransactionTemplate; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.dao.model.sql.RelationEntity; |
|||
import org.thingsboard.server.dao.util.PsqlDao; |
|||
|
|||
import javax.persistence.EntityManager; |
|||
import javax.persistence.PersistenceContext; |
|||
import javax.persistence.Query; |
|||
import java.sql.PreparedStatement; |
|||
import java.sql.SQLException; |
|||
import java.sql.Types; |
|||
import java.util.List; |
|||
|
|||
@PsqlDao |
|||
@Repository |
|||
@Transactional |
|||
public class SqlRelationInsertRepository implements RelationInsertRepository { |
|||
|
|||
private static final String INSERT_ON_CONFLICT_DO_UPDATE_JPA = "INSERT INTO relation (from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info)" + |
|||
" VALUES (:fromId, :fromType, :toId, :toType, :relationTypeGroup, :relationType, :additionalInfo) " + |
|||
"ON CONFLICT (from_id, from_type, relation_type_group, relation_type, to_id, to_type) DO UPDATE SET additional_info = :additionalInfo returning *"; |
|||
|
|||
private static final String INSERT_ON_CONFLICT_DO_UPDATE_JDBC = "INSERT INTO relation (from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info)" + |
|||
" VALUES (?, ?, ?, ?, ?, ?, ?) " + |
|||
"ON CONFLICT (from_id, from_type, relation_type_group, relation_type, to_id, to_type) DO UPDATE SET additional_info = ?"; |
|||
|
|||
|
|||
@PersistenceContext |
|||
protected EntityManager entityManager; |
|||
|
|||
@Autowired |
|||
protected JdbcTemplate jdbcTemplate; |
|||
|
|||
@Autowired |
|||
private TransactionTemplate transactionTemplate; |
|||
|
|||
protected Query getQuery(RelationEntity entity, String query) { |
|||
Query nativeQuery = entityManager.createNativeQuery(query, RelationEntity.class); |
|||
if (entity.getAdditionalInfo() == null) { |
|||
nativeQuery.setParameter("additionalInfo", null); |
|||
} else { |
|||
nativeQuery.setParameter("additionalInfo", JacksonUtil.toString(entity.getAdditionalInfo())); |
|||
} |
|||
return nativeQuery |
|||
.setParameter("fromId", entity.getFromId()) |
|||
.setParameter("fromType", entity.getFromType()) |
|||
.setParameter("toId", entity.getToId()) |
|||
.setParameter("toType", entity.getToType()) |
|||
.setParameter("relationTypeGroup", entity.getRelationTypeGroup()) |
|||
.setParameter("relationType", entity.getRelationType()); |
|||
} |
|||
|
|||
@Override |
|||
public RelationEntity saveOrUpdate(RelationEntity entity) { |
|||
return (RelationEntity) getQuery(entity, INSERT_ON_CONFLICT_DO_UPDATE_JPA).getSingleResult(); |
|||
} |
|||
|
|||
@Override |
|||
public void saveOrUpdate(List<RelationEntity> entities) { |
|||
transactionTemplate.execute(new TransactionCallbackWithoutResult() { |
|||
@Override |
|||
protected void doInTransactionWithoutResult(TransactionStatus status) { |
|||
jdbcTemplate.batchUpdate(INSERT_ON_CONFLICT_DO_UPDATE_JDBC, new BatchPreparedStatementSetter() { |
|||
@Override |
|||
public void setValues(PreparedStatement ps, int i) throws SQLException { |
|||
RelationEntity relation = entities.get(i); |
|||
ps.setObject(1, relation.getFromId()); |
|||
ps.setString(2, relation.getFromType()); |
|||
ps.setObject(3, relation.getToId()); |
|||
ps.setString(4, relation.getToType()); |
|||
|
|||
ps.setString(5, relation.getRelationTypeGroup()); |
|||
ps.setString(6, relation.getRelationType()); |
|||
|
|||
if (relation.getAdditionalInfo() == null) { |
|||
ps.setString(7, null); |
|||
ps.setString(8, null); |
|||
} else { |
|||
String json = JacksonUtil.toString(relation.getAdditionalInfo()); |
|||
ps.setString(7, json); |
|||
ps.setString(8, json); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public int getBatchSize() { |
|||
return entities.size(); |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue