spring boot整合hibernate,druid 连接 postgresql

x33g5p2x  于2021-12-24 转载在 其他  
字(11.6k)|赞(0)|评价(0)|浏览(605)

参考文章:spring boot整合hibernate 连接 Oracle

概述--Hibernate与JPA

  JPA,Java Persistence Api,中文译名为:Java持久层Api。是一个基于ORM(或叫O/R mapping ,对象关系映射)的标准规范,在这个规范中,JPA只定义标准规则,不提供实现。目前,JPA的主要实现有Hibernate,EclipseLink,OpenJPA等。

  由于Hibernate在数据访问解决技术领域的霸主地位,所以JPA标准基本由Hibernate主导。

Pom依赖结构

  1. <dependency>
  2.   <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-jpa</artifactId>
  4. </dependency>
  5. <!--阿里druid数据库链接依赖-->
  6. <dependency>
  7. <groupId>com.alibaba</groupId>
  8. <artifactId>druid-spring-boot-starter</artifactId>
  9. <version>1.1.9</version>
  10. </dependency>
  11. <!--事务管理--原子性,一致性,隔离性,持久性-->
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-jdbc</artifactId>
  15. </dependency>
  16. <!--使用mysql时引入-->
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. </dependency>
  21. <!--使用postgresql时引入-->
  22. <dependency>
  23. <groupId>org.postgresql</groupId>
  24. <artifactId>postgresql</artifactId>
  25. </dependency>

application.yml配置

  1. # postgresql 环境配置
  2. server:
  3. port: 18005
  4. max-http-header-size: 8192
  5. logging:
  6. level:
  7. root: info
  8. spring:
  9. datasource:
  10. url: jdbc:postgresql://10.101.15.59:5432/postgres
  11. username: root
  12. password: 123abc
  13. driverClassName: org.postgresql.Driver
  14. platform: postgres
  15. type: com.alibaba.druid.pool.DruidDataSource
  16. # type: org.apache.commons.dbcp2.BasicDataSource
  17. initialization-mode: always
  18. # ============================== druid ============================== #
  19. druid:
  20. #最大活跃数
  21. maxActive: 20
  22. #初始化数量
  23. initialSize: 1
  24. #最大连接等待超时时间
  25. maxWait: 60000
  26. #打开PSCache,并且指定每个连接PSCache的大小
  27. poolPreparedStatements: true
  28. maxPoolPreparedStatementPerConnectionSize: 20
  29. #通过connectionProperties属性来打开mergeSql功能;慢SQL记录
  30. #connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
  31. minIdle: 1
  32. timeBetweenEvictionRunsMillis: 60000
  33. minEvictableIdleTimeMillis: 300000
  34. validationQuery: select 1 from dual
  35. testWhileIdle: true
  36. testOnBorrow: false
  37. testOnReturn: false
  38. #配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
  39. filters: stat, wall, log4j
  40. # ============================= spring jpa 配置 ============================= #
  41. jpa:
  42. show_sql: true
  43. database-platform: org.hibernate.dialect.PostgreSQL9Dialect
  44. # database-platform: cn.luutqf.springboot.dialect.JsonbPostgresDialect
  45. hibernate:
  46. ddl-auto: update # none: 关闭hibernate的自动创建表结构的机制
  47. properties:
  48. hibernate:
  49. dialect: org.hibernate.dialect.PostgreSQLDialect
  50. hbm2ddl.auto: update
  51. jdbc.lob.non_contextual_creation: true
  52. format_sql: true
  53. temp:
  54. # 兼容SpringBoot2.X, 关闭 Hibernate尝试验证PostgreSQL的CLOB特性
  55. use_jdbc_metadata_defaults: false

工程目录结构

