对于传统关系型数据库来说,Spring Boot使用JPA(Java Persistence API)资源库提供持久化的标准规范,即将Java的普通对象通过对象关系映射(ORM)持久化到数据库中。

项目代码地址:https://github.com/AndyFlower/Spring-Boot-Learn/tree/master/spring-boot-database

一、使用MySQL是maven中的依赖配置

        <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

二、建立数据实体

1、假设有部门、用户、角色三个实体,且关系为一个用户只能隶属于一个部门,一个用户可以拥有多个角色

2、Java类

User.java

 package com.slp.entity;

 import com.fasterxml.jackson.annotation.JsonBackReference;
import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*;
import java.util.Date;
import java.util.List; /**
* Created by sangliping on 2017/8/18.
* @ManyToOne定义User与Department的多对一关系,并用中间表user_role来存储他们的ID
* @DateTimeFormat日期进行格式化
* @JsonBackReference用了方式关系对象的递归访问
*/ @Entity
@Table(name = "user")
public class User implements java.io.Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdate; @ManyToOne
@JoinColumn(name = "did")
@JsonBackReference
private Department deparment; @ManyToMany(cascade = {}, fetch = FetchType.EAGER)
@JoinTable(name = "user_role",
joinColumns = {@JoinColumn(name = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "roles_id")})
private List<Role> roles; public User() {
} public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Date getCreatedate() {
return createdate;
} public void setCreatedate(Date createdate) {
this.createdate = createdate;
} public Department getDeparment() {
return deparment;
} public void setDeparment(Department deparment) {
this.deparment = deparment;
} public List<Role> getRoles() {
return roles;
} public void setRoles(List<Role> roles) {
this.roles = roles;
}
}

Role.java

 package com.slp.entity;

 import javax.persistence.*;
import java.io.Serializable; /**
* Created by sangliping on 2017/8/18.
*/
import javax.persistence.*; @Entity
@Table(name = "role")
public class Role implements java.io.Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name; public Role() {
} public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

Department.java

 package com.slp.entity;

 import javax.persistence.*;

 /**
* Created by sangliping on 2017/8/18.
* @Table指定关联的数据库的表名
* @Id定义一条记录的唯一标识
* @GeneratedValue设置为自动增长
*/ @Entity
@Table(name = "department")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name; public Department() {
} public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

三、使用JPA实体进行持久化

1、持久化实体

UserRepository.java

 package com.slp.repository;

 import com.slp.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; /**
* Created by sangliping on 2017/8/18.
* @Repository将该接口定义为一个资源库,使它能被其他程序引用,为其他程序提供存储数据的功能
*/
@Repository
public interface UserRepository extends JpaRepository<User,Long> { }

RoleRepository.java

 package com.slp.repository;

 import com.slp.entity.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; /**
* Created by sangliping on 2017/8/18.
*/
@Repository
public interface RoleRepository extends JpaRepository<Role,Long> {
}

DepartmentRepository.java

 package com.slp.repository;

 import com.slp.entity.Department;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; /**
* Created by sangliping on 2017/8/18.
*/
@Repository
public interface DepartmentRepository extends JpaRepository<Department,Long> {
}

使用以上的实现我们不用写任何一句Sql语句就可以执行一些基本的操作,这是因为JpaRepository实现了一些方法,JpaRepository继承与PagingAndSortingRepository它提供了扥也和排序的功能,PageAndSortingRepository又继承与CurdRepository它提供了最简单的增删改查操作。

比如JpaRepository的方法包括:

 package org.springframework.data.jpa.repository;

 import java.io.Serializable;
import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor; @NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll(); List<T> findAll(Sort var1); List<T> findAll(Iterable<ID> var1); <S extends T> List<S> save(Iterable<S> var1); void flush(); <S extends T> S saveAndFlush(S var1); void deleteInBatch(Iterable<T> var1); void deleteAllInBatch(); T getOne(ID var1); <S extends T> List<S> findAll(Example<S> var1); <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

JPA定义声明方法的规则:

在接口中使用findBy、readBy、getBy作为方法名的前缀,拼接实体中类的属性字段(首字母大写)并可选择拼接一些SQL查询关键字来合成一个查询方法

 And           findByIdAndName(Long id,String name);
