SpringBoot Jpa企業(yè)開發(fā)示例詳細講解
JPA 介紹
JPA(Java Persistence API),對象關(guān)系映射(ORM)框架規(guī)范,是一種Java持久化規(guī)范。jpa可以通過實體類生成數(shù)據(jù)庫的表,同時自帶很多增刪改查方法,大部分sql語句不需要我們自己寫,配置完成后直接調(diào)用方法即可,很方便。
JPA 簡單使用示例
1. pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql驅(qū)動 依賴 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2. application.properties配置
# 數(shù)據(jù)庫連接配置
spring.datasource.url = jdbc:mysql://localhost:3306/manageserver?serverTimezone=Asia/Shanghai
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
# jpa配置
# 自動更新數(shù)據(jù)庫表
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
# 是否在控制臺顯示Hibernate的sql
spring.jpa.show-sql = false
3. 創(chuàng)建實體類對象,用于映射數(shù)據(jù)庫表
@Table(name="db_dictionary")
@Data
@Entity
public class DbDictionary implements Serializable {
@Id
@GenericGenerator(name = "faceset_generator", strategy = "uuid")
@GeneratedValue(generator = "faceset_generator")
@Column
private String id;
/**
* 類型名稱
*/
@Size(max = 50)
@Column
@NotNull
private String type;
/**
* 中文
*/
@Column
@NotNull
private String name;
/**
* 代碼
*/
@Column
@NotNull
private String code;
/**
* 順序
*/
private Integer sort;
/**
* 描述信息
*/
@Column
private String remark;
private static final long serialVersionUID = 1L;
}4. 創(chuàng)建持久化接口DAO,繼承JpaRepository,用于對數(shù)據(jù)庫進行操作
@Repository
public interface DictionaryDao extends JpaRepository<DbDictionary, String> {
}
5. 至此,JPA基本配置已經(jīng)完成,這里自帶很多內(nèi)置的增刪改查方法,不用我們自己寫sql語句,直接調(diào)用即可。
JPA 實體類中相關(guān)注解說明
@Entity:表明是一個實體類@Table(name = "dict_info"):對應(yīng)的數(shù)據(jù)表名,與@Entity注解一塊使用,但是如果表名和實體類名相同的話,@Table可以省略@GenericGenerator(name = "jpa-uuid", strategy = "uuid"):自定義hibernate主鍵生成策略@Id:表示當(dāng)前字段為主鍵@GeneratedValue(generator = "jpa-uuid"):指定主鍵生成策略為uuid@Column(name = "DICTNAME"):當(dāng)實體類的屬性與其映射的數(shù)據(jù)庫表的列不同名時需要使用@Column 標(biāo)注說明@CreatedDate:創(chuàng)建時間@LastModifiedDate:更新時間@Temporal(TemporalType.TIMESTAMP):實體類會封裝成完整的時間“yyyy-MM-dd hh:MM:ss”的 Date類型@Transient:表示該屬性并非一個到數(shù)據(jù)庫表的字段的映射,ORM框架將忽略該屬性
JPA 持久層關(guān)鍵字說明
JPA Data的使用模式已經(jīng)幫我集成了日常一些關(guān)鍵字用法,通過查詢可以直接使用!
| 關(guān)鍵字 | 方法命名 | sql where字句 |
|---|---|---|
| And | findByNameAndPwd | where name= ? and pwd =? |
| Or | findByNameOrSex | where name= ? or sex=? |
| Is,Equals | findById,findByIdEquals | where id= ? |
| Between | findByIdBetween | where id between ? and ? |
| LessThan | findByIdLessThan | where id < ? |
| LessThanEquals | findByIdLessThanEquals | where id <= ? |
| GreaterThan | findByIdGreaterThan | where id > ? |
| GreaterThanEquals | findByIdGreaterThanEquals | where id > = ? |
| After | findByIdAfter | where id > ? |
| Before | findByIdBefore | where id < ? |
| IsNull | findByNameIsNull | where name is null |
| isNotNull,NotNull | findByNameNotNull | where name is not null |
| Like | findByNameLike | where name like ? |
| NotLike | findByNameNotLike | where name not like ? |
| StartingWith | findByNameStartingWith | where name like ‘?%’ |
| EndingWith | findByNameEndingWith | where name like ‘%?’ |
| Containing | findByNameContaining | where name like ‘%?%’ |
| OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
| Not | findByNameNot | where name <> ? |
| In | findByIdIn(Collection<?> c) | where id in (?) |
| NotIn | findByIdNotIn(Collection<?> c) | where id not in (?) |
| True | findByAaaTue | where aaa = true |
| False | findByAaaFalse | where aaa = false |
| IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
實戰(zhàn)-JPA企業(yè)開發(fā)示例
1. 實體繼承基礎(chǔ)通用屬性
/**
* 實體繼承映射類基礎(chǔ) ,保存實體的通用屬性
*/
@Data
@Accessors(chain = true)
@MappedSuperclass //實體繼承映射
public abstract class BaseEntity implements Serializable {
/**
* 創(chuàng)建者
*/
@Basic
@Column(length = 50)
private String creator;
/**
* 修改者
*/
@Basic
@Column(length = 50)
private String modifier;
/**
* 創(chuàng)建時間
*/
@Basic
@Column(name = "create_time")
@CreatedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 修改時間
*/
@Basic
@Column(name = "update_time")
@LastModifiedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}2. 查詢
2.1 條件查詢
條件查詢有兩種方式,一是直接使用持久層提供的關(guān)鍵字,二是自己寫查詢SQL。
// 根據(jù)名稱和性別查詢用戶 User findByNameAndSex(String name, String sex);
@Query(nativeQuery = true, value = "select * from user where name = :name and sex = :sex")
User findByNameAndSex(@Param("name") String name, @Param("sex") String sex);
2.2 查詢排序
List<T> findAll(Sort sort);
//按創(chuàng)建時間倒序排列
Sort.by("createTime").descending()
2.3 分頁查詢
Page<T> findAll(Pageable pageable);
/*獲取分頁參數(shù)*/
public PageRequest getPageRequest() {
return getPageRequest(Sort.unsorted());
}
/*獲取分頁和排序參數(shù)*/
public PageRequest getPageRequest(Sort sort) {
ServletRequestAttributes attributes = getServletRequestAttributes();
if (StringUtils.hasText(attributes.getRequest().getParameter("page")) && StringUtils.hasText(attributes.getRequest().getParameter("size"))) {
int page = Integer.parseInt(attributes.getRequest().getParameter("page"));
int size = Integer.parseInt(attributes.getRequest().getParameter("size"));
return PageRequest.of(page, size, sort);
}
return PageRequest.of(Constants.zero, Constants.ten);
}2.4 動態(tài)條件查詢
動態(tài)條件查詢Specification,DAO需要再繼承JpaSpecificationExecutor接口
List<T> findAll(@Nullable Specification<T> spec);
Specification<ProjectionInfo> spec = (Specification<ProjectionInfo>) (root, query, cb) -> {
List<Predicate> predicateList = new ArrayList<>();
// 時間
if (null != startTime && null != endTime) {
predicateList.add(cb.between(root.get("createTime"), startTime, endTime));
}
// 數(shù)字
if (searchDto.getCloud() != null) {
predicateList.add(cb.le(root.<Integer>get("cloudPercent"), searchDto.getCloud()));
}
// 字符串
if (searchDto.getName() != null) {
predicateList.add(cb.equal(root.get("name"), searchDto.getName()));
}
// 列表
if (StrUtil.isNotEmpty(searchDto.getSatellite())) {
String[] satellites = searchDto.getSatellite().split(",");
Expression<String> exp = root.<String>get("satellite");
predicateList.add(exp.in(Arrays.asList(satellites)));
}
Predicate[] pre = new Predicate[predicateList.size()];
pre = predicateList.toArray(pre);
return query.where(pre).getRestriction();
};2.5 多表聯(lián)查
@Query(nativeQuery = true, value = "SELECT satellite, count(id), COALESCE(sum(file_size), 0) FROM t_mas_orbit_info" +
" WHERE create_time BETWEEN :startTime AND :endTime " +
" GROUP BY satellite")
List<Object[]> satelliteDataIncreased(@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
2.6 返回自定義Vo
@Query(value = "SELECT new cn.piesat.dispatch.model.vo.FileDataVO(p.id, p.fileName,p.stationCode,p.fileSize, p.fileDate, p.createTime, p.state, p.filePath,p.forwardTime) " +
" FROM DbZxjProductInfoDTO p ")
List<FileDataVO> getFileList();
3. 修改和刪除
進行修改和刪除時,需要添加@Modifying、@Transactional注解。
@Query(nativeQuery = true, value = "UPDATE db_order_info SET download_count = (SELECT download_count + 1) WHERE id = :orderId ") @Modifying @Transactional int updateDownloadTimes(String orderId);
@Modifying @Transactional void deleteByName(String name);
踩坑
1.刪除的方法上一定要加@Transactional和@Modifying注解
2.自定義刪除方法的時候如果傳的是基本類型或者包裝類型一定要用 void deleteByxxx(String s) 而不是 void deleteAllByxxx(String s)。
因為deleteAllByxxx(String s)會被jpa識別為查詢語句,只有傳入?yún)?shù)是列表時才是用deleteAllByxxx(List<String> s)
推薦使用原生sql,自帶的delete或者deleteAll會先進行查詢,然后在查詢結(jié)果上面挨個執(zhí)行刪除,并不是一條sql執(zhí)行完刪除操作,所以還是建議自己寫delete
到此這篇關(guān)于SpringBoot Jpa企業(yè)開發(fā)示例詳細講解的文章就介紹到這了,更多相關(guān)SpringBoot Jpa內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實現(xiàn)批量向mysql寫入數(shù)據(jù)的方法
這篇文章主要介紹了Java實現(xiàn)批量向mysql寫入數(shù)據(jù)的方法,涉及java基于JDBC連接mysql數(shù)據(jù)庫及寫入數(shù)據(jù)的相關(guān)操作技巧,非常簡單實用,需要的朋友可以參考下2017-12-12
Java中notify和notifyAll的區(qū)別及何時使用
本文主要介紹了Java中notify和notifyAll的區(qū)別及何時使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
解決使用@Component會導(dǎo)致spring.factories中的EnableAutoConfiguration無效
這篇文章主要介紹了解決使用@Component會導(dǎo)致spring.factories中的EnableAutoConfiguration無效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
SpringBoot操作spark處理hdfs文件的操作方法
本文介紹了如何使用Spring Boot操作Spark處理HDFS文件,包括導(dǎo)入依賴、配置Spark信息、編寫Controller和Service處理地鐵數(shù)據(jù)、運行項目以及觀察Spark和HDFS的狀態(tài),感興趣的朋友跟隨小編一起看看吧2025-01-01
Java高級之HashMap中的entrySet()方法使用
這篇文章主要介紹了Java高級之HashMap中的entrySet()方法使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03