DataSource配置文件

  1. package org.fiend.config;
  2. import com.alibaba.druid.support.http.StatViewServlet;
  3. import com.alibaba.druid.support.http.WebStatFilter;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import org.springframework.boot.context.properties.ConfigurationProperties;
  6. import org.springframework.boot.jdbc.DataSourceBuilder;
  7. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  8. import org.springframework.boot.web.servlet.ServletRegistrationBean;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import org.springframework.context.annotation.Primary;
  12. import javax.sql.DataSource;
  13. /**
  14. * postgresql data source config
  15. * @author fiend 2018/12/5
  16. */
  17. @Configuration
  18. public class DataSourceConfig {
  19. // @Primary
  20. @Bean(name="dataSource")
  21. @ConfigurationProperties(prefix="spring.datasource")
  22. public DataSource dataSource() {
  23. return DataSourceBuilder.create().type(dataSourceType).build();
  24. }
  25. @Value("${spring.datasource.type}")
  26. private Class<? extends DataSource> dataSourceType;
  27. /**
  28. * 配置监控服务器
  29. * @return 返回监控注册的servlet对象
  30. */
  31. @Bean
  32. @SuppressWarnings("unchecked")
  33. public ServletRegistrationBean statViewServlet() {
  34. ServletRegistrationBean servletRegistrationBean =
  35. new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
  36. // 添加IP白名单
  37. servletRegistrationBean.addInitParameter("allow", "192.168.25.125,127.0.0.1");
  38. // 添加IP黑名单,当白名单和黑名单重复时,黑名单优先级更高
  39. servletRegistrationBean.addInitParameter("deny", "192.168.25.123");
  40. // 添加控制台管理用户
  41. servletRegistrationBean.addInitParameter("loginUsername", "druid");
  42. servletRegistrationBean.addInitParameter("loginPassword", "123456");
  43. // 是否能够重置数据
  44. servletRegistrationBean.addInitParameter("resetEnable", "false");
  45. return servletRegistrationBean;
  46. }
  47. /**
  48. * 配置服务过滤器
  49. * @return 返回过滤器配置对象
  50. */
  51. @Bean
  52. @SuppressWarnings("unchecked")
  53. public FilterRegistrationBean statFilter() {
  54. FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(new WebStatFilter());
  55. // 添加过滤规则
  56. filterRegistrationBean.addUrlPatterns("/*");
  57. // 忽略过滤格式
  58. filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*,");
  59. return filterRegistrationBean;
  60. }
  61. }

Entity文件

  1. package org.fiend.entity;
  2. import javax.persistence.*;
  3. import java.io.Serializable;
  4. /**
  5. * @author fiend 2018/12/5
  6. */
  7. @Entity
  8. @Table(catalog="public", name="user")
  9. public class User implements Serializable { //序列化在Jpa需要
  10. // @Id是用来标识主键的,而@GeneratedValue则是用来指定主键策略的
  11. @Id
  12. @GeneratedValue
  13. private String name;
  14. // @Column(name = "count", nullable = false)
  15. private Integer count;
  16. public String getName() {
  17. return name;
  18. }
  19. public void setName(String name) {
  20. this.name = name;
  21. }
  22. public Integer getCount() {
  23. return count;
  24. }
  25. public void setCount(Integer count) {
  26. this.count = count;
  27. }
  28. }

