【Spring Boot&&Spring Cloud系列】Spring Boot中使用数据库之MySql
对于传统关系型数据库来说,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的更多相关文章
- 20.翻译系列:Code-First中的数据库迁移技术【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/migration-in-code-first.aspx EF 6 Code-First ...
- 在Docker中体验数据库之MySql
在上一篇在Docker中体验数据库之Mongodb之后,这次记录一下在docker中安装mysql.过程要比Mongodb麻烦一点…… 参考网址: https://dev.mysql.com/doc/ ...
- spring boot 2.x 系列 —— spring boot 实现分布式 session
文章目录 一.项目结构 二.分布式session的配置 2.1 引入依赖 2.2 Redis配置 2.3 启动类上添加@EnableRedisHttpSession 注解开启 spring-sessi ...
- spring boot 2.x 系列 —— spring boot 整合 redis
文章目录 一.说明 1.1 项目结构 1.2 项目主要依赖 二.整合 Redis 2.1 在application.yml 中配置redis数据源 2.2 封装redis基本操作 2.3 redisT ...
- spring boot 2.x 系列 —— spring boot 整合 dubbo
文章目录 一. 项目结构说明 二.关键依赖 三.公共模块(boot-dubbo-common) 四. 服务提供者(boot-dubbo-provider) 4.1 提供方配置 4.2 使用注解@Ser ...
- spring boot 2.x 系列 —— spring boot 整合 druid+mybatis
源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构 项目查询用的表对应的建表语句放置在resour ...
- spring boot 2.x 系列 —— spring boot 整合 servlet 3.0
文章目录 一.说明 1.1 项目结构说明 1.2 项目依赖 二.采用spring 注册方式整合 servlet 2.1 新建过滤器.监听器和servlet 2.2 注册过滤器.监听器和servlet ...
- spring boot 2.x 系列 —— spring boot 整合 RabbitMQ
文章目录 一. 项目结构说明 二.关键依赖 三.公共模块(rabbitmq-common) 四.服务消费者(rabbitmq-consumer) 4.1 消息消费者配置 4.2 使用注解@Rabbit ...
- spring boot 2.x 系列 —— spring boot 整合 kafka
文章目录 一.kafka的相关概念: 1.主题和分区 2.分区复制 3. 生产者 4. 消费者 5.broker和集群 二.项目说明 1.1 项目结构说明 1.2 主要依赖 二. 整合 kafka 2 ...
随机推荐
- NR 数据库简介
目前有很多的数据库都存储了蛋白序列,比如NCBI Refseq, protein, swissprot 等,在各个数据库之间,或者是在某个数据库中,蛋白序列有大量冗余:为了方便使用,ncbi 构建了n ...
- 多个IoC容器适配器设计及性能测试(Castle.Windsor Autofac Spring.Core)
[转]多个IoC容器适配器设计及性能测试和容器选择 1. 采用的IoC容器和版本 Autofac.2.6.3.862 Castle.Windsor.3.1.0 Spring.Core.2.0.0 2. ...
- springmvc接口ios网络请求
springmvc: application/json;charset=utf-8的ios网络请求: 后台使用 @RequestBody注解参数接收:
- 【转】Spring Boot干货系列:(二)配置文件解析
转自:Spring Boot干货系列:(二)配置文件解析 前言 上一篇介绍了Spring Boot的入门,知道了Spring Boot使用"习惯优于配置"(项目中存在大量的配置,此 ...
- [Learn AF3]第七章 App framework组件之Popup
AF3的弹出对话框Popup 组件名称:Popup 是否js控件:是,$.afui.popup 说明:af3中的popup和af2中相比变化不大,依然是通过插件popup来实现的 方法 ...
- [译]Angular-ui 之 Url Routing
◄ 前一篇 (Multiple Named Views) 下一篇 (The Components) ► 在你的应用中多数的状态都是基于特定的url地址的.Url Routing机制绝不是在状态 ...
- Umbraco中使用Related Links显示内部链接和外部链接
在Umbraco的论坛里看到的办法,演示了如何在Umbraco中使用Related Links并显示的过程. 原文地址:http://www.nibble.be/?p=48
- 2. 自动化运维系列之Cobbler给Openstack节点安装操作系统。
preface 我们在一篇博文知道了如何搭建Cobbler,那么下面就通过Cobbler来安抓Openstack所有节点吧. 服务器配置信息如下: 主机名 IP 角色 Cobbler.node.com ...
- 如何在Java 环境下使用 HTTP 协议收发 MQ 消息
1. 准备环境在工程 POM 文件添加 HTTP Java 客户端的依赖. <dependency> <groupId>org.eclipse.jetty</groupI ...
- HTML5标签embed详解
摘要: <embed> 标签是 HTML 5 中的新标签,用来定义嵌入的内容,比如插件.类似于HTML 4.01 中的object和applet标签.我们要在网页中正常显示flash内容, ...