一文教會你如何在SpringBoot項目裡集成Hibernate

2024年2月6日 27点热度 0人点赞

前言

一個老項目中使用了Hibernate,是SpringMVC項目,要把定時任務拆出來,使用SpringBoot集成Hibernate,今天整理下集成的過程。

基礎概念

什麼是Hibernate

Hibernate是一個流行的ORM(對象關系映射)框架,它可以將Java對象映射到數據庫表,從而方便地進行持久化操作。

在Spring Boot項目中,集成Hibernate可以幫助我們更輕松地進行數據庫操作。

Hibernate 的主要功能

1.對象關系映射(ORM):Hibernate可以自動將Java類和對象映射到關系數據庫中的表和行。

2.透明持久性:Hibernate可以自動管理對象的生命周期,並將其持久化到數據庫中,從而使開發人員可以專註於業務邏輯,而不必擔心對象的狀態管理。

3.查詢語言:Hibernate提供了一種基於面向對象的查詢語言(HQL),使開發人員可以使用面向對象的方式來查詢和操作數據庫。

4.緩存管理:Hibernate提供了一個高效的緩存管理機制,可以提高應用程序的性能。

5.事務管理:Hibernate可以自動管理數據庫事務,從而確保數據的完整性和一致性。

使用Hibernate的好處

1.簡化數據訪問層:Hibernate簡化了數據訪問層的開發,開發人員隻需要關註業務邏輯,而不必編寫繁瑣的SQL語句。

2.提高開發效率:Hibernate可以自動生成數據庫表和列,省去了手動創建和維護數據庫表的麻煩。此外,Hibernate還提供了一種基於對象的查詢語言,使得查詢和操作數據變得更加簡單。

3.提高可維護性:Hibernate使得應用程序的代碼更加清晰、簡單易懂,使得應用程序更加易於維護。

4.支持多種數據庫:Hibernate可以很方便地支持多種關系數據庫,包括MySQL、Oracle、Microsoft SQL Server等。

5.提高性能:Hibernate提供了一個緩存機制,可以提高應用程序的性能。此外,Hibernate還支持批量處理和延遲加載等優化技術,可以進一步提高應用程序的性能。

6.支持事務管理:Hibernate可以自動管理數據庫事務,從而確保數據的完整性和一致性。開發人員可以專註於業務邏輯,而不必手動處理事務。

添加依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.hibernate.common</groupId>
    <artifactId>hibernate-commons-annotations</artifactId>
    <version>4.0.4.Final</version>
</dependency>

使用SessionFactory

我們這個老項目中使用 SessionFactory,所以這裡整合了SessionFactory 用作數據庫增刪改查。

配置文件

spring:
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:oracle:thin:@ip:1521:ORCL
    username: test
    password: test
    hikari:
      maximum-pool-size: 30
  jpa:
    database: oracle
    hibernate:
      hbm2ddl_auto: none
      dialect: org.hibernate.dialect.OracleDialect
      show_sql: false
      format_sql: false
      use_jdbc_metadata_defaults: false
      default-schema: ${spring.datasource.username}
public class HibernateSessionConfig {
    @Autowired
    private HibernateConfig hibernateConfig;
    @Autowired
    @Bean("sessionFactory")
    public LocalSessionFactoryBean getSessionFactory(DataSource dataSource) {
        return buildLocalSessionFactory(dataSource);
    }
    /**
     * 設置Hibernate的配置屬性
     * @return
     */
    private Properties getHibernateProperties(){
        Properties hibernateProperties = new Properties();
        hibernateProperties.put("hibernate.dialect",hibernateConfig.getDialect());
        hibernateProperties.put("default_schema",hibernateConfig.getDefaultSchema());
        hibernateProperties.put("hibernate.show_sql", hibernateConfig.getShowSql());
        hibernateProperties.put("hibernate.format_sql", hibernateConfig.getFormatSql());
        hibernateProperties.put("hibernate.hbm2ddl.auto", hibernateConfig.getHbm2ddlAuto());
        hibernateProperties.put("hibernate.temp.use_jdbc_metadata_defaults", hibernateConfig.getUseJdbcMetadataDefaults());
        return hibernateProperties;
    }
    /**
     * 構建LocalSessionFactoryBean實例
     * @param dataSource 構建實例所使用的的數據源
     * @return
     */
    private LocalSessionFactoryBean buildLocalSessionFactory(DataSource dataSource){
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setPackagesToScan("org.teamartframework.*","jdly.water.*");
        sessionFactory.setHibernateProperties(getHibernateProperties());
        return sessionFactory;
    }
}
@ConfigurationProperties(
        prefix = "spring.jpa.hibernate"
)
@Component
@Data
public class HibernateConfig {
    private String dialect;
    private String showSql;
    private String formatSql;
    private String hbm2ddlAuto;
    private String useJdbcMetadataDefaults;
    private String defaultSchema;
}

