Springboot对数据访问部分提供了非常强大的集成,支持mysql,oracle等传统数据库的同时,也支持Redis,MongoDB等非关系型数据库,极大的简化了DAO的代码,尤其是Spring Data JPA,为不同数据库提供了统一的接口,我们只需继承其默认的JpaRepository(仓库模式),就自动的拥有很多常见的数据访问方法。

本文Demo:https://github.com/wanliwang/cayman/tree/master/cm-bootweb,每一种类型数据访问对应其Controller名称。

系列文章

快速入门系列--SpringBoot--01基础

快速入门系列--SpringBoot--02数据访问

快速入门系列--SpringBoot--03系统集成

SpringData是解决数据访问问题的一揽子解决方案,包含对JPA, MongoDB, Redis, Hadoop, Data Rest, Elasticsearch等一系列组件的支持,其通过Spring Data Commons提供统一的API。

3个常见数据访问组件的比较:

Hibernate 对数据库提供了较为完整的封装,封装了基本的DAO层操作,有较好的数据库移植性(其实就是对JPA的一种实现)

Mybatis 可以进行更细致的SQL优化,查询必要的字段,但是需要维护SQL和查询结果集的映射,而且数据库的移植性较差,针对不同的数据库编写不同的SQL。(有空试试mybatis接入公司框架)

Spring Data JPA 极大的简化了数据库访问,可以通过命名规范、注解的方式较快的编写SQL。

Spring Data JPA简单介绍,public interface PersonRepository extends JpaRepository<Person, Long> {},只要继承JpaRepository接口,就默认包含了常见的增删改查方法。(需要时再查阅,个人不是很推荐在关系型数据库中使用jpa,但NOSQL还是很推荐的)

声明式事务:给Config类添加@EnableTransactionManagement即可,而springboot无需任何配置,只需在需要事务处理的方法上添加@Transactional注解即可(spring包下)。

访问方式1,jdbc:Spring boot可以通过jdbcTemplate对数据库进行访问,不过功能相对简单,需要自己进行增强,相关配置如下。

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/user?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

Tip:

Docker启动时:docker run -d -p 3306:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=123456 mysql

访问方式2,jpa:Spring Data对java的JPA标准提供了实现(Hibernate也是对该标准的一种实现),Spring boot对此进行了集成,相比访问方式1,需要增加如下配置。

 spring.jpa.generate-ddl=false
spring.jpa.show-sql=true
spring.jpa.hibernate.naming.strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

在Eclipse中,支持JPA实体对象的代码生成,需要在项目Facet上添加jpa,之后使用jpatool生成代码。如果报错,可以直接修改配置文件(项目文件夹下的/.settings /org.eclipse.wst.common.project.facet.core.xml),添加配置项 <installed facet="jpt.jpa" version="2.1"/>即可,之后直接在项目上右键点选JPA Tools生成指定实体即可。

简单查询:按照标准的格式即可,比如通过UserName查询,User findByUserNameIgnoreCase(String userName),其会自动生成对应SQL。

分页查询:其已提供了分页功能,Page<User> findALL(Pageable pageable),Pageable pageable = new PageRequest(1, 10, new Sort(Direction.DESC, "id"))

限制查询:Order findTopByCreateTime(); List<User> findFirst5ByFirstname(String firstname, Sort sort);

自定义查询:在SQL的查询方法上面使用@Query注解,这样可以实现多表查询;删除和修改加上@Modifying;添加@Transactional支持事务,可以设置查询超时等配置项。

Tip:

生成的model有一些问题,比如@Id从Long变成了String, Bit->Byte(需要boolean), Long->BigInteger,因此不太推荐正向工程的形式(由代码生成数据库,容易丢失约束,所以配置项spring.jpa.generate-ddl=false)。同时,自动生成表中的字段会将camel命名的字段转化为xx_xx,因此需要添加上@Column注解

    @Column(name = "phonenumber")
private String phoneNumber;

此外命名时不要使用isXXX形式,在各类序列化时很容易出问题,推荐使用ifActive。

Jpa更加信息的内容请参考: https://projects.spring.io/spring-data-jpa/

访问方式3,Mybatis:在springboot集成下,只需添加maven配置即可,无需任何额外项目配置,而且实体类直接使用pojo类即可,非常非常的方便。

 Maven:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency> 简单示例
@Select("select * from user where username = #{username}")
User findUserByName(@Param("username") String name); @Select("select * from user")
List<User> findAll(); @Insert("insert into user (userID,createTime,createUser,dataChange_LastTime,email,ifActive,nickName,passwordHash,"
+ "phoneNumber, salt, updateUser, userName) values("
+ "#{userID}, #{createTime}, #{createUser}, #{dataChange_LastTime}, #{email}, #{ifActive}, #{nickName}, #{passwordHash}"
+ ", #{phoneNumber},#{salt},#{updateUser},#{userName})")
@SelectKey(statement = "call identity()", keyProperty = "userID", before = false, resultType = long.class)
User insert(User user); @Delete("delete from user where userid =#{userid}")
void delete(Long userid); @Select("select * from user limit #{start},#{end} ")
List<User> getPageUsers(int start, int end); @Update("update user set updateUser=#{updateUser},mail=#{mail} where userid=#{userid}")
int update(User user);