Or findByIdOrName(Long id,String name);
Between findByCreatedateBetween(Date start,Date end);
LessThan findByCreatedateLessThan(Date start);
GreaterThan findByCreatedateGreaterThan(Date start);
IsNull findByNameIsNull();
IsNotNull findByNameIsNotNull();
NotNull findByNameNotNull();
Like findByNameLike(String name);
NotLike findByNameNotLike(String name);
orderBy findByNameOrderByIdAsc(String name);
Not findByNameNot(String name);
In findByNameIn(Collection<String> nameList);
NotIn findByNameNotIn(Collection<String> nameList);

四、Spring Boot参数配置

 spring.datasource.url=jdbc:mysql://localhost:3306/dev?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.password=123456
spring.jpa.database=mysql
spring.jpa.show-sql=true
#配置此选项会自动检查表是否创建,如果没有创建则创建,如果已经创建则更新
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.propertie.hibernate.dialect=org.hibernate.dialect.MySQLDialect

五、创建JPA配置类

 package com.slp.config;

 import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement; /**
* Created by sangliping on 2017/8/18.
* @EnableTransactionManagement启用了JPA的事务管理
* @EnableJpaRepositories启用了JPA资源库并指定了定义的接口资源库的位置
* @EntityScan指定了定义实体的位置
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@EnableJpaRepositories(basePackages = "com.slp.repository")
@EntityScan(basePackages = "com.slp.entity")
public class JpaConfiguration { PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(){
return new PersistenceExceptionTranslationPostProcessor();
}
}

六、测试准备

1、在pom.xml文件中加入测试依赖

 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

2、编写测试JPA配置类

 package com.slp;

 /**
* Created by sangliping on 2017/8/18.
*/
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate; import javax.sql.DataSource;
import java.util.Properties; @Configuration
@EnableJpaRepositories(basePackages = "com.slp.repository")
public class JpaConfiguration { @Bean
PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
return new PersistenceExceptionTranslationPostProcessor();
} @Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/dev?characterEncoding=utf8");
dataSource.setUsername("root");
dataSource.setPassword("123456"); return dataSource;
} @Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan("com.slp.entity");
entityManagerFactoryBean.setJpaProperties(buildHibernateProperties());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter() {{
setDatabase(Database.MYSQL);
}});
return entityManagerFactoryBean;
} protected Properties buildHibernateProperties() {
Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.use_sql_comments", "false");
hibernateProperties.setProperty("hibernate.format_sql", "true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
hibernateProperties.setProperty("hibernate.generate_statistics", "false");
hibernateProperties.setProperty("javax.persistence.validation.mode", "none");
hibernateProperties.setProperty(" spring.jpa.hibernate.ddl-auto", "update");
//Audit History flags
hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", "true");
hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", "true"); return hibernateProperties;
} @Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
} @Bean
public TransactionTemplate transactionTemplate() {
return new TransactionTemplate(transactionManager());
} }

3、编写测试类

 package com.slp;
import com.slp.entity.Department;
import com.slp.entity.Role;
import com.slp.entity.User;
import com.slp.repository.DepartmentRepository;
import com.slp.repository.RoleRepository;
import com.slp.repository.UserRepository;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert; import java.util.*; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {JpaConfiguration.class})
public class MySqlTest {
private static Logger logger = LoggerFactory.getLogger(MySqlTest.class); @Autowired
UserRepository userRepository;
@Autowired
DepartmentRepository departmentRepository;
@Autowired
RoleRepository roleRepository; @Before
public void initData(){
userRepository.deleteAll();
roleRepository.deleteAll();
departmentRepository.deleteAll(); Department department = new Department();
department.setName("开发部");
departmentRepository.save(department);
Assert.notNull(department.getId()); Role role = new Role();
role.setName("slp");
roleRepository.save(role);
Assert.notNull(role.getId()); User user = new User();
user.setName("user");
user.setCreatedate(new Date());
user.setDeparment(department); List<Role> roles = roleRepository.findAll();
Assert.notNull(roles);
user.setRoles(roles); userRepository.save(user);
Assert.notNull(user.getId());
} @Test
public void findPage(){
Pageable pageable = new PageRequest(0, 10, new Sort(Sort.Direction.ASC, "id"));
Page<User> page = userRepository.findAll(pageable);
Assert.notNull(page);
for(User user : page.getContent()) {
logger.info("====user==== user name:{}, department name:{}, role name:{}",
user.getName(), user.getDeparment().getName(), user.getRoles().get(0).getName());
}
} }

注意:

1、不要忘记实体类上的Entity注解

2、不要忘记Repository上的Repository注解

3、测试Jpa配置文件位于test包下

4、如果之前创建了表之后名字变更会新建一个表这样再次执行的之后如果有主外键也会有冲突报错

