在我们项目中经常会遇到数据结构不定的情况,这时普通的关系型数据库不能满足我们的要求。Postgres为我们提供了jsonb
数据类型,我们可在此类型的字段存储json
数据,并可对此数据进行查询。本例将结合hibernate
,Spring Data JPA
,Spring Boot
来实现。
1. 自定义方言
public class JsonbPostgresDialect extends PostgreSQL94Dialect {
public JsonbPostgresDialect() {
this.registerColumnType(Types.JAVA_OBJECT,"jsonb");
}
}
指定方言
spring.jpa.database-platform: com.example.jpajsonb.support.JsonbPostgresDialect
2. 自定义jsonb数据类型
这里主要实现了Map
映射PGObject
(postgres对象类型),通过ObjectMapper
来实现两个数据类型的转换。
public class JsonbType implements UserType{
private final ObjectMapper mapper = new ObjectMapper();;
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.OTHER);
} else {
try{
st.setObject(index, mapper.writeValueAsString(value), Types.OTHER);
}catch (IOException e){
e.printStackTrace();
}
}
}
@Override
public Object deepCopy(Object originalValue) throws HibernateException {
if (originalValue != null) {
try {
return mapper.readValue(mapper.writeValueAsString(originalValue),
returnedClass());
} catch (IOException e) {
throw new HibernateException("Failed to deep copy object", e);
}
}
return null;
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
PGobject o = (PGobject) rs.getObject(names[0]);
if (o.getValue() != null) {
try {
return mapper.readValue(o.getValue(),Map.class);
}catch (IOException e){
e.printStackTrace();
}
}
return new HashMap<String, Object>();
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
Object copy = deepCopy(value);
if (copy instanceof Serializable) {
return (Serializable) copy;
}
throw new SerializationException(String.format("Cannot serialize '%s', %s is not Serializable.", value, value.getClass()), null);
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return deepCopy(cached);
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return deepCopy(original);
}
@Override
public boolean isMutable() {
return true;
}
@Override
public int hashCode(Object x) throws HibernateException {
if (x == null) {
return 0;
}
return x.hashCode();
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return ObjectUtils.nullSafeEquals(x, y);
}
@Override
public Class<?> returnedClass() {
return Map.class;
}
@Override
public int[] sqlTypes() {
return new int[]{Types.JAVA_OBJECT};
}
}
3. 声明使用
先定义数据类型,再在字段上使用
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@TypeDef(name = "JsonbType", typeClass = JsonbType.class)
public class Person {
@Id
@GeneratedValue
private Long id;
@Column(columnDefinition = "jsonb")
@Type(type = "JsonbType")
private Map<String,Object> info;
}
4.Repository
通过postgres
原生sql语句查询,本例含义为json
数据info
的一个key
为name
的值等于。具体的JSON的sql查询方式请参考:
https://www.postgresql.org/docs/9.5/static/functions-json.html
public interface PersonRepository extends JpaRepository<Person,Long> {
@Query(value = "select * from person where info ->> 'name' = :name" , nativeQuery = true)
List<Person> findByName(@Param("name") String name);
}
5. 保存和读取测试
@Bean
CommandLineRunner saveAndReadJsonb(PersonRepository personRepository){
return e -> {
Person p = new Person();
Map m = new HashMap();
m.put("name","汪云飞");
m.put("age",11);
p.setInfo(m);
Person returnPerson = personRepository.save(p);
Map returnMap = returnPerson.getInfo();
for(Object entry :returnMap.entrySet()){
log.info(entry.toString());
}
};
}
6. 查询测试
@Bean
CommandLineRunner queryJsonb(PersonRepository personRepository){
return e -> {
List<Person> people = personRepository.findByName("吴亦凡");
for (Person person : people){
Map info = person.getInfo();
log.info(person.getId() + "/" + info.get("name") + "/" +info.get("age"));
}
};
}
7. 源码地址
http://www.wisely.top/2017/06/27/spring-data-jpa-postgresql-jsonb/
相关推荐
Spring Data JPA 是 Spring 框架的一个模块,它为使用 JPA(Java Persistence API)提供了强大的支持,简化了数据访问层的开发。通过使用 Spring Data JPA,我们可以避免编写大量重复的 CRUD(创建、读取、更新、...
Spring Data JPA 还支持 MyBatis 等其他数据访问技术,允许开发者使用 MyBatis 来访问数据库。 在本讲义中,我们将详细介绍 Spring Data JPA 的基本概念、配置、使用、优点和缺点等方面的知识点。 Spring Data ...
Spring Data JPA是Spring框架的一个重要模块,它简化了与Java Persistence API (JPA)的交互,使得数据库操作变得更加便捷。在这个"Spring Data JPA入门项目01"中,我们将探讨如何利用Spring Data JPA来实现基本的...
它支持多种数据库,包括MySQL、PostgreSQL、Oracle等,并且与Spring Framework无缝集成,使得事务管理、数据源配置等变得简单。 2. **Repository抽象** Spring Data JPA的核心在于Repository接口,开发者可以...
Spring Data JPA是Spring框架的一部分,用于简化Java应用程序与数据库之间的交互。它提供了一种简单的方式来执行CRUD操作(创建、读取、更新和删除),而无需编写大量的模板代码或处理复杂的对象关系映射(ORM)细节...
而"SpringDataJpa"是Spring框架的一部分,它提供了与Java Persistence API (JPA) 的集成,便于我们操作数据库。描述中还提到,这个项目是在IntelliJ IDEA(IDEA)环境下开发的,且可以直接运行,意味着它包含了所有...
在本项目中,"springmvc-jpa-springdata" 是一个基于Java的Web应用程序,它利用了Spring MVC、JPA(Java Persistence API)以及Hibernate作为JPA的具体实现,与PostgreSQL数据库进行数据交互。这个项目的核心是构建...
【集成Spring Data JPA、Hibernate Spatial与PostGIS】 整合这三个技术,可以在Spring应用中构建高效的空间数据处理系统。首先,通过Spring Data JPA配置,连接到使用PostGIS扩展的PostgreSQL数据库。然后,定义...
【描述】:仓库管理系统采用Spring Boot作为基础框架,Spring Data JPA作为数据访问层技术,用于简化与数据库的交互。这样的设计使得开发者可以专注于业务逻辑,而无需过多关注底层数据库的细节。系统可能还包括其他...
【标题】"管理系统系列--仓库管理系统,SpringBoot+Spring Data JPA+......zip" 提供了一个关于构建仓库管理系统的项目框架,它利用了Spring Boot和Spring Data JPA等技术。这个系统旨在自动化仓库操作,提高库存...
本示例将详细介绍如何在Spring Boot项目中实现这样的配置,以支持不同类型的数据库。 首先,我们要理解Spring Boot的自动配置特性。Spring Boot通过`@EnableAutoConfiguration`注解,可以自动配置大量的依赖项,...
2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; ...
这个入门实例将向我们展示如何使用Spring Boot与JPA(Java Persistence API)、PostgreSQL数据库以及AOP(面向切面编程)来实现数据验证。 首先,让我们详细了解一下Spring Boot。Spring Boot的核心理念是“约定...
【标题】"bookcity"是一个基于Java 8技术栈,结合Spring Boot、Spring Data JPA以及PostgreSQL数据库的在线书店应用。这个项目旨在提供一个基本的电子商务平台,用户可以浏览书籍,进行购买操作。 【核心知识点】: ...
在Spring应用中集成PostgreSQL,首先需要在项目中添加Spring Data JPA和PostgreSQL的依赖。然后配置`application.properties`或`application.yml`文件,指定数据源连接信息,如URL、用户名和密码。接下来,定义实体...
本文将深入探讨如何将QueryDSL与Spring Data JPA以及Hibernate在PostgreSQL数据库环境下进行集成,以提升应用的查询能力。 首先,让我们理解QueryDSL的基本概念。QueryDSL是一个通用的查询框架,支持SQL、JDO、JPA...
Spring Boot默认集成了许多库,包括Spring Data JPA和一个默认的数据库连接器(如H2、MySQL、PostgreSQL等)。你需要根据实际使用的数据库选择对应的依赖。例如,如果你使用的是MySQL,需要添加如下依赖: ```xml ...
Spring JPA,全称为Spring Data JPA,是Spring框架的一部分,专门用于简化Java持久层的开发。它提供了一个抽象层,让开发者可以使用简洁、声明式的编程方式来操作数据库,而无需关注底层的JDBC或者ORM(对象关系映射...
5. **Integration with Spring Transaction Management**:Spring Data JPA无缝集成Spring的事务管理,使得事务控制更加方便,无需手动开启和关闭事务。 6. **Auditing**:Spring Data JPA可以通过`@CreatedBy`, `@...