SpringBoot整合hibernate纯注解版

一、hibernate是什么

hibernate是一款优秀的ORM(Object Relational Mapping ,对象关系映射)框架,是一种面向对象编程的框架,它对JDBC进行了封装,是一个全自动的ORM框架,可以自动生成SQL语句,也可以自定义HQL进行执行脚本。

优点:hibernate在进行对象进行数据库存储时,可以不进行SQL编写,配置好对象与数据库的关系后,自动生成SQL执行,也可自动创建表,在简单的数据库关系项目中,可进行高效率的工作。

缺点:hibernte在项目开发的过程中,由于全自动生成SQL,在使用时会发现,当执行复杂关系的数据库关系的业务时,hibernate略显笨重,执行时间偏长且无法灵活的配置关系较为复杂的业务,所以后期有了mybatis的出现,为了可以更加便捷的写sql,灵活的配置SQL。

二、为什么我还要使用hibernate

刚才也描述了,在进行关系较为简单的项目业务上,hibernate可以自动生成SQL执行,也提供了增删改查的方法,可以很简单直接进行对象存储删除,所以在开发逻辑简单的业务时(例如帮学妹做个毕设,课程设计什么的,你懂的,哈哈),可以利用hibernate进行快速的项目开发。

三、开始整合

1.搭建SpringBoot工程,此处不再多讲,之前已经讲过,可以翻看SpringBoot的搭建的帖子,(点我跳转),在pom文件加上如下依赖

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

2.在java文件夹下创建自定义包,项目结构如下

3.全局配置文件如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#配置数据源
spring.datasource.url=jdbc:mysql://localhost:3306/yang
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#服务启动信息
server.port=8088
#jpa配置
#数据库类型为mysql
spring.jpa.database = MYSQL
#是否显示sql
spring.jpa.show-sql = true
#自动创建表
spring.jpa.hibernate.ddl-auto = update
#创建命名策略
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
#数据库方言为mysql
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

