04 SpringBoot对数据库的支持

简介

Spring Data项目是Spring用来解决数据访问问题的一揽子解决方案

Spring Data提供了统一的API,对数据存储技术进行支持

不同的持久层技术,有不同的Spring Data子项目

这些子项目都通过Spring Data Commons项目来实现

Spring DataCommons让我们在使用关系型或非关系型数据库技术时,都使用基于Spring的统一标准

包含:CRUD、查询、排序、分页

常用子项目

  • Spring Data JPA
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>1.11.10.RELEASE</version>
</dependency>

  • Spring Data MongoDB
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>1.10.10.RELEASE</version>
</dependency>

  • Spring Data Neo4J
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-neo4j -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-neo4j</artifactId>
    <version>5.0.3.RELEASE</version>
</dependency>

  • Spring Data Redis
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.0.3.RELEASE</version>
</dependency>

  • Spring Data Solr
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-solr -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-solr</artifactId>
    <version>3.0.3.RELEASE</version>
</dependency>

  • Spring For Apache Hadoop
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-hadoop -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-hadoop</artifactId>
    <version>2.5.0.RELEASE</version>
</dependency>

  • Spring Data GemFire
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-gemfire -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-gemfire</artifactId>
    <version>2.0.3.RELEASE</version>
</dependency>

  • Spring Data REST WebMVC
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-rest-webmvc -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-rest-webmvc</artifactId>
    <version>3.0.3.RELEASE</version>
</dependency>

  • Spring Data Couchbase
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-couchbase -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-couchbase</artifactId>
    <version>3.0.3.RELEASE</version>
</dependency>

  • Spring Data Elasticsearch
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-elasticsearch -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-elasticsearch</artifactId>
    <version>3.0.3.RELEASE</version>
</dependency>

  • Spring Data For Apache Cassandra Core
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-cassandra -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-cassandra</artifactId>
    <version>2.0.3.RELEASE</version>
</dependency>

Repository接口

package org.springframework.data.repository;

import java.io.Serializable;
public interface Repository<T, ID extends Serializable> {

}

Repository根接口接收JPA领域类和领域类的id类型作为类型参数

CrudRepository

CrudRepository子接口定义了和CRUD相关操作的内容


package org.springframework.data.repository;

import java.io.Serializable;


@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {


	<S extends T> S save(S entity);


	<S extends T> Iterable<S> save(Iterable<S> entities);


	T findOne(ID id);

	boolean exists(ID id);

	Iterable<T> findAll();


	Iterable<T> findAll(Iterable<ID> ids);

	long count();


	void delete(ID id);


	void delete(T entity);


	void delete(Iterable<? extends T> entities);


	void deleteAll();
}

PagingAndSortingRepository

PagingAndSortingRepository子接口定义了分页、排序相关的内容


package org.springframework.data.repository;

import java.io.Serializable;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

/**
 * Extension of {@link CrudRepository} to provide additional methods to retrieve entities using the pagination and
 * sorting abstraction.
 * 
 * @author Oliver Gierke
 * @see Sort
 * @see Pageable
 * @see Page
 */
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {

	/**
	 * Returns all entities sorted by the given options.
	 * 
	 * @param sort
	 * @return all entities sorted by the given options
	 */
	Iterable<T> findAll(Sort sort);

	/**
	 * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
	 * 
	 * @param pageable
	 * @return a page of entities
	 */
	Page<T> findAll(Pageable pageable);
}

小结

不同的数据访问技术提供了不同的Repository

如:Spring Data JPA有JpaRepository;Spring Data MongoDB有MongoRepository

Spring Data项目有一个激动人心的功能,可以根据属性名进行计数、删除、查询等方法的操作

关键字 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEquals findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like ‘?%’
EndingWith findByNameEndingWith where name like ‘%?’
Containing findByNameContaining where name like ‘%?%’
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)
NotIn findByIdNotIn(Collection<?> c) where id not in (?)
True findByAaaTue where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?

find方法是查询,如果是计数,则为count,删除,则为delete

限制结果数量:top和first关键字,如,findFirst10ByName,findTop10ByName

Spring Data JPA

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
  • 数据源
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/tdk?useSSL=false&useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  jackson:
    serialization: true

自动配置

