是一种基于jpa进行的再次封装的框架,其底层原理还是由其他框架实现的(这里用的是hibernate)
单元测试 junit 4.9 Aspectjweaver 支持切入点表达式和aop相关注解 Spring相关 版本都是4.2.4.RELEASE Spring-aop aop切面编程的支持包 Spring-test 单元测试和集成测试的简单封装 Spring-context Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等 Spring-context-support 拓展支持,用于MVC方面 Spring-beans spring ioc的基础实现 Spring-core spring核心组件 Spring-orm 整合第三方的orm框架 Hibernate相关 版本 5.0.7.Final Hibernate-core hibernate核心包 Hibernate-entitymanager 实体管理包(和jpa整合) Hibernate-validator 参数校验 C3p0 0.9.1.2 连接池 Log4j 1.2.12 日志 Slf4j-log4j12 1.6.6 Mysql-connector-java 5.1.6 数据库 Spring-data-jpa 1.9.0.RELEASE spring-data-jpa 核心包 Javax.el-api 2.2.4 必须导入的包 Javax.el 2.2.4
将注解映射到数据库表中,配置和jpa配置相同
需要继承两个接口JpaRepository<T,ID>和JpaSpecificationExecutor T 代表实体类 ID代表 实体类的主键
public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer>1.JpaRepository<T,ID>提供了一些简单的数据库操作方法 FindOne 通过主键查询单个 Sava 保存,如果有主键就更新,没有就添加 Delete 通过主键删除 FindAll 查询所有 2.复杂的操作有多种方式进行查询
JPQL查询(查询需要加上Query注解,修改还需要加上Modifying注解) //查询 @Query(value = "from Customer where custName= ? ") Customer findByName(String name); //更新,1代表第一个参数,2代表第二个参数,表示方法定义的时候两个参数的顺序 @Query(value = "update Customer set custName=?1 where custId=?2") @Modifying void update(String custName,long custId);调用更新方法的时候,因为需要对数据库内容进行修改,所以需要配置事务注解 @Transactional @Rollback(value = false)
使用sql语句 //查询 @Query(value = "select * from cst_customer",nativeQuery = true) public List<Customer> findBySql(); //更新 @Query(value = "update cst_customer set cust_name=? where cust_id=?",nativeQuery = true) @Modifying void updatesql(String custName,long custId);使用sql语句,只需要在@Query注解上面加上nativeQuery = true就可以了,其余和jsql的方式一样
3.使用方法查询,由jpa内部自动生成sql语句进行创建
方法查询的规范 find+全局修饰+By+实体属性名称+限定词+连接词+(其他实体属性)+OrderBy+排序属性+排序方向 如:findDistinctByFirstNameIgnoreCaseAndLastNameOrderByAgeDesc(String firstName,String lastName) 4.使用Spring data jpa 中JpaSpecificationExecutor接口 我们要使用其中的方法就必须了解Specification接口 它定义了一个方法toPredicate 其中 有三个参数Root (代表想要查询表的实体类) CriteriaQuery 顶层查询 CriteriaBuilder 具体查询标准 ①相关查询 精确查询: cb.equla(root.get(“custName”),”哈哈”); 并列查询: cb.equla(root.get(“custName”),”哈哈”); cb.equla(root.get(“custId”),”1”); cb.and(p1,p2); 模糊查询: cb.like(root.get(“custName”).as(String.class),”哈%”); 排序查询: 排序查询只需要创建一个排序对象 Sort sort=new Sort(Sort.Direction.DESC,”custName”);第一个参数代表排序方式,第二个表示通过哪个属性排序 分页查询: 分页查询需要一个Pageable对象这个 声明该对象 Pageable pageable=new PageRequest(0,3) 第一个参数从哪开始 第二个参数 一页有几个数据 然后通过customerDao接口调用方法 返回一个分页对象 这个对象是spring data jpa 所提供的 里面包含分页需要的所有属性 totalElements获总数据数量 totalPages 获得一页有几个数据 content 表示 返回的内容
//一般查询 Specification<Customer> spec=new Specification<Customer>(){ public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) { //root就是 相当于实体类对象 query 自定义查询 cb:构建查询 return cb.like(root.get("custName").as(String.class),"7%"); } }; List<Customer> all = customerDao.findAll(spec); //排序查询 customerDao.findAll(new Sort(Sort.Direction.DESC,"custName") //分页查询 Pageable pageable=new PageRequest(0,3); Page<Customer> customers = customerDao.findAll(pageable); System.out.println(customers.getTotalElements()); System.out.println(customers.getTotalPages()); System.out.println(customers.getContent());一的一方:
/* @OneToMany(targetEntity = LinkMan.class) @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")*/ @OneToMany(mappedBy = "customer",cascade = CascadeType.ALL) private Set<LinkMan> linkmans=new HashSet<LinkMan>();多的一方:
@ManyToOne(targetEntity = Customer.class,fetch =FetchType.LAZY ) @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id") private Customer customer;操作在于 1的一方需要有一个存储多的一方的集合,并且需要加上注释@OneToMany(mappedBy=”customer”,cascade=Cascade.Type.ALL) 其中mappedBy 表示放弃维护权,第二个代表级联操作:操作一个对象同时操作它的关联对象 为何要放弃维护权? 因为多对一方再保存的时候已经保存了外键信息,所以不需要再进行更新了 多的一方需要添加一个一的一方的对象同时需要加上注释 @ManyToOne(targetEntity=Customer.class,fetch=FetchType.LAZY) @JoinColumn(name=”lkm_cust_id”,referencedColumnName=”cust_id”) 第一个代表多对一,属性为 目标实体类 需要一方面的字节码文件,还可以配置加载方式 LAZY为懒加载,EAGER为直接加载 第二个注释中 名字为 外键名,第二个为该外键在主表的名字
Add:需要加上@Transaction和@Rollback(注释) 添加的时候 因为使用级联操作,所以只需要在主方进行保存(一方) Delete:删除的时候,一方删除就可以了 Update:无特殊 Search:查询的时候通过对象导航进行查询,但是再toString方法中一定要删除其中一个的输出另一个类的方法,不然会无限循环,出错 同时查询要加上@Transactional注释
双方:
//role方 @ManyToMany(targetEntity = User.class,cascade = CascadeType.ALL) @JoinTable(name = "role_user",joinColumns = { @JoinColumn(name = "ru_role_id",referencedColumnName = "role_id") },inverseJoinColumns = { @JoinColumn(name = "ru_user_id",referencedColumnName = "user_id") }) private Set<User> users=new HashSet<User>(); --------------------------------------------- //user方 @ManyToMany(mappedBy = "users") private Set<Role> roles=new HashSet<Role>();建议多对多的时候也是 一个负责 维护 一个放弃 需要在两个类中各加入一个对方的集合 在集合上面进行配置
主 类 @ManyToMany(targetEntity=User.class,cascade=CascadeType.ALL) @JoinTable(name=”role_user”,joinColumns={ @JoinColumn(name=”ru_role_id,referencedColumnName=”role_id”) },inverseJoinColumns={@JoinColumn(name=”ru_user_id”,referencedColumnName=”user_id”)} ) 其中JoinTable为中间表 joinColumns 中 name为中间表中的主外键名 referencedColumnName为 主表中名 inverseJoinColumns中第一个为中间表中另一个表的外键名 referencedColumnName为 另一个表中的主表外键名
第二个类只需要在集合方法上加上@ManyToMany(mappedBy=”users”)
增加:主类操作 删除:主类进行删除(会删除所有相关) 修改:各改各的 查:互相的都可以查,但是toString中 要删除一个 否则会报错 一方查多方:默认延迟加载,因为多方数据多 多方查一方:默认即时加载,因为一方数据只有一条