当前位置:   article > 正文

SpringBoot集成Hibernate_springboot hibernate

springboot hibernate

Hibernate是什么?

Hibernate与MyBatis都是流行的持久层开发框架,只不过Hibernate是全自动ORM框架,不需要关心sql编写。

Hibernate 是一个高性能的对象/关系映射(ORM)持久化存储和查询的服务,不仅负责从Java类到数据库表的映射 (还包括从Java数据类型到SQL数据类型的映射),还提供了面向对象的数据查询检索机制,从而极大地缩短了手动处理SQL和JDBC上的开发时间。 同时,Hibernate还实现了JPA规范,在SpringBoot中,JPA的默认实现就是使用的Hibernate。

JPA和Hibernate?

JPA

JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。

可以通过注解或者XML描述【对象-关系表】之间的映射关系,并将实体对象持久化到数据库中。

JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的。所以底层需要某种实现,而Hibernate就是实现了JPA接口的ORM框架。

Hibernate

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架。 Hibernate可以自动生成SQL语句、自动执行,从而使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

实际上,JPA规范制定过程中就是借鉴了Hibernate等这些开源的持久框架,也就是说Hibernate的出现比JPA还要早些。

在Hibernate中使用的注解就是JPA注解,Hibernate实现了JPA规范。

Spring Data JPA

spirng data jpa是spring提供的一套简化JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等。

Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。

SpringData

Spring Data 是持久层通用解决方案,支持 关系型数据库 Oracle、MySQL、非关系型数据库NoSQL、Map-Reduce 框架、云基础数据服务 、搜索服务。

Spring Data是一个开源框架而Spring Data JPA是这个框架的模块。

一、新建SpringBoot项目

在pom.xml中引入maven依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-jpa</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>mysql</groupId>
  7. <artifactId>mysql-connector-java</artifactId>
  8. <version>8.0.17</version>
  9. <scope>runtime</scope>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.alibaba</groupId>
  13. <artifactId>druid</artifactId>
  14. <version>1.1.2</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.projectlombok</groupId>
  18. <artifactId>lombok</artifactId>
  19. <version>1.18.10</version>
  20. </dependency>

创建数据库

  1. create table books
  2. (
  3. book_id int(5) primary key auto_increment,
  4. title varchar(200),
  5. category varchar(100)
  6. )
  7. INSERT INTO `books` (`book_id`, `title`, `category`) VALUES
  8. (1, '123', 'qwe'),
  9. (2, '456', 'asd'),
  10. (3, '789', 'zxc');

配置文件application.yml

  1. spring:
  2. jpa:
  3. properties:
  4. hibernate:
  5. dialect: org.hibernate.dialect.MySQLDialect
  6. new_generator_mappings: false
  7. format_sql: true
  8. datasource:
  9. url: jdbc:mysql://localhost:3306/ss?serverTimezone=UTC&useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8
  10. username: root
  11. password: 123qwe

创建如图以下包

