-
在 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>
-
在 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
-
编写配置类:
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 { }
-
编写实体类:
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; }
-
编写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); }
-
编写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; } }
-
编写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(); } }
-
运行程序,抛出异常:
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 数据库错误:
创建对应数据库即可。
-
使用Postman测试:
-
编写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 重新生成即可。