对于传统关系型数据库来说,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. iOS笔记UI--使用storyboard加入约束

    申明:此为本人学习笔记,若有纰漏错误之处的可留言共同探讨 可视化的搭建UI效率是很高的.所以官方苹果也是很推荐的.那么我们来学一学怎样利用系统自带的故事版(storyboard)来搭建UI.可视化搭建 ...

  2. python_程序模拟浏览器请求及会话保持

    python下读取一个页面的数据可以通过urllib2轻松实现请求 import urllib2 print urllib2.urlopen('http://www.baidu.com').read( ...

  3. PHP数组排序函数array_multisort()函数详解(二)

    array_multisort()这个函数可以对多个PHP数组进行排序,排序结果是所有的数组都按第一个数组的顺序进行排列 例如array_multisort($a,$b),$a,$b是两个数组,如果排 ...

  4. UITextView: 响应键盘的 return 事件

    UITextFieldDelegate代理里面响应return键的回调:textFieldShouldReturn:.但是 UITextView的代理UITextViewDelegate 里面并没有这 ...

  5. 配置IP

    配置目的:配置IP为静态,让IP地址不变,方便长时间连接. 几个命令: dhclient 自动获取IP; 杀死进程:dhclient -r ip addr 显示网卡情况,了解到IP地址: 编辑配置文件 ...

  6. JAVA中的数字运算+号与字符串+号

    (1)当“+”两边是非数值类型,“+”就被看作连接符. (2)当“+”两边都是数值类型,“+”就被看作算术运算中的加号. (3)当“+”一边是非数值,一边是数值类型,“+”就被看作连接符.

  7. mysql 创建和删除用户

    1.远程登录mysql mysql -h ip -u root -p 密码 2.创建用户 格式:grant 权限 on 数据库.* to 用户名@登录主机 identified by "密码 ...

  8. 谈谈Android中的SurfaceTexture

    2015.7.2更新 由于很多人要代码,我把代码下载链接放在这里了.不过还是要说一下,surfaceTexture和OpenGL ES结合才能发挥出它最大的效果,我这种写法只是我自己的想法,还有很多种 ...

  9. js准确获取当前页面url网址信息

    这篇文章主要为大家介绍了js准确获取当前页面url网址信息的多种方法,包括正则法.split拆分法等,需要的朋友可以参考下   在WEB开发中,时常会用到javascript来获取当前页面的url网址 ...

  10. Npm基本指令(转)

    一些常用的 npm 指令 當你設定好 node.js 的開發環境後, 是時候來把下面這些常用的 npm 指令給摸熟了. 將套件於全域安裝. 全域安裝的套件通常只是為了執行檔而已. $ npm inst ...