Spring Boot 学习笔记 5 : JPA

  1. 在 pom.xml 文件中添加依赖:

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

    由于使用 HikariCP 连接池,添加下面依赖:

    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
    </dependency>
  2. 在 application.yml 文件中添加配置:

    spring:
        datasource:
            driver-class-name: com.mysql.jdbc.Driver
            url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
            username: root
            password:
            type: com.zaxxer.hikari.HikariDataSource
        jpa:
            database: mysql
            database-platform: MYSQL
            show-sql: true
            format-sql: true
            hibernate:
                ddl-auto: update
                naming:
                    strategy: org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
  3. 编写配置类:

    import com.mj.wcs.domain.User;
    import com.mj.wcs.repository.UserRepository;
    import org.springframework.boot.autoconfigure.domain.EntityScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    /**
     * @author smileorsilence
     * @date 2018/03/28
     */
    @Configuration
    @EntityScan(basePackageClasses = User.class)
    @EnableJpaRepositories(basePackageClasses = UserRepository.class)
    @EnableTransactionManagement
    public class HibernateJpaConfiguration {
    
    }
  4. 编写实体类:

    import com.fasterxml.jackson.annotation.JsonIgnore;
    import lombok.Data;
    
    import javax.persistence.*;
    import javax.validation.constraints.NotNull;
    import java.io.Serializable;
    
    /**
     * @author smileorsilence
     */
    @Data
    @Entity
    @Table(name = "user")
    public class User implements Serializable {
    
        @Id
        @GeneratedValue
        private Long id;
    
        @NotNull
        @Column(name = "username")
        private String username;
    
        @NotNull
        @JsonIgnore
        @Column(name = "password")
        private String password;
    
        @Column(name = "email", unique = true)
        private String email;
    
    }
  5. 编写Repository类:

    import com.mj.wcs.domain.User;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    import java.util.Optional;
    
    /**
     * @author smileorsilence
     * @date 2018/03/28
     */
    @Repository
    public interface UserRepository extends JpaRepository<User, Long> {
    
        Optional<User> findOneByEmail(String email);
    }
  6. 编写Service类:

    import com.mj.wcs.domain.User;
    import com.mj.wcs.repository.UserRepository;
    import com.mj.wcs.service.util.MD5Util;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.inject.Inject;
    
    /**
     * @author smileorsilence
     * @date 2018/03/28
     */
    @Slf4j
    @Service
    @Transactional
    public class UserService {
    
        @Inject
        private UserRepository userRepository;
    
        public User saveUser() {
            User user = new User();
            user.setUsername("爱他明月好");
            user.setPassword(MD5Util.encodeByMD5("憔悴也相关"));
            user = userRepository.save(user);
            log.info("saveUser, user : {}", user);
            return user;
        }
    
    }
  7. 编写Controller类:

    import com.mj.wcs.domain.User;
    import com.mj.wcs.service.UserService;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.inject.Inject;
    
    /**
     * @author smileorsilence
     * @date 2018/03/28
     */
    @Api("test")
    @Slf4j
    @Controller
    @RequestMapping("/api")
    public class UserController {
    
        @Inject
        private UserService userService;
    
        @ApiOperation(value = "测试saveUser方法")
        @RequestMapping(value = "/user/save", method = RequestMethod.GET)
        @ResponseBody
        public User saveUser() {
            log.info("saveUser");
            return userService.saveUser();
        }
    }
  8. 运行程序,抛出异常:

    2018-03-28 16:47:37.032 ERROR 1744 --- [           main] o.s.boot.SpringApplication               : Application startup failed
    
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
        ... ? common frames omitted
    Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:264) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        ... ? common frames omitted
    Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [MYSQL] as strategy [org.hibernate.dialect.Dialect]
        at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.selectStrategyImplementor(StrategySelectorImpl.java:113) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        ... ? common frames omitted

    定位异常原因是 application.yml 配置文件中 JPA 配置错误:

    spring:
        jpa:
            database-platform: MYSQL

    修改为如下:

    spring:
        jpa:
            database-platform: org.hibernate.dialect.MySQL5InnoDBDialect

    抛出异常:

    2018-03-28 18:10:00.899 ERROR 7904 --- [           main] o.s.boot.SpringApplication               : Application startup failed
    
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
        ... ? common frames omitted
    Caused by: com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: Unknown database 'nmgyj-wcs'
        at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:512) ~[HikariCP-2.5.1.jar:na]
        ... ? common frames omitted
    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'nmgyj-wcs'
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
        ... ? common frames omitted

    定位异常原因是 MySQL 数据库中找不到 nmgyj-wcs 数据库错误:

    创建对应数据库即可。

  9. 使用Postman测试:

    testSaveUser

  10. 编写Junit单元测试:

    import com.mj.wcs.domain.User;
    import com.mj.wcs.repository.UserRepository;
    import com.mj.wcs.service.util.MD5Util;
    import lombok.extern.slf4j.Slf4j;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.inject.Inject;
    
    /**
     * @author smileorsilence
     * @date 2018/03/28
     */
    @Slf4j
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest
    public class UserServiceTest {
    
        @Inject
        private UserRepository userRepository;
    
        @Test
        public void saveUser() throws Exception {
            User user = new User();
            user.setUsername("爱他明月好");
            user.setPassword(MD5Util.encodeByMD5("憔悴也相关"));
            user.setEmail("shakespeare@163.com");
            user = userRepository.save(user);
            log.info("saveUser, user : {}", user);
        }
    
    }

    运行测试方法,抛出异常:

    2018-03-28 19:25:49.669  INFO 8324 --- [           main] com.mj.wcs.service.UserServiceTest       : Started UserServiceTest in 15.072 seconds (JVM running for 16.826)
    Hibernate: 
        select
            next_val as id_val 
        from
            hibernate_sequence for update
    
    Hibernate: 
        update
            hibernate_sequence 
        set
            next_val= ? 
        where
            next_val=?
    Hibernate: 
        insert 
        into
            user
            (email, password, username, id) 
        values
            (?, ?, ?, ?)
    2018-03-28 19:25:50.003  WARN 8324 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1062, SQLState: 23000
    2018-03-28 19:25:50.003 ERROR 8324 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : Duplicate entry '1' for key 'PRIMARY'
    2018-03-28 19:25:50.006  INFO 8324 --- [           main] o.h.e.j.b.internal.AbstractBatchImpl     : HHH000010: On release of batch it still contained JDBC statements
    
    org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
        ... ? more
    Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
        ... ? more
    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'
        ... ? more

    定位异常原因可能是 User 实体类中使用 Lombok 提供的 @Data 注解导致 equals() 方法和 hashCode() 方法重写不正确,使用 IDEA 重新生成即可。

    定位异常原因可能是数据库中 hibernate_sequence 这张表中 next_val 这列的值重复所导致。

    hibernate_sequence

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
springboot学习笔记 spring基础 Spring概述 Spring的简史 xml配置 注解配置 java配置 Spring概述 Spring的模块 核心容器CoreContainer Spring-Core Spring-Beans Spring-Context Spring-Context-Support Spring-Expression AOP Spring-AOP Spring-Aspects Messaging Spring-Messaging WEB Spring-Web Spring-Webmvc Spring-WebSocket Spring-Webmvc-Portlet 数据访问/集成(DataAccess/Intefration) Spring-JDBC Spring-TX Spring-ORM Spring-OXM Spring-JMS Spring的生态 Spring Boot Spring XD Spring Cloud Spring Data Spring Integration Spring Batch Spring Security Spring HATEOAS Spring Social Spring AMQP Spring Mobile Spring for Android Spring Web Flow Spring Web Services Spring LDAP Spring Session Spring项目快速搭建 Maven简介 Maven安装 Maven的pom.xml dependencies dependency 变量定义 编译插件 Spring项目的搭建 Spring Tool Suite https://spring.io/tools/sts/all IntelliJ IDEA NetBeans https://netbeans.org/downloads/ Spring基础配置 依赖注入 声明Bean的注解 @Component组件,没有明确的角色 @Service在业务逻辑层(service层) @Repository在数据访问层(dao层) @Controller在展现层(MVC→SpringMVC) 注入Bean的注解 @Autowired:Spring提供的注解 @Inject:JSR-330提供的注解 @Resource:JSR-250提供的注解 Java配置 @Configuration声明当前类是一个配置类 @Bean注解在方法上,声明当前方法的返回值为一个Bean AOP @Aspect 声明是一个切面 拦截规则@After @Before @Around PointCut JoinPoint Spring常用配置 Bean的Scope Singleton Prototype Request Session GlobalSession SpringEL和资源调用 注入普通字符 注入操作系统属性 注入表达式云算结果 注入其他Bean的属性 注入文件内容 注入网址内容 注入属性文件 Bean的初始化和销毁 Java配置方式 注解方式 Profile @Profile 通过设定jvm的spring.profiles.active参数 web项目设置在Servlet的context parameter中 事件Application Event 自定义事件,集成ApplicationEvent 定义事件监听器,实现ApplicationListener 使用容器发布事件 Spring高级话题 Spring Aware BeanNameAware BeanFactoryAware
### 回答1: 很高兴听到您对Spring Boot 2的学习感兴趣。Spring Boot是一个基于Spring框架的快速开发应用程序的工具,它提供了一种简单的方式来创建和配置Spring应用程序。以下是一些学习Spring Boot 2的笔记: 1. Spring Boot 2的新特性:Spring Boot 2相对于Spring Boot 1.x版本来说,有许多新的特性和改进。例如,它支持Java 9和10,提供了更好的响应式编程支持,以及更好的安全性和监控功能。 2. Spring Boot 2的核心组件:Spring Boot 2的核心组件包括Spring Framework、Spring MVC、Spring Data和Spring Security等。这些组件提供了一系列的功能和工具,使得开发人员可以更加轻松地构建和管理应用程序。 3. Spring Boot 2的配置:Spring Boot 2的配置非常简单,它提供了一种基于注解的方式来配置应用程序。开发人员可以使用@Configuration和@Bean注解来定义配置类和Bean。 4. Spring Boot 2的启动器:Spring Boot 2提供了一系列的启动器,这些启动器可以帮助开发人员快速地集成各种常用的框架和库,例如Spring Data JPASpring Security、Thymeleaf等。 5. Spring Boot 2的测试:Spring Boot 2提供了一系列的测试工具,例如Spring Boot Test、Mockito、JUnit等。这些工具可以帮助开发人员编写高质量的单元测试和集成测试。 希望这些笔记对您学习Spring Boot 2有所帮助。如果您有任何问题或疑问,请随时联系我。 ### 回答2: Spring Boot 是一个非常流行的开源框架,它的目的是使 Spring 应用程序的开发过程更加简单、快速和高效。Spring Boot 2 是 Spring Boot 框架的第二个版本,已经成为了当今业界最流行的 Java 开发框架之一。 Spring Boot 2 的新特性: 1. 支持 JDK 9。Spring Boot 2 已经支持 JDK 9 所带来的新特性和功能。 2. 基于 Reactive Streams 的编程模型。Spring Boot 2 增加了对 Reactive Streams 的支持,可以开发响应式应用程序,从而提高了系统的吞吐量和性能。 3. 异步服务器支持。Spring Boot 2 已经支持多种异步服务器,包括 Netty、Undertow 和 Tomcat。 4. 更全面的 Actuator 组件。Actuator 是 Spring Boot 的监控和管理组件,Spring Boot 2 在 Actuator 组件上增加了更多的指标、健康检查和应用程序信息。 5. 更好的自定义配置。Spring Boot 2 简化了自定义配置的流程,使得用户可以更快速地配置应用程序。 学习 Spring Boot 2 的步骤如下: 1. 掌握 Spring 基础知识。学习 Spring Boot 2 前需要掌握 Spring MVC、Spring Data 等相关的知识。 2. 下载安装 Spring BootSpring Boot 2 可以在官网上下载。 3. 学习 Spring Boot 核心组件。包括 Spring IoC、Spring AOP、Spring MVC 等核心组件。 4. 开发一个 Spring Boot 应用程序。可以从一个简单的 Hello World 开始,逐渐增加功能,学习和理解 Spring Boot 的各种特性和功能。 5. 掌握 Spring Boot 的自动配置。Spring Boot 的自动配置可以大大减少开发人员的工作量,学习和掌握自动配置非常重要。 总之,学习 Spring Boot 2 需要不断地实践和探索,只有通过实际的开发经验才能真正掌握和学会这个框架。 ### 回答3: Spring Boot是一款基于Spring框架的快速应用开发框架。在应用开发的过程中,Spring Boot可以自动配置一个相对完整的Spring应用程序,从而大大减少了开发者的工作量,提高了开发效率。显然,它的学习是很有必要的。 Spring Boot 2.x版本相比于1.x版本在很多方面都进行了升级和改进。在学习的过程中,需要关注的重点在以下几点: 1. 新建Spring Boot项目 Spring Boot提供了Spring Initializr来快速创建新的Spring Boot项目。在构建项目的过程中,我们可以自定义项目的基本信息、项目类型、依赖关系等,可以根据需求灵活选择。 2. Spring Boot自动配置 Spring Boot借助于自动配置功能,可以为开发者免去大量的配置工作。Spring Boot把一些常用的配置提取为Starter,开发者只需要引入这些Starter即可实现自动配置,大大降低了开发成本。 3. Spring Boot集成 Spring Boot集成了众多流行的框架,如MyBatis、HibernateJPA、Thymeleaf等,只需要简单的配置就可以实现对这些框架的集成,使得在开发中更加方便。 4. Spring Boot监控管理 Spring Boot通过Actuator提供了一系列配置和管理服务,可以实现对Spring Boot应用程序的监控和管理。开发者可以通过这些服务来监控应用程序的运行状态、访问量、资源使用情况等。 5. Spring Boot测试 Spring Boot天生适合进行单元测试和集成测试,可以使用JUnit、Mockito、Spring Test等框架进行测试。同样可以利用Spring Boot提供的Test Starter进行自动配置,减少测试的开发成本。 以上就是Spring Boot 2的一些学习笔记,它的结构简洁,代码清晰,便于开发者使用。无疑,Spring Boot 2是一个非常适合作为开发者日常工作的框架。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值