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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>

创建数据库

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

配置文件application.yml

spring:
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect
        new_generator_mappings: false
        format_sql: true
  datasource:
    url: jdbc:mysql://localhost:3306/ss?serverTimezone=UTC&useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8
    username: root
    password: 123qwe

创建如图以下包

在config下编写数据源配置

@Configuration
@EnableTransactionManagement(order = 2)
public class DataSourceConfig {
    @Resource
    private DruidProperties druidProperties;

    /**
     * 单数据源连接池配置
     */
    @Bean
    public DruidDataSource singleDatasource() {
        DruidDataSource dataSource = new DruidDataSource();
        druidProperties.config(dataSource);
        return dataSource;
    }
}
@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidProperties {
    private String url;

    private String username;

    private String password;

    private String driverClassName = "com.mysql.cj.jdbc.Driver";

    private Integer initialSize = 10;

    private Integer minIdle = 3;

    private Integer maxActive = 60;

    private Integer maxWait = 60000;

    private Boolean removeAbandoned = true;

    private Integer removeAbandonedTimeout = 180;

    private Integer timeBetweenEvictionRunsMillis = 60000;

    private Integer minEvictableIdleTimeMillis = 300000;

    private String validationQuery = "SELECT 'x'";

    private Boolean testWhileIdle = true;

    private Boolean testOnBorrow = false;

    private Boolean testOnReturn = false;

    private Boolean poolPreparedStatements = true;

    private Integer maxPoolPreparedStatementPerConnectionSize = 50;

    private String filters = "stat";

    public void config(DruidDataSource dataSource) {
        dataSource.setDbType(JdbcConstants.MYSQL);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        // 定义初始连接数
        dataSource.setInitialSize(initialSize);
        // 最小空闲
        dataSource.setMinIdle(minIdle);
        // 定义最大连接数
        dataSource.setMaxActive(maxActive);
        // 获取连接等待超时的时间
        dataSource.setMaxWait(maxWait);
        // 超过时间限制是否回收
        dataSource.setRemoveAbandoned(removeAbandoned);
        // 超过时间限制多长
        dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout);

        // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        // 配置一个连接在池中最小生存的时间,单位是毫秒
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        // 用来检测连接是否有效的sql,要求是一个查询语句
        dataSource.setValidationQuery(validationQuery);
        // 申请连接的时候检测
        dataSource.setTestWhileIdle(testWhileIdle);
        // 申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能
        dataSource.setTestOnBorrow(testOnBorrow);
        // 归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能
        dataSource.setTestOnReturn(testOnReturn);
        // 打开PSCache,并且指定每个连接上PSCache的大小
        dataSource.setPoolPreparedStatements(poolPreparedStatements);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        // 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
        // 监控统计用的filter:stat
        // 日志用的filter:log4j
        // 防御SQL注入的filter:wall
        try {
            dataSource.setFilters(filters);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public Integer getInitialSize() {
        return initialSize;
    }

    public void setInitialSize(Integer initialSize) {
        this.initialSize = initialSize;
    }

    public Integer getMinIdle() {
        return minIdle;
    }

    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }

    public Integer getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(Integer maxActive) {
        this.maxActive = maxActive;
    }

    public Integer getMaxWait() {
        return maxWait;
    }

    public void setMaxWait(Integer maxWait) {
        this.maxWait = maxWait;
    }

    public Integer getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }

    public void setTimeBetweenEvictionRunsMillis(Integer timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    public Integer getMinEvictableIdleTimeMillis() {
        return minEvictableIdleTimeMillis;
    }

    public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }

    public String getValidationQuery() {
        return validationQuery;
    }

    public void setValidationQuery(String validationQuery) {
        this.validationQuery = validationQuery;
    }

    public Boolean getTestWhileIdle() {
        return testWhileIdle;
    }

    public void setTestWhileIdle(Boolean testWhileIdle) {
        this.testWhileIdle = testWhileIdle;
    }

    public Boolean getTestOnBorrow() {
        return testOnBorrow;
    }

    public void setTestOnBorrow(Boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }

    public Boolean getTestOnReturn() {
        return testOnReturn;
    }

    public void setTestOnReturn(Boolean testOnReturn) {
        this.testOnReturn = testOnReturn;
    }

    public Boolean getPoolPreparedStatements() {
        return poolPreparedStatements;
    }

    public void setPoolPreparedStatements(Boolean poolPreparedStatements) {
        this.poolPreparedStatements = poolPreparedStatements;
    }

    public Integer getMaxPoolPreparedStatementPerConnectionSize() {
        return maxPoolPreparedStatementPerConnectionSize;
    }

    public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) {
        this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
    }

    public String getFilters() {
        return filters;
    }

    public void setFilters(String filters) {
        this.filters = filters;
    }

    public Boolean getRemoveAbandoned() {
        return removeAbandoned;
    }

    public void setRemoveAbandoned(Boolean removeAbandoned) {
        this.removeAbandoned = removeAbandoned;
    }

    public Integer getRemoveAbandonedTimeout() {
        return removeAbandonedTimeout;
    }

    public void setRemoveAbandonedTimeout(Integer removeAbandonedTimeout) {
        this.removeAbandonedTimeout = removeAbandonedTimeout;
    }
}