Tip:

官方文档:http://www.mybatis.org/mybatis-3/zh/java-api.html,强烈推荐注解方式。

读写分离的配置(druid多数据源):http://blog.csdn.net/xiaoyu411502/article/details/48164311/,http://www.cnblogs.com/Alandre/p/6611813.html

传统的mybatis生成工具: mybatis-generator-gui

此外,只需要添加spring-boot-starter-data-rest,即可默认支持Rest Data,其默认配置了rest.base-path等信息,也很便捷。

Spring对mongo的支持通过Spring Data MongoDB来实现,提供的功能为:@Document映射领域对象与MongoDB的一个文档;@Id映射当前属性是ID;@DbRef当前属性将参考其他文档;@Field为文档的属性定义名称;@Version将当前属性作为版本。其提供了MongoTemplate用于数据访问,以及MongoClient和MongoDbFactory来配置数据库连接属性,Springboot均提供默认配置,常见配置如下所示。

 spring.data.mongodb.host=
spring.data.mongodb.port=27017
spring.data.mongodb.uri=mongodb://localhost/test
spring.data.mongodb.database= Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

推荐个mongodb视图工具:https://robomongo.org/download

Redis可以被当做缓存服务器使用,也可以作为数据库服务器使用,推荐一个Redis的客户端工具:https://github.com/caoxinyu/RedisClient

数据库服务器:Spring对Redis的支持通过Spring Data Redis来实现,Spring Data JPA提供了链接相关的ConnectinFactory(LettuceConnectionFactory&Srp)、数据操作相关RedisTemplate(StringRedisTemplate)和序列化器(JdkSerializationRedisSerializer&String&Jackson2Json),Springboot提供了默认的设置(org.springframework.boot.autoconfigure.redis),配置如下所示。

常见的数据访问操作:opsForValue()操作只有简单属性的数据;opsForList()操作含有List的数据;opsForSet操作含有Set的数据;opsForZSet操作含有有序集合数据;opsForHash操作含有hash的数据。

 spring.redis.database=0 #db0
spring.redis.host=localhost
spring.redis.password=
spring.redis.port=6379 Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

数据缓存Cache:在Config类中,注册RedisCacheManager,添加上@EnableCache注解。Springboot默认是ConcurrentMapCacheManager来处理缓存,若需要Redis作为缓存提供者,只需配置spring.cache.type=redis,使用@Cacheable, @CachePut, @CacheEvict, @Caching即可。

 spring.cache.type=redis
Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

由于有的数据提供系统只能运行在类Linux系统上,因此引入docker的概念(搭建环境时真心非常的棒,只需关注需要的组件,而无需关注依赖组件):

Window下安装包(需要bios支持虚拟cpu):https://github.com/boot2docker/windows-installer/releases

Tip: 这种方式实际有3层环境,本机->virtualbox->docker

测试时需要注意端口转发,分别是docker->virtualbox,然后是virtualbox到本机(生产环境是linux直接部署docker,无此问题),如果使用oracle数据库需要自己下载ojdbc并安装到maven。

Docker常见命令:

功能 示例
镜像命令  
镜像检索 docker search 镜像名(redis)
镜像拉取 docker pull redis
镜像列表 docker images
删除指定镜像 docker rmi image-id
删除所有镜像 docker rmi ${docker images -q}
容器命令  
运行容器 docker run --name test-redis -d redis,其中-name为起名,-d为选择的镜像
容器列表 docker ps,添加-a可以查看运行或停止的容器
启动容器 docker start test-redis(container-name, container-id)
停止容器 docker stop test-redis
端口映射 Docker容器中运行软件所使用的端口,本机和局域网无法访问,所以需要将docker中容器中的端口映射到当前主机上,比如以redis为例,将容器6379端口映射到本地6378端口 docker run -d -p 6378:6379 --name port-redis redis
删除指定容器 docker rm container-id
删除所有容器 docker rm $(docker ps -a -q)
容器日志 docker logs port-redis
登录容器 Docker exec –it container-id bash exit退出
容器改名 docker rename xxx xxx

docker run命令参数:-d后台运行;-p暴露端口;-e设置环境变量,与dockerfile env设置相同效果 –name设置名称

Tip:

Hadoop、异步消息的整合会放在之后的文章中,敬请关注!J

  • 补充

在测试环境,比较便捷的一种sql数据库,hsqldb

参考资料

  1. 汪云飞. Spring Boot实战[M]. 北京:电子工业出版社, 2016.