創建Dao層

@Repository
public class CommonDao{
    @Autowired
    @Qualifier("sessionFactory")
    private SessionFactory sessionFactory;
    public Session getSession() {
        // 事務必須是開啟的(Required),否則獲取不到
        return sessionFactory.getCurrentSession();
    }
    /**
     * 根據傳入的實體持久化對象
     */
    public <T> Serializable save(T entity) {
        try {
            Serializable id = getSession().save(entity);
            getSession().flush();
            if (logger.isDebugEnabled()) {
                logger.debug("保存實體成功,"   entity.getClass().getName());
            }
            return id;
        } catch (RuntimeException e) {
            logger.error("保存實體異常", e);
            throw e;
        }
    }
        /**
     * 根據Id獲取對象。
     */
    public <T> T get(Class<T> entityClass, final Serializable id) {
        return (T) getSession().get(entityClass, id);
    }
        /**
     * 根據主鍵更新實體
     */
    public <T> void updateEntityById(Class entityName, Serializable id) {
        updateEntitie(get(entityName, id));
    }
        /**
     * 根據主鍵刪除指定的實體
     * 
     * @param <T>
     * @param pojo
     */
    public <T> void deleteEntityById(Class entityName, Serializable id) {
        delete(get(entityName, id));
        getSession().flush();
    }
    /**
     * 執行自定義sql
     * 
     * @param <T>
     * @param pojo
     */
    public List<Map<String, Object>> findToMapList(String sql) {
        Query query = getSession().createSQLQuery(sql);
        List<Map<String, Object>>  lst = new ArrayList();
        try {
            query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
            lst = query.list();
        } catch (HibernateException e) {
            e.printStackTrace();
        } finally {
        }
        return lst;
     }
    /**
     * 返回實體
     * @param sql
     * @param clazz
     * @param param 
     * @return
     */
    public List<T> find(String sql,Class clazz, Object... param){
        Query query = null;
        query = getSession().createSQLQuery(sql).addEntity(clazz); //返回實體類的方法
        if (param != null && param.length > 0) {
            for (int i = 0; i < param.length; i  ) {
                query.setParameter(i, param[i]);
            }
        }
        return query.list();
    }
}

使用Repository訪問數據庫

依賴和上面引入的一樣,這裡就不在重復了。

配置數據源

server:
  port: 8030
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://ip:3306/test?useSSL=false&serverTimezone=UTC
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: none
    database: mysql
    database-platform: org.hibernate.dialect.MySQLDialect
    show-sql: true


Spring.jpa.hibernate.ddl-auto屬性指定了Hibernate如何自動生成數據庫表,create-drop表示每次啟動應用程序時都會創建表,並在關閉應用程序時刪除表。

none表示不用更新。

創建實體類

@Entity
@Table(name = "person")
@Data
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private int age;
}

創建Repository

@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
    @Query("select t from Person t where t.name like :name")
    public List<Person> findUserByName(@Param("name") String name);
}

業務類

@Service
public class PersonService {
    @Autowired
    private PersonRepository personRepository;
    public void savePerson(Person person) {
        personRepository.save(person);
    }
    public List<Person> getPersons() {
        return personRepository.findAll();
    }
}

接口類

@RestController
public class PersionController {
    @Autowired
    private PersonService personService;
    @GetMapping("save")
    public String save(){
        Person person = new Person();
        person.setName("zhangsan");
        personService.savePerson(person);
        return "hello world";
    }
    @GetMapping("get")
    public List<Person> get(String name){
        return personService.findUserByName(name);
    }
}

總結

我們已經成功地在Spring Boot項目中集成了Hibernate,並且可以使用它來方便地進行數據庫操作。當然,在實際的項目中,可能需要進行更復雜的配置和操作,但這個示例應該可以讓你快速入門。