美文网首页
SpringBoot对非关系型数据库NoSql的支持

SpringBoot对非关系型数据库NoSql的支持

作者: 赵镇 | 来源:发表于2017-09-05 23:00 被阅读159次

    NoSql是对于所有不使用关系作为数据管理的数据库系统的总称,NoSql的特点主要是不使用sql作为查询语言。数据存储也不是固定的表和字段
    NoSql数据库主要有文档存储型(MongoDB),图形关系存储型(Neo4j),键值对存储型(Redis)

    Spring对MongoDB的支持

    Spring对MongoDB的支持主要是通过Spring Data MongoDB来实现的。

    Spring Data MongoDB提供的注解支持

    • @Document 映射领域对象与MongoDB的一个文档
    • @Id 映射当前属性是ID
    • @DbRef 当前属性将参考其他文档
    • @Field 为文档的属性定义名称
    • @Version 将当前属性作为版本

    数据操作MongoTemplete的支持

    MongoTemplete为我们提供了数据放我那和操作的方法,我们还需要为MongoClient和MongoDbFactory来配置数据库连接属性。

        @Bean
        public MongoClient client() throws UnKnownHostException{
        MongoClient client = new MongoClient(new ServerAddress("127.0.0.1",27017))
        }
        @Bean
        public MongoDbFactory mongoDbFactory() throws Exception{
        String database = new MongoClientURI("mongodb://localhost/test").getDatabase();
        return new SimpleMongoDbFactory(client(),database);
        }
        @Bean
        public MongoTemplete mongoTemplete(MongoDbFactory mongoDbFactory)throws UnKnownHostException{
            return new MongoTemplete(mongoDbFactory);
        }
    

    @Repository的支持

    Spring提供了类似JpaRepository的支持MongoRepository的支持
    在自定义的Repository接口中继承即可

    public interface PersonRepository extends MongoRepository<Person,String>{
    }
    

    如何开启MongoRepository,则需要在配置类或是Spring的入口类中加入注解@EnableMongoRepository

    SpringBoot对MongoDB的支持

    springBoot为我们提供了一些默认属性例如默认端口27017,默认服务器为localhost。默认数据库为test等
    我们开始使用之前除了上述知识需要掌握以外只需引入spring-boot-starter-data-mongodb依赖外,无需任何其他配置。

    SpringBoot+MongoDB实战

    首先依然是准备代码

    代码准备

    pom文件引入

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-mongodb</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    

    在这里要注意的是,我们这里只是测试MongoDB单数据源的情况,如果要进行多数据源测试,那么需要进行额外的配置,如果这里引入了mysql的依赖。那么程序会报错

    Cannot determine embedded database driver class for database type NONE
    

    接下来是实体的准备
    Person类

    @Document
    public class Person {
        @Id
        private  String id;
        private  String name;
        private  Integer age;
        @Field("locs")
        private Collection<Location> locations = new LinkedHashSet<>();
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public Collection<Location> getLocations() {
            return locations;
        }
    
        public void setLocations(Collection<Location> locations) {
            this.locations = locations;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public void setAge(Integer age) {
            this.age = age;
    
        }
    
        public Person(String name, Integer age) {
            super();
            this.name = name;
            this.age = age;
        }
    }
    
    

    Location类

    public class Location {
        private  String place;
    
        private  String year;
    
        public String getPlace() {
            return place;
        }
    
        public void setPlace(String place) {
            this.place = place;
        }
    
        public String getYear() {
            return year;
        }
    
        public void setYear(String year) {
            this.year = year;
        }
    
        public Location(String place, String year) {
            super();
            this.place = place;
            this.year = year;
        }
    }
    
    

    @Document注解映射领域模型和MongoDB的文档
    @Id注解表明这个属性为文档的Id
    @Field注解此属性在文档中的名称为locs,locations属性将以数组形式存在当前数据记录中

    Repository

        Person findByName(String name);
    
        @Query("{'age':?0}")
        List<Person> withQueryFindByAge(Integer age);
    

    从上述方法可见,MongoRepository仍然支持类似于JPA的方法名和Query查询

    Controller层

    @RestController
    public class DataController {
        @Autowired
        PersonRepository personRepository;
    
        @RequestMapping("/save")
        public  Person save(){
            Person p = new Person("zhaozhen",23);
            Collection<Location> locations = new LinkedHashSet<>();
            Location loc1 =new Location("上海","2012");
            Location loc2 =new Location("合肥","2013");
            Location loc3 =new Location("武汉","2014");
            Location loc4 =new Location("北京","2015");
            locations.add(loc1);
            locations.add(loc2);
            locations.add(loc3);
            locations.add(loc4);
            p.setLocations(locations);
            return  personRepository.save(p);
        }
    
        @RequestMapping("/q1")
        public  Person q1(String name){
            return  personRepository.findByName(name);
        }
    
        @RequestMapping("q2")
        public List<Person> q2 (Integer age){
            return  personRepository.withQueryFindByAge(age);
        }
    }
    

    访问http://localhost:8080/save 可以看到

    这里写图片描述
    数据已经被保存到MongoDB中(可视化工具为RoboMongo),Mongo的安装请参照:MongoDB学习(三)MongoDB 3.2.8的使用详解
    测试两个查询方法的结果如下图
    查询年龄

    查询姓名


    查询姓名

    源码地址

    Spring对Redis的支持

    Redis是一个基于键值对的开源内存数据存储,当然Redis也可以作为数据缓存。Spring 对Redis的支持是通过Spring Data Redis来实现的,SpringData JPA为我们提供了连接相关的connectionFactory和数据操作相关的RedisTemplete。根据Redis的不同的java客户端有如下

    connectionFactory划分

    • JedisConnectionFactory ,使用Jedis作为Redis客户端
    • JredisConnectionFactory,使用Jredis作为Redis客户端
    • LettuceConnectionFactory,使用Lettuce作为Redis客户端
    • SrpConnectionFactory,使用Squllara/redis-protocol作为Redis客户端

    数据操作相关的RedisTemplete主要分为RedisTemplete和StringRedisTemplete两个模板进行数据操作。前者主要处理对象的数据操作,后者主要处理String类型的数据操作。两种数据操作模板主要有以下方法

    操作方法

    • opsForValue 操作只有简单属性的数据
    • opsForList 操作含有List的数据
    • opsForSet 操作含有Set的数据
    • opsForZSet操作含有ZSet(有序的set)的数据
    • opsForHash 操作含有hash的数据

    Redis的序列化Serializer

    当我们的数据存储到Redis的时候,我们的键值对是通过Serializer序列化到数据库的RedisTemplete默认使用的是JdkSerializationRedisSerializer,StringRedisTemplete默认使用的是StringRedisSerializer,除此之外Spring Data JPA还为我们提供如下Serializer:GenericToStringSerializer,Jackson2JsonRedisSerializer,JacksonJsonRedisSerializer,OxmSerializer.

    SpringBoot对Redis的支持

    SpringBoot的自动配置为我们自动默认配置了JedisConnectionfactory、RedisTemplete,StringRedisTemplete,让我们可以直接使用Redis作为数据存储。我们也可以在properties文件中以spring.redis开头作为前缀配置Redis的属性。

    SpringBoot对Redis的实践

    前期准备

    首先需要在本机安装Redis 。教程传送门:在windows上搭建Redis环境
    然后下载一个Redis管理的可视化工具。例如Redis client或者Redis Desktop Manager

    代码准备

    实体类

    public class Person implements Serializable {
        private  String id;
        private String name;
        private Integer age;
    
        public  Person(){
            super();
        }
        public Person(String id, Integer age, String name) {
            super();
            this.id = id;
            this.age = age;
            this.name = name;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    

    Dao层

    @Repository
    public class PersonDao {
        @Autowired
        StringRedisTemplate stringRedisTemplate;
    
        @Resource(name = "stringRedisTemplate")
        ValueOperations<String,String> valueOpsStr;
    
        @Autowired
        RedisTemplate<Object,Object> redisTemplate;
        @Resource(name = "redisTemplate")
        ValueOperations<Object,Object> valueOps;
        //存储字符串类型
        public void stringRedisTempleteDemo(){
            valueOpsStr.set("xx","yy");
        }
        //存储对象类型
        public  void  save(Person person){
            valueOps.set(person.getId(),person);
        }
        //获得字符串
        public  String getString(){
            return  valueOpsStr.get("xx");
        }
        //获取对象类型
        public Person getPerson(){
            return (Person) valueOps.get("1");
        }
    }
    

    SpringBoot为我们配置了RedisTemplete。而RedisTemplete使用的是JdkSerializationRedisSerializer(用二进制存储数据)。这个对后续可视化工具的演示不太直接。
    我们在此自己配置RedisTemplete并定义Serializer。

    入口类

    @SpringBootApplication
    public class SpringBootRedisApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBootRedisApplication.class, args);
        }
        @Bean
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
                throws UnknownHostException {
            RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
            template.setConnectionFactory(redisConnectionFactory);
    
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
    
            template.setValueSerializer(jackson2JsonRedisSerializer); //1
            template.setKeySerializer(new StringRedisSerializer()); //2
    
            template.afterPropertiesSet();
            return template;
        }
    
    }
    
    

    控制器

    @RestController
    public class DataController {
    
        @Autowired
        PersonDao personDao;
    
        @RequestMapping("/test")
        public void set(){
            Person p = new Person("1",23,"zhaozhen");
            personDao.save(p);
            personDao.stringRedisTempleteDemo();
        }
    
        @RequestMapping("/getStr")
        public String getStr(){
            return personDao.getString();
    
        }
        @RequestMapping("/getPerson")
        public Person getPerson(){
            return  personDao.getPerson();
        }
    
    }
    
    

    运行之后我们可以看到。访问http://localhost:8080/test 会发现数据可视化中出现了如下数据

    这里写图片描述

    获取字符数据http://localhost:8080/getStr

    这里写图片描述

    获取实体数据http://localhost:8080/getPerson

    这里写图片描述
    代码

    总结

    本篇博客主要讲解了SpringBoot与两种Nosql数据库的结合,比较简单。后续会继续深入的探讨SpringBoot的知识。希望与大家多交流。

    相关文章

      网友评论

          本文标题:SpringBoot对非关系型数据库NoSql的支持

          本文链接:https://www.haomeiwen.com/subject/vfopjxtx.html