在config下编写数据源配置

  1. @Configuration
  2. @EnableTransactionManagement(order = 2)
  3. public class DataSourceConfig {
  4. @Resource
  5. private DruidProperties druidProperties;
  6. /**
  7. * 单数据源连接池配置
  8. */
  9. @Bean
  10. public DruidDataSource singleDatasource() {
  11. DruidDataSource dataSource = new DruidDataSource();
  12. druidProperties.config(dataSource);
  13. return dataSource;
  14. }
  15. }
  1. @Component
  2. @ConfigurationProperties(prefix = "spring.datasource")
  3. public class DruidProperties {
  4. private String url;
  5. private String username;
  6. private String password;
  7. private String driverClassName = "com.mysql.cj.jdbc.Driver";
  8. private Integer initialSize = 10;
  9. private Integer minIdle = 3;
  10. private Integer maxActive = 60;
  11. private Integer maxWait = 60000;
  12. private Boolean removeAbandoned = true;
  13. private Integer removeAbandonedTimeout = 180;
  14. private Integer timeBetweenEvictionRunsMillis = 60000;
  15. private Integer minEvictableIdleTimeMillis = 300000;
  16. private String validationQuery = "SELECT 'x'";
  17. private Boolean testWhileIdle = true;
  18. private Boolean testOnBorrow = false;
  19. private Boolean testOnReturn = false;
  20. private Boolean poolPreparedStatements = true;
  21. private Integer maxPoolPreparedStatementPerConnectionSize = 50;
  22. private String filters = "stat";
  23. public void config(DruidDataSource dataSource) {
  24. dataSource.setDbType(JdbcConstants.MYSQL);
  25. dataSource.setUrl(url);
  26. dataSource.setUsername(username);
  27. dataSource.setPassword(password);
  28. dataSource.setDriverClassName(driverClassName);
  29. // 定义初始连接数
  30. dataSource.setInitialSize(initialSize);
  31. // 最小空闲
  32. dataSource.setMinIdle(minIdle);
  33. // 定义最大连接数
  34. dataSource.setMaxActive(maxActive);
  35. // 获取连接等待超时的时间
  36. dataSource.setMaxWait(maxWait);
  37. // 超过时间限制是否回收
  38. dataSource.setRemoveAbandoned(removeAbandoned);
  39. // 超过时间限制多长
  40. dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout);
  41. // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
  42. dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
  43. // 配置一个连接在池中最小生存的时间,单位是毫秒
  44. dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
  45. // 用来检测连接是否有效的sql,要求是一个查询语句
  46. dataSource.setValidationQuery(validationQuery);
  47. // 申请连接的时候检测
  48. dataSource.setTestWhileIdle(testWhileIdle);
  49. // 申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能
  50. dataSource.setTestOnBorrow(testOnBorrow);
  51. // 归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能
  52. dataSource.setTestOnReturn(testOnReturn);
  53. // 打开PSCache,并且指定每个连接上PSCache的大小
  54. dataSource.setPoolPreparedStatements(poolPreparedStatements);
  55. dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
  56. // 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
  57. // 监控统计用的filter:stat
  58. // 日志用的filter:log4j
  59. // 防御SQL注入的filter:wall
  60. try {
  61. dataSource.setFilters(filters);
  62. } catch (SQLException e) {
  63. e.printStackTrace();
  64. }
  65. }
  66. public String getUrl() {
  67. return url;
  68. }
  69. public void setUrl(String url) {
  70. this.url = url;
  71. }
  72. public String getUsername() {
  73. return username;
  74. }
  75. public void setUsername(String username) {
  76. this.username = username;
  77. }
  78. public String getPassword() {
  79. return password;
  80. }
  81. public void setPassword(String password) {
  82. this.password = password;
  83. }
  84. public String getDriverClassName() {
  85. return driverClassName;
  86. }
  87. public void setDriverClassName(String driverClassName) {
  88. this.driverClassName = driverClassName;
  89. }
  90. public Integer getInitialSize() {
  91. return initialSize;
  92. }
  93. public void setInitialSize(Integer initialSize) {
  94. this.initialSize = initialSize;
  95. }
  96. public Integer getMinIdle() {
  97. return minIdle;
  98. }
  99. public void setMinIdle(Integer minIdle) {
  100. this.minIdle = minIdle;
  101. }
  102. public Integer getMaxActive() {
  103. return maxActive;
  104. }
  105. public void setMaxActive(Integer maxActive) {
  106. this.maxActive = maxActive;
  107. }
  108. public Integer getMaxWait() {
  109. return maxWait;
  110. }
  111. public void setMaxWait(Integer maxWait) {
  112. this.maxWait = maxWait;
  113. }
  114. public Integer getTimeBetweenEvictionRunsMillis() {
  115. return timeBetweenEvictionRunsMillis;
  116. }
  117. public void setTimeBetweenEvictionRunsMillis(Integer timeBetweenEvictionRunsMillis) {
  118. this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
  119. }
  120. public Integer getMinEvictableIdleTimeMillis() {
  121. return minEvictableIdleTimeMillis;
  122. }
  123. public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) {
  124. this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
  125. }
  126. public String getValidationQuery() {
  127. return validationQuery;
  128. }
  129. public void setValidationQuery(String validationQuery) {
  130. this.validationQuery = validationQuery;
  131. }
  132. public Boolean getTestWhileIdle() {
  133. return testWhileIdle;
  134. }
  135. public void setTestWhileIdle(Boolean testWhileIdle) {
  136. this.testWhileIdle = testWhileIdle;
  137. }
  138. public Boolean getTestOnBorrow() {
  139. return testOnBorrow;
  140. }
  141. public void setTestOnBorrow(Boolean testOnBorrow) {
  142. this.testOnBorrow = testOnBorrow;
  143. }
  144. public Boolean getTestOnReturn() {
  145. return testOnReturn;
  146. }
  147. public void setTestOnReturn(Boolean testOnReturn) {
  148. this.testOnReturn = testOnReturn;
  149. }
  150. public Boolean getPoolPreparedStatements() {
  151. return poolPreparedStatements;
  152. }
  153. public void setPoolPreparedStatements(Boolean poolPreparedStatements) {
  154. this.poolPreparedStatements = poolPreparedStatements;
  155. }
  156. public Integer getMaxPoolPreparedStatementPerConnectionSize() {
  157. return maxPoolPreparedStatementPerConnectionSize;
  158. }
  159. public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) {
  160. this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
  161. }
  162. public String getFilters() {
  163. return filters;
  164. }
  165. public void setFilters(String filters) {
  166. this.filters = filters;
  167. }
  168. public Boolean getRemoveAbandoned() {
  169. return removeAbandoned;
  170. }
  171. public void setRemoveAbandoned(Boolean removeAbandoned) {
  172. this.removeAbandoned = removeAbandoned;
  173. }
  174. public Integer getRemoveAbandonedTimeout() {
  175. return removeAbandonedTimeout;
  176. }
  177. public void setRemoveAbandonedTimeout(Integer removeAbandonedTimeout) {
  178. this.removeAbandonedTimeout = removeAbandonedTimeout;
  179. }
  180. }

