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 標注說明@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之System.getProperty()的作用及使用說明
這篇文章主要介紹了Java之System.getProperty()的作用及使用說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
Json轉(zhuǎn)list二層解析轉(zhuǎn)換代碼實例
這篇文章主要介紹了Json轉(zhuǎn)list二層解析轉(zhuǎn)換代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-12-12
在springboot中實現(xiàn)個別bean懶加載的操作
這篇文章主要介紹了在springboot中實現(xiàn)個別bean懶加載的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
spring-data-redis連接操作redis的實現(xiàn)
spring-data-redis則是對Jedis進行了高度封裝,使用起來非常方便。本文主要介紹了spring-data-redis連接操作redis的實現(xiàn),感興趣的可以了解一下2021-07-07