SpringBoot自动开启了注解事务的支持(@EnableTransactionManagement

还配置了一个JdbcTemplate

Spring还提供了一个初始化数据的功能,放在类路径下的schema.sql自动初始化表结构,data.sql自动填充表数据

SpringData对JPA的自动配置放在org.springframework.boot.autoconfigure.orm.jpa

默认的JPA实现是Hibernate

配置JPA的前缀为:spring.jpa

自动扫描注解有@Entity的实体类

在Web项目中,我们经常遇到控制器或页面访问数据的时候出现会话连接关闭的错误

这个时候,我们会配置一个Open EntityManager(Session)In View这个过滤器

SpringBoot为我们自动配置了OpenEntityManagerInViewInterceptor这个Bean,

并且已经注册到SpringMVC拦截器。

无需手动开启

@EnableJpaRepositories

案例

  • pom

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
  • domain
package org.zln.spb.demo01.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQuery;

/**
 * @Author 张柳宁
 * @Description
 * @Date Create in 2018/1/31
 * @Modified By:
 */
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@NamedQuery(name = "Person.withNameAndAddressNamedQuery",
        query = "select p from Person p where p.name = ?1 and p.address = ?2")
public class Person {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private Integer age;
    private String address;
}

  • dao
package org.zln.spb.demo01.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.zln.spb.demo01.domain.Person;

import java.util.List;

/**
 * @Author 张柳宁
 * @Description
 * @Date Create in 2018/1/31
 * @Modified By:
 */

public interface PersonDao extends JpaRepository<Person,Long> {

    List<Person> findByAddress(String address);

    Person findByNameAndAddress(String name,String address);

    @Query("select p from Person p where p.name = :name and p.address = :address")
    Person withNameAndAddressQuery(@Param("name") String name,@Param("address") String address);

    Person withNameAndAddressNamedQuery(String name,String address);

    List<Person> findByNameLike(String name);



}


  • 测试
package org.zln.spb.demo01.dao;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.zln.spb.demo01.domain.Person;

import java.util.List;

import static org.junit.Assert.*;

/**
 * @Author 张柳宁
 * @Description
 * @Date Create in 2018/1/31
 * @Modified By:
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonDaoTest {

    @Autowired
    private PersonDao personDao;

    @Test
    public void findByAddress() {
        personDao.findByAddress("地址");
    }

    @Test
    public void findByNameAndAddress() {
        personDao.findByNameAndAddress("姓名","地址");
    }

    @Test
    public void withNameAndAddressQuery() {
        personDao.withNameAndAddressQuery("姓名","地址");
    }

    @Test
    public void withNameAndAddressNamedQuery() {
        personDao.withNameAndAddressNamedQuery("姓名","地址");
    }

    @Test
    public void findByNameLike() {
        List<Person> personList = personDao.findByNameLike("%name%");
        System.out.println(personList);
    }
}
  • 排序
personList = personDao.findAll(new Sort(Sort.Direction.DESC,"age"));
  • 分页查询
Page<Person> people = personDao.findAll(new PageRequest(2,3));
for (Person person:people){
  System.out.println(person);
}

小结

对于大多数的SQL,其实都是非常简单的单表查询

这个时候使用IDEA对Hibernate的自动生成代码,非常方便的

对于一些复杂SQL,再考虑使用MyBatis或者JdbcTemplate

整合H2数据库

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
</dependency>

server:
  port: 8000
spring:
  jpa:
    generate-ddl: false
    show-sql: true
    hibernate:
      ddl-auto: none
  datasource:                           # 指定数据源
    platform: h2                        # 指定数据源类型
    schema: classpath:schema.sql        # 指定h2数据库的建表脚本
    data: classpath:data.sql            # 指定h2数据库的数据脚本
logging:                                # 配置日志级别,让hibernate打印出执行的SQL
  level:
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.hibernate.type.descriptor.sql.BasicExtractor: TRACE

HikariDataSource数据源

配置

# jdbc_config   datasource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/datebook?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=root
# Hikari will use the above plus the following to setup connection pooling
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=DatebookHikariCP
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
spring:
  profiles:
    active: prod
  datasource:
  #  使用高性能数据源
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.jdbc.Driver
    hikari:
      minimum-idle: 15
      maximum-pool-size: 50
      idle-timeout: 30000
      pool-name: DatebookHikariCP
      maxLifetime: 40000 # 这个值要配置的比mysql的wait_timeout小,默认值是30分钟。但是不得配置少于30秒,佛足额就会重置回默认值
      connection-timeout: 30000
      connection-test-query: SELECT 1
      connection-init-sql: set names utf8mb4
      validation-timeout: 5000

springboot 2.0 默认连接池就是Hikari了,所以引用parents后不用专门加依赖

java配置

Java配置数据源

    public HikariDataSource dataSourceConf(MutiDataSourceProperties dataSource) {
        //数据源配置信息
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(dataSource.getUrl());
        hikariConfig.setUsername(dataSource.getUsername());
        hikariConfig.setPassword(dataSource.getPassword());
        hikariConfig.setDriverClassName(dataSource.getDriverClassName());

        //初始化数据源
        HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
        return hikariDataSource;
    }

默认配置

事务

所有的数据库访问技术都有事务处理机制

这些技术提供了API用于事务的开启、提交、回滚等操作

Spring事务机制提供了PlatformTransactionManager接口

数据库访问技术 实现
JDBC DataSourceTransactionManager
JPA JpaTransactionManager
Hibernate HibernateTransactionManager
JDO JdoTransactionManager
分布式事务 JtaTransactionManager

如果不使用SpringBoot,用Spring原始的方式自己配置的话

1、配置PlatformTransactionManager

2、开启事务@EnableTransactionManagement

@Transactional

事务行为基本上都是由@Transactional注解来控制的

如果想要使用默认的事务配置,那么在编写Dao代码的时候,就要去继承SimpleJpaRepository

事务传播行为介绍:

@Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
  @Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事务
  @Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
  @Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常
  @Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
  @Transactional(propagation=Propagation.SUPPORTS) :如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.

事务超时设置:

@Transactional(timeout=30) //默认是30秒

事务隔离级别:

@Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读, 不可重复读) 基本不使用
  @Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)
  @Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)
  @Transactional(isolation = Isolation.SERIALIZABLE):串行化

MYSQL: 默认为REPEATABLE_READ级别
  SQLSERVER: 默认为READ_COMMITTED

脏读 : 一个事务读取到另一事务未提交的更新数据
不可重复读 : 在同一事务中, 多次读取同一数据返回的结果有所不同, 换句话说,
后续读取可以读到另一事务已提交的更新数据. 相反, "可重复读"在同一事务中多次
读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据
幻读 : 一个事务读到另一个事务已提交的insert数据

参数名称 功能描述
readOnly 该属性用于设置当前事务是否为只读事务,设置为true表示只读,
false则表示可读写,默认值为false。
例如:@Transactional(readOnly=true)
rollbackFor 该属性用于设置需要进行回滚的异常类数组,
当方法中抛出指定异常数组中的异常时,则进行事务回滚。
例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:
@Transactional(rollbackFor={RuntimeException.class, Exception.class})
rollbackForClassName 该属性用于设置需要进行回滚的异常类名称数组,
当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。
例如:指定单一异常类名称:@Transactional(rollbackForClassName=“RuntimeException”)
指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,“Exception”})
noRollbackFor 该属性用于设置不需要进行回滚的异常类数组,
当方法中抛出指定异常数组中的异常时,不进行事务回滚。
例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)
指定多个异常类:
@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
noRollbackForClassName 该属性用于设置不需要进行回滚的异常类名称数组,
当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。
例如:指定单一异常类名称:@Transactional(noRollbackForClassName=“RuntimeException”)
指定多个异常类名称:
@Transactional(noRollbackForClassName={“RuntimeException”,“Exception”})
propagation 该属性用于设置事务的传播行为,具体取值可参考表6-7。
例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,
readOnly=true)
isolation 该属性用于设置底层数据库的事务隔离级别,
事务隔离级别用于处理多事务并发的情况,
通常使用数据库的默认隔离级别即可,基本不需要进行设置
timeout 该属性用于设置事务的超时秒数,默认值为-1表示永不超时

注意的几点:

1、@Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.
  2、用 spring 事务管理器,由spring来负责数据库的打开,提交,回滚.默认遇到运行期例外(throw new RuntimeException(“注释”);)会回滚,即遇到不受检查(unchecked)的例外时回滚;而遇到需要捕获的例外(throw new Exception(“注释”);)不会回滚,即遇到受检查的例外(就是非运行时抛出的异常,编译器会检查到的异常叫受检查例外或说受检查异常)时,需我们指定方式来让事务回滚要想所有异常都回滚,要加上 @Transactional( rollbackFor={Exception.class,其它异常}) .如果让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

​ 3、@Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。

4、@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上。然而,请注意仅仅 @Transactional 注解的出现不足于开启事务行为,它仅仅 是一种元数据,能够被可以识别 @Transactional 注解和上述的配置适当的具有事务行为的beans所使用。上面的例子中,其实正是 元素的出现 开启 了事务行为。

5、Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。你当然可以在接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理时它才生效。因为注解是不能继承的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。因此,请接受Spring团队的建议并且在具体的类上使用 @Transactional 注解。

SpringBoot的事务支持

只要选择了一个数据访问技术,配置好了DataSource,事务管理起默认就会配置好

缓存

缓存的使用详见Spring章节

在SpringBoot中,其自动配置了以下CacheManager

EhCacheCacheConfiguration、GenericCacheConfiguration、GuavaCacheConfiguration、HazelcastCacheConfiguration、HazelcastInstanceConfiguration、HazelcastJCacheCustomizationConfiguration、RedisCacheConfiguration、……

默认使用SimpleCacheConfiguration

缓存相关配置以 spring.cache为前缀

只要导入了相关jar包,并在配置类上使用@EnableCache开启缓存支持即可

ehcache

添加ehcache的pom

<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.4</version>
</dependency>

在类路径下放置 ehcache.xml 即可

redis

将redis的starter pom添加到maven依赖,

SpringBoot自动为我们配置RedisCacheManager以及RedisTemplate的Bean

MongoDB

application.yml

spring:
  data:
    mongodb:
#      uri: mongodb://用户名:密码@localhost:27017/test
      uri: mongodb://localhost:27017/test

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>org.zln.example</groupId>
	<artifactId>spring-boot-data-mongodb-01</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-boot-data-mongodb-01</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.10.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

实体类

package org.zln.example.springbootdatamongodb01.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.io.Serializable;

@Data
@Document(collection = "user")
@AllArgsConstructor
@NoArgsConstructor
public class UserEntity implements Serializable {
        @Id
        private String userId;
        private String userName;
        private String passWord;

        @Override
        public String toString() {
                final StringBuilder sb = new StringBuilder("UserEntity{");
                sb.append("userId='").append(userId).append('\'');
                sb.append(", userName='").append(userName).append('\'');
                sb.append(", passWord='").append(passWord).append('\'');
                sb.append('}');
                return sb.toString();
        }
}

dao

package org.zln.example.springbootdatamongodb01.dao;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import org.zln.example.springbootdatamongodb01.entity.UserEntity;

/**
 * @Author 张柳宁
 * @Description
 * @Date Create in 2018/2/1
 * @Modified By:
 */
@Repository
public interface UserDao extends MongoRepository<UserEntity,String>{

    UserEntity insert(UserEntity entity);

    UserEntity findByUserId(String userId);

}

测试

package org.zln.example.springbootdatamongodb01.dao;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.zln.example.springbootdatamongodb01.entity.UserEntity;

import static org.junit.Assert.*;

/**
 * @Author 张柳宁
 * @Description
 * @Date Create in 2018/2/1
 * @Modified By:
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserDaoTest {

    @Autowired
    private UserDao userDao;

    @Test
    public void insert() {
        UserEntity userEntity = new UserEntity("01","uname","pd");
        userDao.insert(userEntity);
    }

    @Test
    public void findByUserId() {
        UserEntity userEntity = userDao.findByUserId("01");
        System.out.println(userEntity);
    }
}

如果不想使用Reposi

Redis

application.yml

spring:
  redis:
    host: localhost
    port: 6379

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>org.zln.example</groupId>
	<artifactId>spring-boot-data-redis-01</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-boot-data-redis-01</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.10.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.8.2</version>
		</dependency>
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>23.6-jre</version>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

实体类

package org.zln.example.springbootdataredis01.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @Author 张柳宁
 * @Description
 * @Date Create in 2018/2/1
 * @Modified By:
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserEntity implements Serializable{
    private Long id;
    private String name;

    @Override
    public String toString() {
        return com.google.common.base.MoreObjects.toStringHelper(this)
                .add("id", id)
                .add("name", name)
                .toString();
    }
}

dao

package org.zln.example.springbootdataredis01.dao;

import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import org.zln.example.springbootdataredis01.entity.UserEntity;

/**
 * @Author 张柳宁
 * @Description
 * @Date Create in 2018/2/1
 * @Modified By:
 */
@Repository
public class UserDao {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    Gson gson = new Gson();

    public void add(UserEntity userEntity) {
        redisTemplate.opsForValue().set(userEntity.getId() + "", gson.toJson(userEntity));
    }

    public UserEntity get(String k) {
        String userEntityJson = redisTemplate.opsForValue().get(k);
        UserEntity userEntity = gson.fromJson(userEntityJson,UserEntity.class);
        return userEntity;
    }
}

RedisTemplate可以直接使用

测试

package org.zln.example.springbootdataredis01.dao;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.zln.example.springbootdataredis01.entity.UserEntity;

import static org.junit.Assert.*;

/**
 * @Author 张柳宁
 * @Description
 * @Date Create in 2018/2/1
 * @Modified By:
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserDaoTest {

    @Autowired
    private UserDao userDao;

    @Test
    public void add() {
        UserEntity userEntity = new UserEntity(1L,"哇哈哈");
        userDao.add(userEntity);
    }

    @Test
    public void get() {
        UserEntity userEntity = userDao.get("1");
        System.out.println(userEntity);
    }
}

使用Druid

SpringBoot默认的数据源是org.apache.tomcat.jdbc.pool.DataSource

为了使用性能更好的Druid,需要重新配置

		<!--数据源-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.29</version>
		</dependency>
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

加强配置

e3f87584-2e32-4e86-b99c-97ce848b4439.png

20cb4f48-36a4-425a-9af3-c1e58ab6876e.png

4db2d6c7-1109-4d8b-8dad-afc8afd9ff11.png

7c47ca0c-58ef-4798-98af-1a66f45e2436.png

猜你喜欢

转载自blog.csdn.net/m0_37208669/article/details/85235229