【Spring Boot&&Spring Cloud系列】Spring Boot中使用数据库之MySql的更多相关文章

  1. 20.翻译系列:Code-First中的数据库迁移技术【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/migration-in-code-first.aspx EF 6 Code-First ...

  2. 在Docker中体验数据库之MySql

    在上一篇在Docker中体验数据库之Mongodb之后,这次记录一下在docker中安装mysql.过程要比Mongodb麻烦一点…… 参考网址: https://dev.mysql.com/doc/ ...

  3. spring boot 2.x 系列 —— spring boot 实现分布式 session

    文章目录 一.项目结构 二.分布式session的配置 2.1 引入依赖 2.2 Redis配置 2.3 启动类上添加@EnableRedisHttpSession 注解开启 spring-sessi ...

  4. spring boot 2.x 系列 —— spring boot 整合 redis

    文章目录 一.说明 1.1 项目结构 1.2 项目主要依赖 二.整合 Redis 2.1 在application.yml 中配置redis数据源 2.2 封装redis基本操作 2.3 redisT ...

  5. spring boot 2.x 系列 —— spring boot 整合 dubbo

    文章目录 一. 项目结构说明 二.关键依赖 三.公共模块(boot-dubbo-common) 四. 服务提供者(boot-dubbo-provider) 4.1 提供方配置 4.2 使用注解@Ser ...

  6. spring boot 2.x 系列 —— spring boot 整合 druid+mybatis

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构 项目查询用的表对应的建表语句放置在resour ...

  7. spring boot 2.x 系列 —— spring boot 整合 servlet 3.0

    文章目录 一.说明 1.1 项目结构说明 1.2 项目依赖 二.采用spring 注册方式整合 servlet 2.1 新建过滤器.监听器和servlet 2.2 注册过滤器.监听器和servlet ...

  8. spring boot 2.x 系列 —— spring boot 整合 RabbitMQ

    文章目录 一. 项目结构说明 二.关键依赖 三.公共模块(rabbitmq-common) 四.服务消费者(rabbitmq-consumer) 4.1 消息消费者配置 4.2 使用注解@Rabbit ...

  9. spring boot 2.x 系列 —— spring boot 整合 kafka

    文章目录 一.kafka的相关概念: 1.主题和分区 2.分区复制 3. 生产者 4. 消费者 5.broker和集群 二.项目说明 1.1 项目结构说明 1.2 主要依赖 二. 整合 kafka 2 ...

随机推荐

  1. (转)DSound开发常用的几个结构

    WAVEFORMATEX WAVEFORMATEX { WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPe ...

  2. Java设计模式六大原则之场景应用分析

    定义:不要存在多于一个导致类变更的原因. 通俗的说.即一个类仅仅负责一项职责. 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而须要改动类T时,有可能会导致原本执行正 ...

  3. ASP.NET 网站超时跳转到登录界面

    利用actionFilter过滤器实现,超时跳转到登录界面 /// <summary> /// 登录超时跳转至登录界面 /// </summary> public class ...

  4. RabbitMQ学习笔记(一):安装及Springboot集成

    前言 MQ,即消息队列Message Queue的缩写. RabbitMQ 是MQ的一种,就像招商银行是银行的一种一样.主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用. 消息 ...

  5. Oracle性能调整ASH,AWR,ADDM

    ASH (Active Session History)ASH以V$SESSION为基础,每秒采样一次,记录活动会话等待的事件.不活动的会话不会采样,采样工作由新引入的后台进程MMNL来完成.ASH ...

  6. 【项目管理】Project使用

    http://www.cnblogs.com/wangfupeng1988/p/3647166.html

  7. 一分钟理清Vue-cli 代码构建步骤。

    1. $ npm install vue -cli -g $ vue init webpack project-name $ cd project-name $ npm install $ npm r ...

  8. iOS 开发,工程中混合使用 ARC 和非ARC(转)

    [前提知识] ARC:Automatic Reference Counting,自动引用计数 在开发 iOS 3 以及之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain. ...

  9. Window系统、主函数和窗体函数这三者之间的关系

    理解Window系统.主窗体.窗体函数这三者之间的关系,对于编写Windows程序十分重要. 主函数和窗体函数都是由Windows系统来调用的函数.仅仅只是主函数是程序启动之后.系统首先调用的函数: ...

  10. 【安全开发】java安全编码规范

    申明:本文非笔者原创,原文转载自:https://github.com/SecurityPaper/SecurityPaper-web/blob/master/_posts/2.SDL%E8%A7%8 ...