【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 ...
随机推荐
- Eclipse SVN过滤文件夹及文件的方法
有两个步骤: 1.在TortoiseSVN中将文件.文件夹加入ignore list: 2.在Eclipse中Ignored Resources利用模式匹配忽略指定文件夹.文件类型. 这样,那些无需同 ...
- (诊断)git review时出现fatal: ICLA contributor agreement requires current contact information.错误
使用git review时出现错误: fatal: ICLA contributor agreement requires current contact information. Please re ...
- Windows2008安装WebSphere 6.1提示此安装程序不能在图形方式中运行
推荐的解决方式:http://blog.sina.com.cn/s/blog_4b010fb50100n1mk.html 在一般情况下,安装Websphere是直接运行launchpad.exe,然后 ...
- linux vi命令详解2
刚开始学着用linux,对vi命令不是很熟,在网上转接了一篇. vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指 ...
- mysql错误代码对照表较完整 mysql_errno()
From: http://blog.csdn.net/aidenliu/article/details/5925604 mysql错误代码对照表较完整 0101 属于其他进程的专用标志. 0102 ...
- HTML5 Canvas 超炫酷烟花绽放动画教程
这是一个很酷的HTML5 Canvas动画,它将模拟的是我们现实生活中烟花绽放的动画特效,效果非常逼真,但是毕竟是电脑模拟,带女朋友看就算了,效果还是差了点,呵呵.这个HTML5 Canvas动画有一 ...
- 安装PHP5 PHP7
安装 PHP5 PHP官网www.php.net • 当前主流版本为5./7.1 • cd /usr/local/src/ • wget http://cn2.php.net/distribution ...
- Scala2.11.8 spark2.3.1 mongodb connector 2.3.0
import java.sql.DriverManager import com.mongodb.spark._ import org.apache.spark.SparkConf import or ...
- HOStringSense大段字符串检测器
下载地址:https://github.com/holtwick/HOStringSense-for-Xcode 修改HOStringSense.xcodeproj工程里的HOStringHelper ...
- wget 下载指定url路径下的 指定类型的(全部)文件
wget http://mirrors.ustc.edu.cn/ubuntu/pool/main/g/gcc-4.4/ -r -np -nd -A .deb -e robots=offwget htt ...