SpringBoot详细研究-02数据访问的更多相关文章

  1. SpringBoot系列之JDBC数据访问

    SpringBoot系列之JDBC数据访问 New->Project or Module->Spring Initializer 选择JDBC和mysql驱动,为了方便测试web等等也可以 ...

  2. SpringBoot:Mybatis + Druid 数据访问

    西部开源-秦疆老师:基于SpringBoot 2.1.7 的博客教程 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! 简介 对于数据访问层 ...

  3. SpringBoot详细研究-01基础

    Springboot可以说是当前最火的java框架了,非常适合于"微服务"思路的开发,大幅缩短软件开发周期. 概念 过去Spring充满了配置bean的xml文件,随着spring ...

  4. SpringBoot(3):SpringData 数据访问

    一. 简介 Spring Data是一个用于简化数据库访问,并支持云服务的开源框架:其主要目标是 使得对数据的访问变得方便快捷.对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系 ...

  5. SpringBoot详细研究-03系统集成

    据说杰克船长被黑客盗片了,看来信息安全依然任重而道远,本文以此为引子,来介绍下spring boot对于系统集成方面的支持. Spring Security提供一套安全框架,通过IOC和AOP来实现安 ...

  6. SpringBoot详细研究-05微服务与拾遗

    这将是SpringBoot学习系列的最后一篇文章,主要涉及Spring Cloud和JHispter两个知识点,都具有一定综合性,需要多加实践加强理解. Spring Cloud 微服务Microse ...

  7. SpringBoot详细研究-04部署测试与监控

    这部分的内容实际就是devops的主要工作内容,当然一名合格的程序要也需要掌握这部分的知识. 热部署 简单来说,在开发时,修改了任何的代码,IDE将自动编译运行及发布:在发布时,当前发布不影响线上服务 ...

  8. springboot 数据访问【转】【补】

    六.SpringBoot与数据访问 1.JDBC pom.xml配置 <dependencies> <dependency> <groupId>org.spring ...

  9. SpringBoot数据访问(一) SpringBoot整合Mybatis

    前言 SpringData是Spring提供的一个用于简化数据库访问.支持云服务的开源框架.它是一个伞形项目,包含了大量关系型数据库及非关系型数据库的数据访问解决方案,其设计目的是为了使我们可以快速且 ...

随机推荐

  1. 洛谷P3241 开店

    题意:紫妹和幽香是17岁的少女,喜欢可爱的东西. 给定一棵树,有点权,边权.每次求所有权值在[l, r]范围内的点到点x的距离和.强制在线. 解:动态点分治怎么搞啊...... 一开始想的是权值的限制 ...

  2. python之旅:面向对象进阶

    一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object) ...

  3. Java 使用 Enum 实现单例模式

    在这篇文章中介绍了单例模式有五种写法:懒汉.饿汉.双重检验锁.静态内部类.枚举.如果涉及到反序列化创建对象时推荐使用枚举的方式来实现单例,因为Enum能防止反序列化时重新创建新的对象.本文介绍 Enu ...

  4. Docker:搭建私有仓库(Registry 2.4)

    一.背景 首先,Docker Hub是一个很好的用于管理公共镜像的地方,我们可以在上面找到想要的镜像(Docker Hub的下载量已经达到数亿次):而且我们也可以把自己的镜像推送上去.但是,有的时候, ...

  5. 三次握手---TCP/IP

    首先由Client发出请求连接即 SYN=1 ACK=0  (请看头字段的介绍), TCP规定SYN=1时不能携带数据,但要消耗一个序号,因此声明自己的序号是 seq=x 然后 Server 进行回复 ...

  6. 关于Thinkphp5类命名导致的“模块不存在”问题

    不得不说,thinkphp5就是个十足的坑货, 在thinkphp3.2.3的基础上,函数.用法变了也就忍了, 在mac下写的一个类文件 GetRedisData.php,在mac+mamp环境下是正 ...

  7. 基于docker的spark-hadoop分布式集群之一: 环境搭建

    一.软件准备 1.基础docker镜像:ubuntu,目前最新的版本是18 2.需准备的环境软件包: (1) spark-2.3.0-bin-hadoop2.7.tgz (2) hadoop-2.7. ...

  8. Redis记录-Redis介绍

    Redis是一个开源,高级的键值存储和一个适用的解决方案,用于构建高性能,可扩展的Web应用程序. Redis有三个主要特点,使它优越于其它键值数据存储系统 - Redis将其数据库完全保存在内存中, ...

  9. .NET面试题系列(六)多线程

    1.多线程的三个特性:原子性.可见性.有序性 原子性:是指一个操作是不可中断的.即使是多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰. 比如,对于一个静态全局变量int i,两个线程同 ...

  10. 利用fiddler来模拟低速环境

    为了让我们的站点拥有更好的用户体验,更短的加载时间,我们会“按需加载”页面的资源. 在调试程序的时候,我们希望能有一个低速率的网络环境来模拟真实线上的环境,这个时候fiddler(下载fiddler请 ...