在entity下创建实体类

@Entity
@Table(name = "books")
@Data
public class Book implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "book_id")
    private int bookId;
    @Column(name = "title")
    private String title;
    @Column(name = "category")
    private String category;
}

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

public interface BookDao {
    List<Book> getAllBooks();

    Book getBookById(int bookId);

    void addBook(Book book);

    void updateBook(Book book);

    void deleteBook(int bookId);

    boolean bookExists(String title,String category);
}

@Repository
public class IBookDao implements BookDao {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<Book> getAllBooks() {
        String sql = "FROM Book as book ORDER BY book.bookId";
        return (List<Book>)entityManager.createQuery(sql).getResultList();
    }

    @Override
    public Book getBookById(int bookId) {
        return entityManager.find(Book.class,bookId);
    }

    @Override
    public void addBook(Book book) {
        entityManager.persist(book);
    }

    @Override
    public void updateBook(Book book) {
        Book book1 = getBookById(book.getBookId());
        book1.setTitle(book.getTitle());
        book1.setCategory(book.getCategory());
        entityManager.flush();
        entityManager.clear();
    }

    @Override
    public void deleteBook(int bookId) {
        entityManager.remove(getBookById(bookId));
    }

    @Override
    public boolean bookExists(String title, String category) {
        String sql = "FROM Book as book WHERE book.title=?0 and book.category=?1";
        int count = entityManager.createQuery(sql)
                .setParameter(0,title)
                .setParameter(1,category)
                .getResultList().size();
        return count > 0;
    }
}

创建业务层Service,注入BookDao

@Service
public class BookService {

    @Autowired
    private BookDao bookDao;

    public Book getBookById(int bookId){
        Book book= bookDao.getBookById(bookId);
        return book;
    }

    public List<Book> getAllBooks(){
        return bookDao.getAllBooks();
    }

    public synchronized boolean addBook(Book book){
        if(bookDao.bookExists(book.getTitle(),book.getCategory())){
            return false;
        }else {
            bookDao.addBook(book);
            return true;
        }
    }
    public void updateBook(Book book){
        bookDao.updateBook(book);
    }

    public void deleteBook(int bookId){
        bookDao.deleteBook(bookId);
    }
}

测试类 编写测试代码

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

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class HibernateApplicationTests {

    @Autowired
    private BookService bookService;

    @Test
    @Rollback(false)
    public void contextLoads() {
        Book book = bookService.getBookById(1);
        assertThat(book.getTitle(),is("123"));

        List<Book> list = bookService.getAllBooks();
        assertThat(list,notNullValue());
        assertThat(list.size(), is(3));
        boolean flag = bookService.addBook(book);
        assertThat(flag, is(false));

        book.setTitle("012");
        bookService.updateBook(book);
        Book book1 = bookService.getBookById(1);
        System.out.println(book1);
        assertThat(book1.getTitle(), is("012"));


        bookService.deleteBook(1);
        Book article2 = bookService.getBookById(1);
        assertThat(article2, nullValue());
    }

}

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

  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值