目录
- JPA 介绍
- JPA 简单使用示例
- JPA 实体类中相关注解说明
- JPA 持久层关键字说明
- 实战-JPA企业开发示例
- 1. 实体继承基础通用属性
- 2. 查询
- 2.1 条件查询
- 2.2 查询排序
- 2.3 分页查询
- 2.4 动态条件查询
- 2.5 多表联查
- 2.6 返回自定义Vo
- 3. 修改和删除
- 踩坑
JPA 介绍
JPA(Java Persistence API),对象关系映射(ORM)框架规范,是一种Java持久化规范。jpa可以通过实体类生成数据库的表,同时自带很多增删改查方法,大部分sql语句不需要我们自己写,配置完成后直接调用方法即可,很方便。
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驱动 依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
2. application.properties配置
# 数据库连接配置
spring.datasource.url = jdbc:mysql://localhost:3306/manageserver?serverTimezone=Asia/Shanghaispring.datasource.username = rootspandroidring.datasource.password = 123456spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver# jpa配置# 自动更新数据库表spring.jpa.hibernate.ddl-auto=updatespring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy# 是否在控制台显示Hibernate的sqlspring.jpa.show-sql = false
3. 创建实体类对象,用于映射数据库表
@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. 创建持久化接口DAO,继承JpaRepository,用于对数据库进行操作
@Repository public interface DictionaryDao extends JpaRepository<DbDictionary, String> { }
5. 至此,JPA基本配置已经完成,这里自带很多内置的增删改查方法,不用我们自己写sql语句,直接调用即可。
JPA 实体类中相关js注解说明
@Entity
:表明是一个实体类@Table(name = "dict_info")
:对应的数据表名,与@Entity注解一块使用,但是如果表名和实体类名相同的话,@Table可以省略@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
:自定义hibernate主键生成策略@Id
:表示当前字段为主键@GeneratedValue(generator = "jpa-uuid")
:指定主键生成策略为uuid@Column(name = "DICTNAME")
:当实体类的属性与其映射的数据库表的列不同名时需要使用@Column 标注说明@CreatedDate
:创建时间@LastModifiedDate
:更新时间@Temporal(TemporalType.TIMESTAMP)
:实体类会封装成完整的时间“yyyy-MM-dd hh:MM:ss”的 Date类型@Transient
:表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性
JPA 持久层关键字说明
JPA Data的使用模式已经帮我集成了日常一些关键字用法,通过查询可以直接使用!
关键字 | 方法命名 | 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(?) |
实战-JPA企业开发示例
1. 实体继承基础通用属性
/** * 实体继承映射类基础 ,保存实体的通用属性 */ @Data @Accessors(chain = true) @MappedSuperclass //实体继承映射 public abstract class BaseEntity implements Serializable { /** * 创建者 */ @Basic @Column(length = 50) private String creator; /** * 修改者 */ @Basic @Column(length = 50) private String modifier; /** * 创建时间 */ @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 条件查询
条件查询有两种方式,一是直接使用持久层提供的关键字,二是自己写查询SQL。
// 根据名称和性别查询用户 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); //按创建时间倒序排列 Sort.by("createTime").descending()
2.3 分页查询
Page<T> findAll(Pageable pageable); /*获取分页参数*/ public PageRequest getPageRequest() { return getPageRequest(Sort.unsorted()); } /*获取分页和排序参数*/ public http://www.devze.comPageRequest getPageRequest(Sort sort) { ServletRequestAttributes attributes = getServletRequestAttributes(); if (StringUtils.hasText(attributes.getRequest().getParameter("page")) && StringUtils.hasT开发者_自学开发ext(attributes.getRequest().getParameter("size"))) { www.devze.com 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 动态条件查询
动态条件查询Specification
,DAO需要再继承JpASPecificationExecuto
r接口
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)); } // 数字 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 多表联查
@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)会被javascriptjpa识别为查询语句,只有传入参数是列表时才是用deleteAllByxxx(List<String> s)
推荐使用原生sql,自带的delete或者deleteAll会先进行查询,然后在查询结果上面挨个执行删除,并不是一条sql执行完删除操作,所以还是建议自己写delete
到此这篇关于SpringBoot Jpa企业开发示例详细讲解的文章就介绍到这了,更多相关SpringBoot Jpa内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
精彩评论