在entity下创建实体类

  1. @Entity
  2. @Table(name = "books")
  3. @Data
  4. public class Book implements Serializable {
  5. private static final long serialVersionUID = 1L;
  6. @Id
  7. @GeneratedValue(strategy = GenerationType.AUTO)
  8. @Column(name = "book_id")
  9. private int bookId;
  10. @Column(name = "title")
  11. private String title;
  12. @Column(name = "category")
  13. private String category;
  14. }

创建在repository下创建Dao层接口和在impl下创建Dao实现类

  1. public interface BookDao {
  2. List<Book> getAllBooks();
  3. Book getBookById(int bookId);
  4. void addBook(Book book);
  5. void updateBook(Book book);
  6. void deleteBook(int bookId);
  7. boolean bookExists(String title,String category);
  8. }

  1. @Repository
  2. public class IBookDao implements BookDao {
  3. @PersistenceContext
  4. private EntityManager entityManager;
  5. @Override
  6. public List<Book> getAllBooks() {
  7. String sql = "FROM Book as book ORDER BY book.bookId";
  8. return (List<Book>)entityManager.createQuery(sql).getResultList();
  9. }
  10. @Override
  11. public Book getBookById(int bookId) {
  12. return entityManager.find(Book.class,bookId);
  13. }
  14. @Override
  15. public void addBook(Book book) {
  16. entityManager.persist(book);
  17. }
  18. @Override
  19. public void updateBook(Book book) {
  20. Book book1 = getBookById(book.getBookId());
  21. book1.setTitle(book.getTitle());
  22. book1.setCategory(book.getCategory());
  23. entityManager.flush();
  24. entityManager.clear();
  25. }
  26. @Override
  27. public void deleteBook(int bookId) {
  28. entityManager.remove(getBookById(bookId));
  29. }
  30. @Override
  31. public boolean bookExists(String title, String category) {
  32. String sql = "FROM Book as book WHERE book.title=?0 and book.category=?1";
  33. int count = entityManager.createQuery(sql)
  34. .setParameter(0,title)
  35. .setParameter(1,category)
  36. .getResultList().size();
  37. return count > 0;
  38. }
  39. }

创建业务层Service,注入BookDao

  1. @Service
  2. public class BookService {
  3. @Autowired
  4. private BookDao bookDao;
  5. public Book getBookById(int bookId){
  6. Book book= bookDao.getBookById(bookId);
  7. return book;
  8. }
  9. public List<Book> getAllBooks(){
  10. return bookDao.getAllBooks();
  11. }
  12. public synchronized boolean addBook(Book book){
  13. if(bookDao.bookExists(book.getTitle(),book.getCategory())){
  14. return false;
  15. }else {
  16. bookDao.addBook(book);
  17. return true;
  18. }
  19. }
  20. public void updateBook(Book book){
  21. bookDao.updateBook(book);
  22. }
  23. public void deleteBook(int bookId){
  24. bookDao.deleteBook(bookId);
  25. }
  26. }

测试类 编写测试代码

再上图中测试类下编写以下代码

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. @Transactional
  4. public class HibernateApplicationTests {
  5. @Autowired
  6. private BookService bookService;
  7. @Test
  8. @Rollback(false)
  9. public void contextLoads() {
  10. Book book = bookService.getBookById(1);
  11. assertThat(book.getTitle(),is("123"));
  12. List<Book> list = bookService.getAllBooks();
  13. assertThat(list,notNullValue());
  14. assertThat(list.size(), is(3));
  15. boolean flag = bookService.addBook(book);
  16. assertThat(flag, is(false));
  17. book.setTitle("012");
  18. bookService.updateBook(book);
  19. Book book1 = bookService.getBookById(1);
  20. System.out.println(book1);
  21. assertThat(book1.getTitle(), is("012"));
  22. bookService.deleteBook(1);
  23. Book article2 = bookService.getBookById(1);
  24. assertThat(article2, nullValue());
  25. }
  26. }

依次执行上面测试代码中的增删改查。根据数据库和控制台输出查看结果是否测试通过。简单的集成Hibernate已经完成。更多可以了解JPA复杂语句查询以及根据实体类自动创建数据库。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/815314
推荐阅读
相关标签
  

闽ICP备14008679号