Repository文件

  1. package org.fiend.repository;
  2. import org.fiend.entity.User;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import org.springframework.data.jpa.repository.Modifying;
  5. import org.springframework.data.jpa.repository.Query;
  6. import org.springframework.data.repository.query.Param;
  7. import org.springframework.stereotype.Repository;
  8. import javax.transaction.Transactional;
  9. import java.util.LinkedHashMap;
  10. import java.util.List;
  11. /**
  12. * @author langpf 2018/12/10
  13. */
  14. @Repository
  15. public interface UserRepository extends JpaRepository<User, String> {
  16. /**
  17. * 进行数据库操作, 可以通过自定义HQL来完成符合个性的其他操作
  18. * 通过@Query注解, 完成了HQL的书写, 其中“:name”与下方的@Param注解中参数保持一致。
  19. * HQL可使用Hibernate的SQL生成和缓存策略
  20. * HQL中一些关键字如 SELECT, FROM 和 WHERE等, 是不区分大小写的, 但是一些属性如表名和列名区分大小写
  21. */
  22. @Query(value = "SELECT u FROM User u WHERE name=:name")
  23. User findName(@Param("name") String name);
  24. /**
  25. * 使用SQL语句, nativeQuery为true代表使用SQL语言
  26. * 建议尽可能的使用HQL语句, 以避免数据库关于可移植性的麻烦, 且HQL可使用Hibernate的SQL生成和缓存策略。
  27. */
  28. @Query(value = "insert into User value(?,?,?)", nativeQuery = true)
  29. @Transactional
  30. @Modifying
  31. int countUserBy(@Param("id") Integer id, @Param("name") String name,
  32. @Param("password") String password);
  33. /**
  34. * 根据用户名查询
  35. */
  36. @Query("select t from User t where t.name = :name")
  37. User findByUserName(@Param("name") String name);
  38. /**
  39. * 查询全部
  40. */
  41. @Query("select t from User t")
  42. List<User> find();
  43. /**
  44. * 删除, 必须加入@Modifying和@Transactional
  45. */
  46. @Modifying
  47. @Transactional
  48. @Query("delete from User u where u.id=:id")
  49. int deleteUserById(@Param("id") Integer id);
  50. @Modifying
  51. @Transactional
  52. @Query("update User u set u.name = :name where u.id=:id")
  53. int queryUserById(@Param("id") Integer id, @Param("name") String name);
  54. /* =========================== 分页查询等 =========================== */
  55. /**
  56. * 根据表名, 字段, 参数查询, 拼接sql语句
  57. * @param  tableName 表名
  58. * @param filed 字段名
  59. * @param o 字段参数
  60. */
  61. List<User> findByHql(String tableName, String filed, Object o);
  62. Object findObjiectByHql(String tableName, String filed, Object o);
  63. /**
  64. * 多个字段的查询
  65. * @param tableName 表名
  66. * @param map 将你的字段传入map中
  67. */
  68. List<User> findByMoreFiled(String tableName, LinkedHashMap<String, Object> map);
  69. /**
  70. * 多字段查询分页
  71. * @param tableName 表名
  72. * @param map 以map存储key,value
  73. * @param star 第几页
  74. * @param pageNumber 一个页面的条数
  75. */
  76. List<User> findByMoreFiledPage(String tableName, LinkedHashMap<String, Object> map,
  77. int star, int pageNumber);
  78. /**
  79. * 一个字段的分页
  80. * @param  tableName 表名
  81. * @param filed 字段名
  82. * @param o 字段参数
  83. * @param start 第几页
  84. * @param pageNumber 一个页面多少条数据
  85. */
  86. List<User> findPages(String tableName, String filed, Object o, int start, int pageNumber);
  87. /**
  88. * 根据传入的map遍历key,value拼接字符串, 以id为条件更新
  89. * @param tableName 表名
  90. * @param map 传入参数放入map中
  91. */
  92. Integer updateMoreFiled(String tableName, LinkedHashMap<String, Object> map,
  93. Long id);
  94. /**
  95. * 根据条件查询总条数返回object类型
  96. * @param tableName  表名
  97. * @param map 传入参数放入map中
  98. */
  99. Object findCount(String tableName, LinkedHashMap<String, Object> map);
  100. }

Service文件

  1. package org.fiend.service;
  2. import com.alibaba.fastjson.JSONObject;
  3. import org.fiend.base.AbstractService;
  4. import org.fiend.entity.User;
  5. import org.fiend.repository.UserRepository;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.stereotype.Service;
  10. import java.util.List;
  11. /**
  12. * @author Administrator
  13. */
  14. @Service
  15. public class HomeService extends AbstractService {
  16. Logger log = LoggerFactory.getLogger(getClass());
  17. @Autowired
  18. private UserRepository userRepository;
  19. public JSONObject getUserList() {
  20. JSONObject json = new JSONObject();
  21. List<User> userList = userRepository.find();
  22. json.put("userList", userList);
  23. return json;
  24. }
  25. public JSONObject getUserList1() {
  26. JSONObject json = new JSONObject();
  27. List<User> userList = userRepository.findAll();
  28. json.put("userList", userList);
  29. return json;
  30. }
  31. public List<User> find() {
  32. List<User> list = null;
  33. try {
  34. list = userRepository.find();
  35. } catch (Exception e) {
  36. }
  37. return list;
  38. }
  39. public String deleteUserById(Integer id){
  40. int a = userRepository.deleteUserById(id);
  41. return "chenggong";
  42. }
  43. public String queryUserById(Integer id ,String name){
  44. int a = userRepository.queryUserById(id,name);
  45. return "成功";
  46. }
  47. public String countUserBy(Integer id ,String name ,String password){
  48. int a = userRepository.countUserBy(id,name,password);
  49. return "成功";
  50. }
  51. }