4.创建实体类-用户类,及统一返回对象ResultObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.yang.bean;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
* 用户实体类
* @author Yang
*
*/
@Entity
@Table(name="t_user")
public class User {
/*用户名称*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="user_id")
private int userId;
/*用户登录名称*/
@Column(name="user_name")
private String userName;
/* 用户登录密码 */
@Column(name="pass_word")
private String password;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
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;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName + ", password=" + password + "]";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.yang.bean;

public class ResultObject<T> {
private int code;
private String msg;
private T data;
private Long count;

public Long getCount() {
return count;
}
public void setCount(Long count) {
this.count = count;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

5.创建数据查询接口,需要继承JpaRepository接口来实现查询

1
2
3
4
5
6
7
8
9
10
package com.yang.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.yang.bean.User;

@Repository
public interface UserDao extends JpaRepository<User, Long>{

}

6.编写Service接口及实现类,实现类注入数据层接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.yang.service;

import java.util.List;

import com.yang.bean.User;

/**
*
* @author yzx96
*
*/
public interface UserService {
/**
* 查询所有用户
* @return
*/
public List<User> getAllUser();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.yang.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yang.bean.User;
import com.yang.dao.UserDao;
import com.yang.service.UserService;

/**
* 服务实现
* @author yzx96
*
*/
@Service
public class UserServiceImpl implements UserService {
/**
* 注入数据层接口
*/
@Autowired
UserDao userDao;

@Override
public List<User> getAllUser() {
return userDao.findAll();
}

}

7.编写控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.yang.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yang.bean.ResultObject;
import com.yang.bean.User;
import com.yang.service.UserService;
@RestController
@RequestMapping("/user")
public class UseController {

@Autowired
private UserService userService;


@RequestMapping("/getAllUser")
public ResultObject<List<User>> getAllUser(){
List<User> list=userService.getAllUser();
ResultObject<List<User>> rs=new ResultObject<List<User>>();
rs.setCode(0);
rs.setData(list);
return rs;
}
}

8.编写启动类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.yang.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@ComponentScan(basePackages={"com.yang"}) // 扫描该包路径下的所有spring组件
@EnableJpaRepositories("com.yang.dao") // JPA扫描该包路径下的Repositorie
@EntityScan("com.yang.bean")
@SpringBootApplication
public class StartAppHibernatelication {
public static void main(String[] args) {
SpringApplication.run(StartAppHibernatelication.class, args);
}
}

9.创建数据库表及插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
CREATE TABLE `t_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(50) DEFAULT NULL,
`pass_word` varchar(50) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;


INSERT INTO `t_user` VALUES ('1', 'zhangsan', '00000');
INSERT INTO `t_user` VALUES ('2', 'lisi2', '123456');
INSERT INTO `t_user` VALUES ('3', 'lisi3', '123456');
INSERT INTO `t_user` VALUES ('4', 'lisi4', '123456');
INSERT INTO `t_user` VALUES ('5', 'lisi5', '123456');
INSERT INTO `t_user` VALUES ('6', 'lisi6', '123456');
INSERT INTO `t_user` VALUES ('7', 'lisi7', '123456');
INSERT INTO `t_user` VALUES ('8', 'lisi8', '123456');
INSERT INTO `t_user` VALUES ('9', 'lisi9', '123456');
INSERT INTO `t_user` VALUES ('10', 'lisi10', '123456');
INSERT INTO `t_user` VALUES ('11', 'lisi11', '123456');
INSERT INTO `t_user` VALUES ('12', 'lisi12', '123456');
INSERT INTO `t_user` VALUES ('13', 'lisi13', '123456');
INSERT INTO `t_user` VALUES ('14', 'lisi14', '123456');
INSERT INTO `t_user` VALUES ('15', 'lisi15', '123456');
INSERT INTO `t_user` VALUES ('16', 'lisi16', '123456');
INSERT INTO `t_user` VALUES ('17', 'lisi17', '123456');
INSERT INTO `t_user` VALUES ('18', 'lisi18', '123456');
INSERT INTO `t_user` VALUES ('19', 'lisi19', '123456');
INSERT INTO `t_user` VALUES ('20', 'lisi20', '123456');

10.启动项目,访问地址:localhost:8088/user/getAllUser ,访问结果如下

四、整合的时候遇到的坑

1.注入数据层接口失败,启动时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-01-30 10:57:19.756 ERROR 22892 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userDao in com.yang.service.impl.UserServiceImpl required a bean of type 'com.yang.dao.UserDao' that could not be found.


Action:

Consider defining a bean of type 'com.yang.dao.UserDao' in your configuration.

原因:在启动类上,只是用了@EnableJpaRepositories注解,但未将该注解指定数据层接口包名,需要指定数据层接口的包名,上面代码是已经修复过的,错误代码如下

2.启动时,无法创建userDao,原因为无法创建bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.yang.bean.User
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:579) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:584) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
... 37 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.yang.bean.User
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:473) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:73) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:181) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:119) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:102) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:298) ~[spring-data-commons-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$3(RepositoryFactoryBeanSupport.java:287) ~[spring-data-commons-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.util.Lazy.getNullable(Lazy.java:141) ~[spring-data-commons-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.util.Lazy.get(Lazy.java:63) ~[spring-data-commons-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:290) ~[spring-data-commons-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:102) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1765) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
... 47 common frames omitted

解决方案:使用@EntityScan注解指定实体类的地址

3.注解的顺序导致的项目无法启动@SpringBootApplication注解需要放到扫描包指定配置之后,否则数据层也无法依赖,实体类指向也不能生效(这个问题困扰了我两个小时)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-01-30 11:07:22.925 ERROR 21064 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'useController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'userDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.yang.bean.User
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:587) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:373) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1348) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:578) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at com.yang.boot.StartAppHibernatelication.main(StartAppHibernatelication.java:15) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_91]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.0.2.RELEASE.jar:2.0.2.RELEASE]

五、项目下载地址如下

点击我下载,小心你的鼠标