• 【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

     1 package com.slp.entity;
     2 
     3 import com.fasterxml.jackson.annotation.JsonBackReference;
     4 import org.springframework.format.annotation.DateTimeFormat;
     5 
     6 import javax.persistence.*;
     7 import java.util.Date;
     8 import java.util.List;
     9 
    10 
    11 /**
    12  * Created by sangliping on 2017/8/18.
    13  * @ManyToOne定义User与Department的多对一关系,并用中间表user_role来存储他们的ID
    14  * @DateTimeFormat日期进行格式化
    15  * @JsonBackReference用了方式关系对象的递归访问
    16  */
    17 
    18 @Entity
    19 @Table(name = "user")
    20 public class User implements java.io.Serializable{
    21     @Id
    22     @GeneratedValue(strategy = GenerationType.IDENTITY)
    23     private Long id;
    24     private String name;
    25     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    26     private Date createdate;
    27 
    28     @ManyToOne
    29     @JoinColumn(name = "did")
    30     @JsonBackReference
    31     private Department deparment;
    32 
    33     @ManyToMany(cascade = {}, fetch = FetchType.EAGER)
    34     @JoinTable(name = "user_role",
    35             joinColumns = {@JoinColumn(name = "user_id")},
    36             inverseJoinColumns = {@JoinColumn(name = "roles_id")})
    37     private List<Role> roles;
    38 
    39     public User() {
    40     }
    41 
    42     public Long getId() {
    43         return id;
    44     }
    45 
    46     public void setId(Long id) {
    47         this.id = id;
    48     }
    49 
    50     public String getName() {
    51         return name;
    52     }
    53 
    54     public void setName(String name) {
    55         this.name = name;
    56     }
    57 
    58     public Date getCreatedate() {
    59         return createdate;
    60     }
    61 
    62     public void setCreatedate(Date createdate) {
    63         this.createdate = createdate;
    64     }
    65 
    66     public Department getDeparment() {
    67         return deparment;
    68     }
    69 
    70     public void setDeparment(Department deparment) {
    71         this.deparment = deparment;
    72     }
    73 
    74     public List<Role> getRoles() {
    75         return roles;
    76     }
    77 
    78     public void setRoles(List<Role> roles) {
    79         this.roles = roles;
    80     }
    81 }

    Role.java

     1 package com.slp.entity;
     2 
     3 import javax.persistence.*;
     4 import java.io.Serializable;
     5 
     6 /**
     7  * Created by sangliping on 2017/8/18.
     8  */
     9 import javax.persistence.*;
    10 
    11 @Entity
    12 @Table(name = "role")
    13 public class Role implements java.io.Serializable{
    14     @Id
    15     @GeneratedValue(strategy = GenerationType.IDENTITY)
    16     private Long id;
    17     private String name;
    18 
    19     public Role() {
    20     }
    21 
    22     public Long getId() {
    23         return id;
    24     }
    25 
    26     public void setId(Long id) {
    27         this.id = id;
    28     }
    29 
    30     public String getName() {
    31         return name;
    32     }
    33 
    34     public void setName(String name) {
    35         this.name = name;
    36     }
    37 }

    Department.java

     1 package com.slp.entity;
     2 
     3 
     4 import javax.persistence.*;
     5 
     6 /**
     7  * Created by sangliping on 2017/8/18.
     8  * @Table指定关联的数据库的表名
     9  * @Id定义一条记录的唯一标识
    10  * @GeneratedValue设置为自动增长
    11  */
    12 
    13 @Entity
    14 @Table(name = "department")
    15 public class Department {
    16     @Id
    17     @GeneratedValue(strategy = GenerationType.IDENTITY)
    18     private Long id;
    19     private String name;
    20 
    21     public Department() {
    22     }
    23 
    24     public Long getId() {
    25         return id;
    26     }
    27 
    28     public void setId(Long id) {
    29         this.id = id;
    30     }
    31 
    32     public String getName() {
    33         return name;
    34     }
    35 
    36     public void setName(String name) {
    37         this.name = name;
    38     }
    39 }

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

    1、持久化实体

    UserRepository.java

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

    RoleRepository.java

     1 package com.slp.repository;
     2 
     3 import com.slp.entity.Role;
     4 import org.springframework.data.jpa.repository.JpaRepository;
     5 import org.springframework.stereotype.Repository;
     6 
     7 
     8 /**
     9  * Created by sangliping on 2017/8/18.
    10  */
    11 @Repository
    12 public interface RoleRepository extends JpaRepository<Role,Long> {
    13 }

    DepartmentRepository.java

     1 package com.slp.repository;
     2 
     3 import com.slp.entity.Department;
     4 import org.springframework.data.jpa.repository.JpaRepository;
     5 import org.springframework.stereotype.Repository;
     6 
     7 /**
     8  * Created by sangliping on 2017/8/18.
     9  */
    10 @Repository
    11 public interface DepartmentRepository extends JpaRepository<Department,Long> {
    12 }

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

    比如JpaRepository的方法包括:

     1 package org.springframework.data.jpa.repository;
     2 
     3 import java.io.Serializable;
     4 import java.util.List;
     5 import org.springframework.data.domain.Example;
     6 import org.springframework.data.domain.Sort;
     7 import org.springframework.data.repository.NoRepositoryBean;
     8 import org.springframework.data.repository.PagingAndSortingRepository;
     9 import org.springframework.data.repository.query.QueryByExampleExecutor;
    10 
    11 @NoRepositoryBean
    12 public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    13     List<T> findAll();
    14 
    15     List<T> findAll(Sort var1);
    16 
    17     List<T> findAll(Iterable<ID> var1);
    18 
    19     <S extends T> List<S> save(Iterable<S> var1);
    20 
    21     void flush();
    22 
    23     <S extends T> S saveAndFlush(S var1);
    24 
    25     void deleteInBatch(Iterable<T> var1);
    26 
    27     void deleteAllInBatch();
    28 
    29     T getOne(ID var1);
    30 
    31     <S extends T> List<S> findAll(Example<S> var1);
    32 
    33     <S extends T> List<S> findAll(Example<S> var1, Sort var2);
    34 }

    JPA定义声明方法的规则:

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

     1 And           findByIdAndName(Long id,String name);
     2 Or            findByIdOrName(Long id,String name);
     3 Between       findByCreatedateBetween(Date start,Date end);
     4 LessThan      findByCreatedateLessThan(Date start);
     5 GreaterThan   findByCreatedateGreaterThan(Date start);
     6 IsNull        findByNameIsNull();
     7 IsNotNull     findByNameIsNotNull();
     8 NotNull       findByNameNotNull();
     9 Like          findByNameLike(String name);
    10 NotLike       findByNameNotLike(String name);
    11 orderBy       findByNameOrderByIdAsc(String name);
    12 Not           findByNameNot(String name);
    13 In            findByNameIn(Collection<String> nameList);
    14 NotIn         findByNameNotIn(Collection<String> nameList);

    四、Spring Boot参数配置

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

    五、创建JPA配置类

     1 package com.slp.config;
     2 
     3 import org.springframework.boot.autoconfigure.domain.EntityScan;
     4 import org.springframework.context.annotation.Configuration;
     5 import org.springframework.core.Ordered;
     6 import org.springframework.core.annotation.Order;
     7 import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
     8 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
     9 import org.springframework.transaction.annotation.EnableTransactionManagement;
    10 
    11 /**
    12  * Created by sangliping on 2017/8/18.
    13  * @EnableTransactionManagement启用了JPA的事务管理
    14  * @EnableJpaRepositories启用了JPA资源库并指定了定义的接口资源库的位置
    15  * @EntityScan指定了定义实体的位置
    16  */
    17 @Order(Ordered.HIGHEST_PRECEDENCE)
    18 @Configuration
    19 @EnableTransactionManagement(proxyTargetClass = true)
    20 @EnableJpaRepositories(basePackages = "com.slp.repository")
    21 @EntityScan(basePackages = "com.slp.entity")
    22 public class JpaConfiguration {
    23 
    24     PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(){
    25         return new PersistenceExceptionTranslationPostProcessor();
    26     }
    27 }

    六、测试准备

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

    1 <dependency>
    2     <groupId>org.springframework.boot</groupId>
    3     <artifactId>spring-boot-starter-test</artifactId>
    4     <scope>test</scope>
    5 </dependency>

    2、编写测试JPA配置类

     1 package com.slp;
     2 
     3 /**
     4  * Created by sangliping on 2017/8/18.
     5  */
     6 import org.springframework.context.annotation.Bean;
     7 import org.springframework.context.annotation.Configuration;
     8 import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
     9 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    10 import org.springframework.jdbc.datasource.DriverManagerDataSource;
    11 import org.springframework.orm.jpa.JpaTransactionManager;
    12 import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    13 import org.springframework.orm.jpa.vendor.Database;
    14 import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
    15 import org.springframework.transaction.PlatformTransactionManager;
    16 import org.springframework.transaction.support.TransactionTemplate;
    17 
    18 import javax.sql.DataSource;
    19 import java.util.Properties;
    20 
    21 
    22 @Configuration
    23 @EnableJpaRepositories(basePackages = "com.slp.repository")
    24 public class JpaConfiguration {
    25 
    26     @Bean
    27     PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
    28         return new PersistenceExceptionTranslationPostProcessor();
    29     }
    30 
    31     @Bean
    32     public DataSource dataSource() {
    33         DriverManagerDataSource dataSource = new DriverManagerDataSource();
    34         dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    35         dataSource.setUrl("jdbc:mysql://localhost:3306/dev?characterEncoding=utf8");
    36         dataSource.setUsername("root");
    37         dataSource.setPassword("123456");
    38 
    39         return dataSource;
    40     }
    41 
    42     @Bean
    43     public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    44         LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    45         entityManagerFactoryBean.setDataSource(dataSource());
    46         entityManagerFactoryBean.setPackagesToScan("com.slp.entity");
    47         entityManagerFactoryBean.setJpaProperties(buildHibernateProperties());
    48         entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter() {{
    49             setDatabase(Database.MYSQL);
    50         }});
    51         return entityManagerFactoryBean;
    52     }
    53 
    54     protected Properties buildHibernateProperties() {
    55         Properties hibernateProperties = new Properties();
    56 
    57         hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
    58         hibernateProperties.setProperty("hibernate.show_sql", "true");
    59         hibernateProperties.setProperty("hibernate.use_sql_comments", "false");
    60         hibernateProperties.setProperty("hibernate.format_sql", "true");
    61         hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
    62         hibernateProperties.setProperty("hibernate.generate_statistics", "false");
    63         hibernateProperties.setProperty("javax.persistence.validation.mode", "none");
    64         hibernateProperties.setProperty(" spring.jpa.hibernate.ddl-auto", "update");
    65         //Audit History flags
    66         hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", "true");
    67         hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", "true");
    68 
    69         return hibernateProperties;
    70     }
    71 
    72     @Bean
    73     public PlatformTransactionManager transactionManager() {
    74         return new JpaTransactionManager();
    75     }
    76 
    77     @Bean
    78     public TransactionTemplate transactionTemplate() {
    79         return new TransactionTemplate(transactionManager());
    80     }
    81 
    82 }

    3、编写测试类

     1 package com.slp;
     2 import com.slp.entity.Department;
     3 import com.slp.entity.Role;
     4 import com.slp.entity.User;
     5 import com.slp.repository.DepartmentRepository;
     6 import com.slp.repository.RoleRepository;
     7 import com.slp.repository.UserRepository;
     8 import org.junit.Before;
     9 import org.junit.Test;
    10 import org.junit.runner.RunWith;
    11 import org.slf4j.Logger;
    12 import org.slf4j.LoggerFactory;
    13 import org.springframework.beans.factory.annotation.Autowired;
    14 import org.springframework.data.domain.Page;
    15 import org.springframework.data.domain.PageRequest;
    16 import org.springframework.data.domain.Pageable;
    17 import org.springframework.data.domain.Sort;
    18 import org.springframework.test.context.ContextConfiguration;
    19 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    20 import org.springframework.util.Assert;
    21 
    22 import java.util.*;
    23 
    24 @RunWith(SpringJUnit4ClassRunner.class)
    25 @ContextConfiguration(classes = {JpaConfiguration.class})
    26 public class MySqlTest {
    27     private static Logger logger = LoggerFactory.getLogger(MySqlTest.class);
    28 
    29     @Autowired
    30     UserRepository userRepository;
    31     @Autowired
    32     DepartmentRepository departmentRepository;
    33     @Autowired
    34     RoleRepository roleRepository;
    35 
    36     @Before
    37     public void initData(){
    38         userRepository.deleteAll();
    39         roleRepository.deleteAll();
    40         departmentRepository.deleteAll();
    41 
    42         Department department = new Department();
    43         department.setName("开发部");
    44         departmentRepository.save(department);
    45         Assert.notNull(department.getId());
    46 
    47         Role role = new Role();
    48         role.setName("slp");
    49         roleRepository.save(role);
    50         Assert.notNull(role.getId());
    51 
    52         User user = new User();
    53         user.setName("user");
    54         user.setCreatedate(new Date());
    55         user.setDeparment(department);
    56 
    57         List<Role> roles = roleRepository.findAll();
    58         Assert.notNull(roles);
    59         user.setRoles(roles);
    60 
    61         userRepository.save(user);
    62         Assert.notNull(user.getId());
    63     }
    64 
    65     @Test
    66     public void findPage(){
    67         Pageable pageable = new PageRequest(0, 10, new Sort(Sort.Direction.ASC, "id"));
    68         Page<User> page = userRepository.findAll(pageable);
    69         Assert.notNull(page);
    70         for(User user : page.getContent()) {
    71             logger.info("====user==== user name:{}, department name:{}, role name:{}",
    72                     user.getName(), user.getDeparment().getName(), user.getRoles().get(0).getName());
    73         }
    74     }
    75 
    76 }

    注意:

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

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

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

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

  • 相关阅读:
    国防科学技术大学第忘记叫啥杯了
    2015 湘潭大学程序设计比赛(Internet)--D题-最小的数 2015-05-13 20:55 51人阅读 评论(0) 收藏
    ACM的探索之Everything is Generated In Equal Probability! 后序补充丫!
    线段树进阶之模板观见
    《地狱是上帝不在的地方》
    《E=MC2或一个思想的故事》
    画图软件gliffy
    线段树进阶之递归实现
    party lamps(dfs优化+规律枚举)
    滑雪(dfs+dp)
  • 原文地址:https://www.cnblogs.com/dream-to-pku/p/7389882.html
Copyright © 2020-2023  润新知