赞
踩
Hibernate与MyBatis都是流行的持久层开发框架,只不过Hibernate是全自动ORM框架,不需要关心sql编写。
Hibernate 是一个高性能的对象/关系映射(ORM)持久化存储和查询的服务,不仅负责从Java类到数据库表的映射 (还包括从Java数据类型到SQL数据类型的映射),还提供了面向对象的数据查询检索机制,从而极大地缩短了手动处理SQL和JDBC上的开发时间。 同时,Hibernate还实现了JPA规范,在SpringBoot中,JPA的默认实现就是使用的Hibernate。
JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。
可以通过注解或者XML描述【对象-关系表】之间的映射关系,并将实体对象持久化到数据库中。
JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的。所以底层需要某种实现,而Hibernate就是实现了JPA接口的ORM框架。
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架。 Hibernate可以自动生成SQL语句、自动执行,从而使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
实际上,JPA规范制定过程中就是借鉴了Hibernate等这些开源的持久框架,也就是说Hibernate的出现比JPA还要早些。
在Hibernate中使用的注解就是JPA注解,Hibernate实现了JPA规范。
spirng data jpa是spring提供的一套简化JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等。
Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。
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复杂语句查询以及根据实体类自动创建数据库。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。