Controller文件

  1. package org.fiend.controller;
  2. import com.alibaba.fastjson.JSONObject;
  3. import org.fiend.base.AbstractController;
  4. import org.fiend.service.HomeService;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.ResponseBody;
  10. import javax.inject.Inject;
  11. import javax.inject.Named;
  12. /**
  13. * @author Administrator
  14. */
  15. @Controller
  16. @RequestMapping(value = "home")
  17. public class HomeController extends AbstractController<HomeService> {
  18. Logger log = LoggerFactory.getLogger(this.getClass());
  19. @Override
  20. @Inject
  21. @Named("homeService")
  22. protected void setService(HomeService service) {
  23. this.service = service;
  24. }
  25. @RequestMapping(value = "getUserList")
  26. @ResponseBody
  27. public JSONObject getUserList() {
  28. return service.getUserList();
  29. }
  30. @RequestMapping(value = "getUserList1")
  31. @ResponseBody
  32. public JSONObject getUserList1() {
  33. return service.getUserList1();
  34. }
  35. }

运行结果

附录

Repository文件注解说明:

  1. @modifying
  2. 1)可以通过自定义的JPQL完成UPDATEDELETE操作。 注意:JPQL不支持使用INSERT
  3. 2)在@Query注解中编写JPQL语句,但必须使用@Modifying修饰,以通知SpringData这是一个UPDATE DELETE操作
  4. 3UPDATE DELETE操作需要使用事务,此时需要定义Service层,在Service层的方法上添加事务操作;
  5. 4)默认情况下,SpringData的每个方法上有事务,但都是一个只读事务。
  6. @Transactional
  7. A. 一个功能是否要事务,必须纳入设计、编码考虑。不能仅仅完成了基本功能就ok
  8. B. 如果加了事务,必须做好开发环境测试(测试环境也尽量触发异常、测试回滚),确保事务生效。
  9. C. 以下列了事务使用过程的注意事项,请大家留意。
  10. 1.不要在接口上声明@Transactional ,而要在具体类的方法上使用 @Transactional 注解,否则注解可能无效。
  11. 2.不要图省事,将@Transactional放置在类级的声明中,放在类声明,会使得所有方法都有事务。
  12. @Transactional应该放在方法级别,不需要使用事务的方法,就不要放置事务,比如查询方法。
  13. 否则对性能是有影响的。
  14. 3.使用了@Transactional的方法,对同一个类里面的方法调用,
  15. @Transactional无效。比如有一个类Test,它的一个方法AA再调用Test本类的方法B
  16. (不管B是否public还是private),但A没有声明注解事务,而B有。
  17. 则外部调用A之后,B的事务是不会起作用的。(经常在这里出错)
  18. 4.使用了@Transactional的方法,只能是public
  19. @Transactional注解的方法都是被外部其他类调用才有效,故只能是public
  20. 道理和上面的有关联。故在protectedprivate 或者 package-visible 的方法上使用 @Transactional
  21. 注解,它也不会报错,但事务无效。
  22. 5.经过在ICORE-CLAIM中测试,效果如下:
  23. A.抛出受查异常XXXException,事务会回滚。
  24. B.抛出运行时异常NullPointerException,事务会回滚。
  25. C.Quartz中,execute直接调用加了@Transactional方法,可以回滚;
  26. 间接调用,不会回滚。(即上文3点提到的)
  27. D.异步任务中,execute直接调用加了@Transactional方法,可以回滚;
  28. 间接调用,不会回滚。(即上文3点提到的)
  29. E.在action中加上@Transactional,不会回滚。切记不要在action中加上事务。
  30. F.在service中加上@Transactional,如果是action直接调该方法,会回滚,如果是间接调,不会回滚。
  31. (即上文3提到的)
  32. G.在service中的private加上@Transactional,事务不会回滚。

相关文章