1.qbe查询
Probe:具有填充字段的域对象的实际实体类,即查询条件封装类[必填]
ExampleMatcher:如何匹配特定字段的匹配规则,可以重复使用多个示例。
Example:由探针和ExampleMatcher组成,用于创建查询。
限制:
1.不支持or
2.仅支持正则表达式等
@ToString
@NoArgsConstructor
@Setter
@Getter
@Entity
@Table(name = "tb_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
//注意映射的值~!
@Enumerated(EnumType.STRING)
@Column(name = "gender")
private Gender gender;
}
@AllArgsConstructor
@Getter
public enum Gender {
MAIL("男性"),FMAIL("女性");
private String name;
}
public interface UserRepository extends JpaRepository<User,Long> {
}
@Test
public void test3(){
//需要忽略掉主键,否则会查询
ExampleMatcher matcher=ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.STARTING))
//类似于条件的构建,有很多的with
.withIgnorePaths("id");
User user=new User();
user.setName("peace");
Example<User> ex= Example.of(user,matcher);
System.out.println(this.userRepository.findAll(ex));
}
2.JpaSpecificationExecutor的使用方法
Root<T>root:代表了可以查询操作的实体对象的根
CriteriaQuery<?> query:代表一个specific的顶层查询对象
CriteriaBuilder:用来构建CritiaQuery的构建器对象,起始相当于条件或者条件组合
@ToString
@Setter
@Getter
@Entity
@Table(name = "tb_stu")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id",unique = true,nullable = false)
private Long id;
@Column(name = "name",columnDefinition = "姓名")
private String name;
@Column(name = "age",columnDefinition = "年龄")
private Integer age;
@Column(name = "gender",columnDefinition = "性别")
private Character gender;
}
//JpaSpecificationExecutor接口不能单独使用,需要配置Jpa中其他接口一起使用
public interface StuRepo extends JpaRepository<Student,Long>,JpaSpecificationExecutor<Student> ,UdStuRepository{
@Query(value = "from Student where name= :username ")
Student findBJpql(String username);
@Query(value = "select * from tb_stu where name= ?",nativeQuery = true)
List<Student> findBySql(String username);
@Query(value = "update Student set name=:username where id=:id")
@Modifying//说明当前语句是更新语句
void updateByJpql(String username,long id);
}
@Test
public void test5() {
Specification<Student> spec = new Specification<Student>() {
/**
* 定义了查询条件
* @param root select * from t_users 封装了查询条件对象
* @param query 定义了一个基本的查询,查询了那些字段,排序是什么
* @param criteriaBuilder 创建一个查询条件
* @return
*/
@Override
public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
Predicate pre = criteriaBuilder.equal(root.get("name").as(String.class), "111");
// return pre;
//注意这种写法!返回的行以及对行的操作!
return query.where(pre).getRestriction();
}
};
Optional<Student> student = this.stuRepo.findOne(spec);
System.out.println(student.get());
}
自定义Repository
@ToString
@Setter
@Getter
@Entity
@Table(name = "tb_stu")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id",unique = true,nullable = false)
private Long id;
@Column(name = "name",columnDefinition = "姓名")
private String name;
@Column(name = "age",columnDefinition = "年龄")
private Integer age;
@Column(name = "gender",columnDefinition = "性别")
private Character gender;
}
@Repository(value = "UdStuRepository")
public interface UdStuRepository {
public Student findUserById(Long id);
}
//自定义方法注意命名
public class UdStuRepositoryImpl implements UdStuRepository {
@PersistenceContext(name = "entityManagerFactory")
private EntityManager em;
@Override
public Student findUserById(Long id) {
System.out.println("UDRepository");
return em.find(Student.class,id);
}
}
通常的封装方式为
3.实体监听器
自定义实体监听器:
https://blog.csdn.net/weixin_37968613/article/details/88554236
使用步骤:
【1】在对应注解中使用@EntityListener来引入监听器
【2】在对应的属性上引入@CreateBy
【3】实现AuditorAware接口告诉Jpa当前用户是谁
【4】enableJpaRepository上开启功能
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "tb_traveler")
@EntityListeners(AuditingEntityListener.class)
public class Traveler {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
@CreatedBy
@Column(name = "createUserid")
private String createUserid;
@LastModifiedBy
@Column(name = "lastModifiedUserid")
private String lastModifiedUserid;
@CreatedDate
@Column(name = "createTime")
private LocalDateTime createTime;
@LastModifiedDate
@Column(name = "lastModifiedTime")
private LocalDateTime lastModifiedTime;
}
public interface TravelerRepository extends JpaRepository<Traveler,Long> {
}
public class MyAuditorAware implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
//两种方式
//1.和SecurityContextHolder获取
//2.通过request里卖弄获取或者session里面取得
ServletRequestAttributes servletRequestAttributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String ip=servletRequestAttributes.getRequest().getRemoteAddr();
return Optional.ofNullable(ip);
}
}
@Test
public void test4(){
Traveler t=new Traveler();
t.setName("hello");
t.setAddress("zhengzhou");
this.travelerRepository.save(t);
}
MappedSuperclass:
https://www.cnblogs.com/zqyanywn/p/7753596.html
1.标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。
2.标注为@MappedSuperclass的类不能再标注@Entity或@Table注解,也无需实现序列化接口。
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
public abstract class AbstractAutitable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@CreatedDate
@Column(name = "createTime")
private LocalDateTime createTime;
@LastModifiedDate
@Column(name = "lastModifiedTime")
private LocalDateTime lastModifiedTime;
@CreatedBy
@Column(name = "createBy")
private String createBy;
@LastModifiedBy
@Column(name = "lastModifidBy")
private String lastModifidBy;
}
编写需要自定义实体监听器需要注意的地方
3.乐观锁的使用
-- 悲观锁
select * from user where id=1 for update;
update user set name='jack' where id=1;
-- 乐观锁
select uid,name,version from user where id=1;
update user set name='jack',version=version+1 where id=1 and version=1;
spring data jpa通过aop动态维护这个version值,从而更优雅地实现乐观锁。
实现原理关键源码
@EnbaleSpringDataWebSupport对web的支持,不怎么用
@PageableDefault改变默认的page和size
主从表的使用@MapKey
https://blog.csdn.net/wwwcomy/article/details/84922934
Druid配置,在阅读的时间需要查看配置类,按名知意的可以查看源码:
package com.alibaba.druid.spring.boot.autoconfigure;
然后点击对应的类来获取信息
对@Transactional注解的支持
事务隔离级别:
该注解需要注意的:
1.@Transactional只能被应用到public方法上,如果不是该访问权限,不会生效
2.用Spring事务管理器,由Spring来负责数据库打开、提交、回滚。遇到不受检查的例外会回滚。
3.建议在具体的类上使用@Transactional注解,如果你在使用基于类的代理是,事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。
4.事务有两种配置方法,aspectj也能配置!
声明式事务: