快速构建SpringBoot项目并整合Hibernate实现CRUD(详细版)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
从无到有详细版
1.创建项目(为了方便,使用Maven项目)
新建-选择maven项目-一直下一步,到:
然后点 Finish 完成创建。
2.添加依赖
此时已经创建了一个Maven项目,因为需要使用SpringBoot,我们需要在pom.xml里面添加SpringBoot的依赖
打开pom.xml文件,加入以下依赖(注意标签):
继承springboot父工程:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
引入web的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在引入一个打包插件,后面需要用到:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
以上一个web版的springboot的依赖已经加完。
3.创建应用启动入口。
通常使用App.java,注意启动类需要放在代码包的顶层,不然可能启动不了,比如像我这样的结构:
可看出App.java在我所有代码的包顶层。
App.java代码:
package com.xingsfdz.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/**
*
* @类名称 App.java
* @类描述 <pre></pre>
* @作者
* @创建时间 2019年12月19日 下午4:38:33
* @版本 1.00
*
* @修改记录
* <pre>
* 版本 修改人 修改日期 修改内容描述
* ----------------------------------------------
* 1.00 xingsfdz 2019年12月19日
* ----------------------------------------------
* </pre>
*/
@SpringBootApplication
@EnableJpaRepositories //启用SpringData jpa
public class App
{
public static void main( String[] args ) {
SpringApplication.run(App.class, args);
}
}
@SpringBootApplication说明:
很多Spring Boot开发者总是使用 @Configuration , @EnableAutoConfiguration 和 @ComponentScan 注
解他们的main类。 由于这些注解被如此频繁地一块使用(特别是你遵循以上最佳实践时) , Spring Boot提供
一个方便的 @SpringBootApplication 选择。该 @SpringBootApplication 注解等价于以默认属性使用
@Configuration , @EnableAutoConfiguration 和 @ComponentScan 。
@EnableJpaRepositories :该注解是后面需要使用Spring Jpa Data需要添加的,如果不需要对数据持久化操作,不需要改注解。
4.配置文件:
先创建资源文件夹:
新建的文件夹应该不是source的文件夹,可以右键-->Bulid Path-->User as Source Folder。使该文件夹成为Source文件夹。
然后新建SpringBoot的配置文件,通常命名为:application.properties,以下是我只配置了应用启动的端口号,默认8080。
server.port=8027
5.新建Controller层类进行url请求测试:
DemoController.java
@RequestMapping("xingsfdz")
@RestController
public class DemoController {
@RequestMapping("")
public String demo(){
return "xingsfdz";
}
}
游览器请求测试正常:
6.添加数据库持久Jpa
以上已经springboot启动正常,接下来加入数据库持久Jpa,使用的是Spring Data Jpa,首先再pom.xml文件加入相关依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
使用的是Mysql,加入Mysql的驱动:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
application.properties配置文件加入数据访问的相关配置:
#mysql
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useunicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
7.新建实体类
我们可以设计新建一个基类,把一些公用的字段放在基类里面,避免重复创建,新建基类
BaseEntity.java
注://@MappedSuperclass标识的类不能再有@Entity和@Table注解。基类使用@MappedSuperclass,具体业务实体类(需要建表的)使用@Entity和@Table
package com.xingsfdz.demo.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
/**
*
* @类名称 BaseEntity.java
* @类描述 <pre>实体基类</pre>
* @作者
* @创建时间 2019年12月19日 下午6:01:12
* @版本 1.00
*
* @修改记录
* <pre>
* 版本 修改人 修改日期 修改内容描述
* ----------------------------------------------
* 1.00 xingsfdz 2019年12月19日
* ----------------------------------------------
* </pre>
*/
//@MappedSuperclass标识的类不能再有@Entity和@Table注解。
@MappedSuperclass
public class BaseEntity implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "version")
private String version;
@Column(name = "flag")
private String flag;
@Column(name = "status")
private String status;
@Column(name = "createDate")
private Date createDate;
@Column(name = "updateDate")
private Date updateDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
@Override
public String toString() {
return "BaseEntity [id=" + id + ", version=" + version + ", flag=" + flag + ", status=" + status
+ ", createDate=" + createDate + ", updateDate=" + updateDate + "]";
}
}
子类,继承上面的基类:
package com.xingsfdz.demo.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
*
* @类名称 User.java
* @类描述 <pre>用户实体</pre>
* @作者
* @创建时间 2019年12月19日 下午6:05:28
* @版本 1.00
*
* @修改记录
* <pre>
* 版本 修改人 修改日期 修改内容描述
* ----------------------------------------------
* 1.00 xingsfdz 2019年12月19日
* ----------------------------------------------
* </pre>
*/
@Entity
@Table(name = "xbc_user")
public class User extends BaseEntity{
@Column(name = "userName")
private String userName;
@Column(name = "password")
private String password;
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 [userName=" + userName + ", password=" + password + "]";
}
}
8.创建数据访问 dao层
(接口,由于使用Spring Data Jpa封装了很多方法,一般方法无需实现,直接使用,当然也可以自己实现):数据库操作接口继承自JpaRepository泛型类
注意:
1.代码中有Hql与Sql两个查询方法,//nativeQuery为true代表使用SQL语言。
2.注意使用注解@Repository 标识该类。
package com.xingsfdz.demo.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.xingsfdz.demo.entity.User;
/**
*
* @类名称 UserRepository.java
* @类描述 <pre>数据库操作接口</pre>
* @作者
* @创建时间 2019年12月19日 下午6:10:31
* @版本 1.00
*
* @修改记录
* <pre>
* 版本 修改人 修改日期 修改内容描述
* ----------------------------------------------
* 1.00 xingsfdz 2019年12月19日
* ----------------------------------------------
* </pre>
*/
@Repository
public interface UserRepository extends JpaRepository<User, Integer>{
public User findById(Long id);//查询用户通过id
@SuppressWarnings("unchecked")
public User save(User user);//保存用户
@Query(value = "SELECT u FROM User u WHERE name=:name")
public User findNameHql(@Param("name") String name);
//nativeQuery为true代表使用SQL语言
@Query(value = "SELECT * FROM yyh_user WHERE name=?", nativeQuery = true)
public User findNameSql(String name);
}
9.创建Service层
(通常用来处理业务,就是具体做业务的一层,也叫biz层)
先创建接口,并定义三个方法:
package com.xingsfdz.demo.service;
import com.xingsfdz.demo.entity.User;
/**
*
* @类名称 UserService.java
* @类描述 <pre>业务层接口</pre>
* @作者
* @创建时间 2019年12月19日 下午6:22:31
* @版本 1.00
*
* @修改记录
* <pre>
* 版本 修改人 修改日期 修改内容描述
* ----------------------------------------------
* 1.00 xingsfdz 2019年12月19日
* ----------------------------------------------
* </pre>
*/
public interface UserService {
public User findById(Long id);//查询用户通过id
public User save(User user);//保存用户
public User findNameHql(String name);
}
再建具体的实现类:
注意:
1.需要使用注解把实现类注入ioc容器,一般使用:@Service或者
@Component
package com.xingsfdz.demo.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xingsfdz.demo.dao.UserRepository;
import com.xingsfdz.demo.entity.User;
import com.xingsfdz.demo.service.UserService;
/**
*
* @类名称 UserServiceImpl.java
* @类描述 <pre>业务层具体实现</pre>
* @作者
* @创建时间 2019年12月19日 下午6:26:07
* @版本 1.00
*
* @修改记录
* <pre>
* 版本 修改人 修改日期 修改内容描述
* ----------------------------------------------
* 1.00 xingsfdz 2019年12月19日
* ----------------------------------------------
* </pre>
*/
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userDao;
public User findById(Long id) {
return userDao.findById(id);
}
public User save(User user) {
return userDao.save(user);
}
public User findNameHql(String name) {
return userDao.findNameHql(name);
}
}
10.创建Controller控制层操作方法测试:
package com.xingsfdz.demo.controller;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.xingsfdz.demo.entity.User;
import com.xingsfdz.demo.service.UserService;
/**
*
* @类名称 DemoController.java
* @类描述 <pre></pre>
* @作者 m
* @创建时间 2019年12月19日 下午4:39:36
* @版本 1.00
*
* @修改记录
* <pre>
* 版本 修改人 修改日期 修改内容描述
* ----------------------------------------------
* 1.00 xingsfdz 2019年12月19日
* ----------------------------------------------
* </pre>
*/
@RequestMapping("xingsfdz")
@RestController
public class DemoController {
@Resource
private UserService userServiceImpl;
@RequestMapping("")
public String demo(){
return "xingsfdz";
}
@RequestMapping("findById")
public User findById(Long id){
return userServiceImpl.findById(id);
}
@RequestMapping("save")
public User save(){
User user = new User();
user.setUserName("xingsfdz");
user.setPassword("123456");
return userServiceImpl.save(user);
}
}
注意:
使用的时候如果使用接口作为类型,直接使用@Autowired
是无法找到具体是哪个bean的,因为@Autowired
默认是按照类型注入的,需要加上@Qualifier
注解指定实现类的bean id,如果@Service
中没有指定bean id(bean name),默认是类名的首字母小写作为bean name。当然也可以使用@Resource
注解,它默认是by name 注入的,所以变量名需要和待注入的实现类的bean name保持一致。
游览器访问结果:
11.其他
1.ps,注解说明参见官方:
在Spring2.0之前的版本中,@Repository
注解可以标记在任何的类上,用来表明该类是用来执行与数据库相关的操作(即dao对象),并支持自动处理数据库操作产生的异常
在Spring2.5版本中,引入了更多的Spring类注解:@Component
,@Service
,@Controller
。@Component
是一个通用的Spring容器管理的单例bean组件。而@Repository
, @Service
, @Controller
就是针对不同的使用场景所采取的特定功能化的注解组件。
因此,当你的一个类被@Component
所注解,那么就意味着同样可以用@Repository
, @Service
, @Controller
来替代它,同时这些注解会具备有更多的功能,而且功能各异。
最后,如果你不知道要在项目的业务层采用@Service
还是@Component
注解。那么,@Service
是一个更好的选择。
就如上文所说的,@Repository
早已被支持了在你的持久层作为一个标记可以去自动处理数据库操作产生的异常(译者注:因为原生的java操作数据库所产生的异常只定义了几种,但是产生数据库异常的原因却有很多种,这样对于数据库操作的报错排查造成了一定的影响;而Spring拓展了原生的持久层异常,针对不同的产生原因有了更多的异常进行描述。所以,在注解了@Repository
的类上如果数据库操作中抛出了异常,就能对其进行处理,转而抛出的是翻译后的spring专属数据库异常,方便我们对异常进行排查处理)。
注解 | 含义 |
@Component | 最普通的组件,可以被注入到spring容器进行管理 |
@Repository | 作用于持久层 |
@Service | 作用于业务逻辑层 |
@Controller | 作用于表现层(spring-mvc的注解) |
2.spring.jpa.hibernate.ddl-auto = update 说明:
ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有数据会清空
ddl-auto:create-drop----每次程序结束的时候会清空表
ddl-auto:update----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
ddl-auto:validate----运行程序会校验数据与数据库的字段类型是否相同,不同会报错
3.HIbernate 、JPA、Spring Data Jpa简单说明
ORM:对象关系映射
JPA:
ORM的规范,也就是定义的一些接口。
Hibernate:
一个实现了JPA接口的ORM(对象关系映射)框架。
Spring Data jpa:
由于Hibernate在数据访问解决技术领域的霸主地位,所以JPA标准基本由Hibernate主导。对JPA的再次封装,封装了一些Dao层访问数据的方法
JPA是一套规范,内部是有接口和抽象类组成的。hibernate是一套成熟的ORM框架,而且Hibernate实现了JPA规范,所以也可以称hibernate为JPA的一种实现方式,我们使用JPA的API编程,意味着站在更高的角度上看待问题(面向接口编程)Spring Data JPA是Spring提供的一套对JPA操作更加高级的封装,是在JPA规范下的专门用来进行数据持久化的解决方案。
总结:
JPA是一种规范,Hibernate实现了JPA规范,即Hibernate为JPA的一种实现;而Spring Data JPA是对JPA进行更高级的封装,让其dao编码变得更简单。
另区别详细可以参见:https://www.jianshu.com/p/c23c82a8fcfc
待更 20191220...
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |