從無到有詳細版
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>
* @作者 xingsfdz [email protected]
* @創建時間 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>
* @作者 xingsfdz [email protected]
* @創建時間 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>
* @作者 xingsfdz [email protected]
* @創建時間 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>
* @作者 xingsfdz [email protected]
* @創建時間 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>
* @作者 xingsfdz [email protected]
* @創建時間 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>
* @作者 xingsfdz [email protected]
* @創建時間 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>
* @作者 xingsfdz [email protected]
* @創建時間 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...