我们有一个以MySQL数据库和Spring为框架的项目.我是Spring的新手,希望实现数据库访问层,并发现有几个选项,比如
我已经浏览了stackoverflow中的各个帖子,并在网上进行了一些研究,但每个问题都有不同的答案支持不同的选项.此外,我确实看到提及现在不推荐使用Spring JDBC模板.
该应用程序每小时可能有大约1000个事务,大约有60%的读取和40%的写入.
任何人都可以帮我找到答案,哪3个选项适合哪个,为什么?或者,如果你能指出一些资源,那也将受到高度赞赏.
我正在尝试使用Spring Data Mongodb为我的mongodb文档实现版本控制系统.我以为我会利用Mongo生命周期事件
我想要做的是听取onBeforeSave并获取文档的原始版本,并获得两者之间的差异.
@Override
public void onBeforeSave(Table table, DBObject dbo) {
if (table.getId() != null) {
TableChange change = new TableChange();
Table beforeTable = mongoOperations.findById(table.getId(), Table.class);
if (!beforeTable.getName().equals(table.getName())) {
change.setName(table.getName());
}
MapDifference<String, Column> diff = Maps.difference(beforeTable.getColumns(), table.getColumns());
logger.debug(diff.entriesInCommon().toString());
logger.debug(diff.entriesDiffering().toString());
logger.debug(diff.entriesOnlyOnLeft().toString());
logger.debug(diff.entriesOnlyOnRight().toString());
table.addChange(change);
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我无法获得对mongoOperations的引用.它不断创建循环引用.是否我@Autowire:
Mongo配置:
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
<constructor-arg name="mongoConverter" ref="fooConverter" />
<property name="writeResultChecking" value="EXCEPTION" />
</bean>
<bean class="com.example.listener.document.TableListener"></bean>
Run Code Online (Sandbox Code Playgroud)
监听器:
public class TableListener extends AbstractMongoEventListener<Table> {
private static final Logger logger …Run Code Online (Sandbox Code Playgroud) 我正在使用带有mongodb的spring数据来存储二进制数据,例如图像等.我想维护一个版本字段以附加到url,以便从缓存图像中欺骗浏览器.
请参阅下面的文档基类:
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.index.Indexed;
public abstract class BaseDocument {
@Id
@Indexed(unique=true)
protected long id;
protected byte[] data;
protected String mimeType;
protected String filename;
protected String extension;
@Version
private Long version;
Run Code Online (Sandbox Code Playgroud)
我还有一个包装MongoOperations的存储库来保存我的文档.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class DocumentRepository implements IDocumentRepository {
@Autowired
private MongoOperations mongoTemplate;
@Override
public <D extends BaseDocument> void saveDocument(D document) {
mongoTemplate.save(document);
}
Run Code Online (Sandbox Code Playgroud)
为了实现版本控制,我做了一些狩猎,发现有一个@Version注释为spring mongo,但是已被弃用.然后我发现应该使用spring数据@Version注释.所以我继续使用弹簧数据@Version注释.
我期望发生的是每次保存文档时我的版本字段都会增加.我多次覆盖同一个文档,但我的版本字段并没有像我期望的那样增加.
我做错了什么或者我还需要做些什么吗?
示例:课程和教师有多对一的关系,如何通过Spring-data rest改变某个课程的教师?
GET http://localhost:7070/study-spring-data/course/2
Run Code Online (Sandbox Code Playgroud)
响应:
{
"name" : "CSCI-338 Hardcore Java",
"_links" : [ {
"rel" : "course.Course.teacher",
"href" : "http://localhost:7070/study-spring-data/course/2/teacher"
}, {
"rel" : "self",
"href" : "http://localhost:7070/study-spring-data/course/2"
} ]
}
GET http://localhost:7070/study-spring-data/course/2/teacher
Run Code Online (Sandbox Code Playgroud)
响应:
{
"_links" : [ {
"rel" : "course.Course.teacher",
"href" : "http://localhost:7070/study-spring-data/course/2/teacher/1"
} ]
}
Run Code Online (Sandbox Code Playgroud)
如上所示,课程2与教师1相关,如何将教师改为教师2?
我试过了:
成功更新课程名称:
PUT http://localhost:7070/study-spring-data/course/2
有效载荷
{
"name" : "CSCI-223 Hardcore C++",
}
Run Code Online (Sandbox Code Playgroud)
尝试更新参考对象教师时失败:
PUT http://localhost:7070/study-spring-data/course/2/teacher
Run Code Online (Sandbox Code Playgroud)
有效载荷
{
"_links" : [ {
"rel" : "course.Course.teacher",
"href" : "http://localhost:7070/study-spring-data/course/2/teacher/2" …Run Code Online (Sandbox Code Playgroud) 我想为我的存储库公开新的端点,这也扩展了RevisionRepository.
@RepositoryRestResource(collectionResourceRel = "persons", itemResourceRel = "person", path = "persons")
public interface PersonRepository extends PagingAndSortingRepository<PersonEntity, Long>, RevisionRepository<PersonEntity, Long, Integer> {
Revision<Integer, PersonEntity> findLastChangeRevision(@Param("id") Long id);
Revisions<Integer, PersonEntity> findRevisions(@Param("id") Long id);
Page<Revision<Integer, PersonEntity>> findRevisions(@Param("id") Long id, Pageable pageable);
PersonEntity findByName(@Param("name") String name);
}
Run Code Online (Sandbox Code Playgroud)
我现在的问题是,这些新方法不会作为网址(findLastChangeRevision,findRevisions)公开,只会findByName在搜索网址下.我目前对于实际的网址形式并不是特别关注,只要它有效.
我现在知道的唯一选择是
我对上面的选项有很多保留意见.我不知道该怎么办.
当调用entityManager.persist(...)-Method并且在spring数据jpa中调用entityManager.merge(...)时.根据文档: 如果实体尚未持久化,Spring Data JPA将通过调用entityManager.persist(...)-Method来保存实体,否则将调用entityManager.merge(...)-Method ...
那么Spring数据如何确定实体是否持久化?
在使用Spring Data JPA和Spring Data REST的应用程序中,假设您有一个这样的实体类:
@Entity
public class Person {
@Id @GeneratedValue
private int id;
private String name;
@JsonIgnore
private String superSecretValue;
...
}
Run Code Online (Sandbox Code Playgroud)
我们希望Spring Data REST公开所有这个实体的字段EXCEPT superSecretValue,因此我们用这个字段注释了该字段@JsonIgnore.
但是,在某些情况下,我们想要访问superSecretValue,因此我们创建一个投影,返回所有字段,包括:
@Projection(name = "withSecret", types = {Person.class})
public interface PersonWithSecret {
String getName();
String getSuperSecretValue();
}
Run Code Online (Sandbox Code Playgroud)
真棒.所以现在我们可以访问包括如下字段的Person实体:superSecretValue
curl http://localhost:8080/persons?projection=withSecret
Run Code Online (Sandbox Code Playgroud)
我的问题是我们如何确保这一预测?我们该如何配置的东西,任何人都可以检索Person实体,而不该superSecretValue领域......但只用了一定的作用(比如人ROLE_ADMIN)可以使用投影来检索隐藏字段?
我发现使用的例子不胜枚举@PreAuthorize或@Secured注释,以确保春季数据JPA库CRUD方法(例如save(),delete())...但不知道如何限制一个Spring数据REST投影的应用实例.
我正在尝试使用审计来保存dateCreated并保存dateUpdated在我的对象中,但是由于我ID手动设置,还有一些额外的工作.
遵循Oliver Gierke在DATAMONGO-946中提出的建议, 我试图找出如何正确实现它.
作为上面Jira任务的原始海报,我从这里下载了示例https://github.com/spring-guides/gs-accessing-data-mongodb.git并对其进行了一些修改:
package hello;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.domain.Persistable;
import java.util.Date;
public class Customer implements Persistable<String> {
@Id
private String id;
@CreatedDate
private Date createdDate;
@LastModifiedDate
private Date lastModifiedDate;
private String firstName;
private String lastName;
private boolean persisted;
public Customer() {
}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void setPersisted(boolean persisted) {
this.persisted = persisted; …Run Code Online (Sandbox Code Playgroud) 我认为JPA是一个直接的关系.看起来像这样.CompanyGroup:
@Entity
@Table
public class CompanyGroup implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(name = "name")
private String name;
@JoinColumn(name = "companies")
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Company> companies;
}
Run Code Online (Sandbox Code Playgroud)
公司:
@Entity
@Table
public class Company implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name = "name")
private String name;
@JoinColumn(name = "users")
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<User> users;
@Id
@GeneratedValue
private Long id;
} …Run Code Online (Sandbox Code Playgroud) 我使用Spring Data并决定创建可以在Hibernate实体中使用的新自定义数据类型.我检查了文档,BasicType并根据此官方用户指南选择并实施它.
我希望能够在其类名下注册该类型,并且能够在实体中使用新类型而无需@Type注释.不幸的是,我无法引用MetadataBuilder或Hibernate配置来注册新类型.有没有办法在Spring Data中获取它?似乎Hibernate的初始化对用户是隐藏的,并且不能轻易访问.我们使用以下类来初始化JPA:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager",
basePackages = {
"..." // omitted
}
)
public class JpaConfiguration implements TransactionManagementConfigurer {
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean configureEntityManagerFactory(
DataSource dataSource,
SchemaPerTenantConnectionProviderImpl provider) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setPersistenceUnitName("defaultPersistenceUnit");
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setPackagesToScan(
"..." // omitted
);
entityManagerFactoryBean.setJpaProperties(properties(provider));
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return entityManagerFactoryBean;
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new JpaTransactionManager();
}
private Properties properties(SchemaPerTenantConnectionProviderImpl …Run Code Online (Sandbox Code Playgroud) spring-data ×10
java ×7
spring ×7
hibernate ×2
mongodb ×2
rest ×2
jpa ×1
postgresql ×1
spring-orm ×1
versioning ×1