@Repository
public
interface
PersonDao
extends
JpaRepository
<
PersonPO
,
String
>
,
JpaSpecificationExecutor
<
PersonPO
>
{
在controller层注入,并调用即可
在dao接口中,可以通过jpa的条件构建规则来写一个方法,也可以自定义sql,通常构建规则只能解决简单的需求,复杂的需求还是需要手动写sql来实现。(称作JPQL语句,
注意JPQL不支持insert操作
)
@Modifying
@Transactional
@Query("update CityStationGoods csg set csg.isOnsale = ?2 where csg.id = ?1",nativeQuery=false)
int updateOnSaleState(int id, Boolean isOnsale);
注意:@Modifying
表示除查询外的操作,即对数据库数据有更改。@Transactional
表示事务,如果是变更操作需要开启事务才行(该注解可以写在Service或Repository中),@Query
的value指定sql,nativeQuery=true
表示使用数据库查询,即数据库中表:city_station_goods
,否则为本地查询,即使用映射后的实体类作为查询对象,本地PO实体:CityStationGoods
。
sql中的参数有两种写法:
- 使用占位符:?1,依据参数顺序从1到n
- 使用命名参数:
:name
,相应的方法中的参数需要加上注解:@Param("name") String name
,
调用继承过来的方法方法:save()
或者saveAll()
,传入一个实体或者实体列表进行保存
直接编辑SQL
默认的删除方法有:
- delete(实体),只能传入一个可以对应到数据库的实体,即数据库中存在一样的数据的实体
- deleteInBatch(实体的迭代器),传入一个实体列表,实体同上,在一个语句中进行删除,使用or拼接id(where id=? or id=?..)
- deleteAll(),删除所有数据项,不过是一条一条删除,会先查询所有项,再删除
- deleteAll(实体的迭代器),删除所有传入的实体,一条一条删除,
- deleteAllInBatch(),删除所有数据,一条语句中拼接id删除,同样会先查询出所有的,再删除
- deleteById(String id),根据id删除某一条数据项
我的需求是根据某个条件删除符合该条件的所有数据项,如果使用默认方法,需要先查询到所有符合的数据项,然后传给删除方法,但是,查询出所有数据项的所有字段增加了网络传输,降低了效率,实际上只需要查出符合条件的id列表即可定位数据项。然后需要批量删除。这个需求只能自己写sql:
@Repository
public interface PersonDao extends JpaRepository<PersonPO,String>, JpaSpecificationExecutor<PersonPO>{
@Query(value="select id from tb_person where age>?1 limit 0,?2",nativeQuery=true)
List<String> findId(int age,int num);
@Transactional
@Modifying
@Query(value="delete from tb_person where id in ?1",nativeQuery=true)
int deleteInIds(List<String> ids);
注意:如果查询出来的数据字段不是全部,则返回值如果写成List<PersonPO>
可能会报错,如果删除数据过多,建议分批次删除,即查询的时候限制数量,多次查询多次删除。
查询可以使用方法命名规则,也可以使用sql来查询,如果是多条件查询,可以使用:Specification
命名规则:
手写SQL多条件查询:
@Query(nativeQuery = true, value = "SELECT COUNT(1) FROM trade_info t LEFT JOIN role_info r ON t.role_id = r.id " +
"WHERE t.order_pay_state <> 1 AND r.nick_name LIKE :nickName" +
"AND IF(:platform=0, t.pay_type<>0, t.pay_type=:platform) " +
"AND IF(:maxTime=0, t.create_time IS NOT NULL, UNIX_TIMESTAMP(t.create_time) <= :maxTime) " +
"AND IF(:minTime=0, t.create_time IS NOT NULL, UNIX_TIMESTAMP(t.create_time) >= :minTime) ")
public int findFailCount(@Param("nickName") String nickName,
@Param("platform") Integer platform,
@Param("maxTime") Long maxTime,
@Param("minTime") Long minTime);
不过这里要注意几个点
1.如果加了@Param这个注解,那SQL里面一定要用冒号来引入参数,如 :key
2.如果没有加@Param,那需要用问号来引入参数,如 ?1
使用Specification:
Specification<PersonPO> spec = new Specification<PersonPO>(){
@override
public Predicate toPredicate(Root<PersonPO> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> pList = new ArrayList<>();
if(StringUtils.isNotEmpty(name)){
pList.add(criteriaBuilder.like(root.get("name").as(String.class), "%"+name+"%"));
if(StringUtils.isNotEmpty(code)){
pList.add(criteriaBuilder.equal(root.get("name").as(String.class), code));
Predicate[] p = new Predicate[pList.size()];
return criteriaBuilder.and(pList.toArray(p));
Page<PersonPO> all = personDao.findAll(spec,PageRequest.of(pageNum,pageSize));
int dataList = all.getContent();
int num = all.getTotalElements();
注意:如果多条件查询中,既有and又有or:criteriaQuery.where(predicateAnd,predicateOR).getRestriction()
返回一个组合predicate
分页功能实现需要继承JpaRepository
调用:personDao.findAll(PageRequest.of(pageNum,pageSize))
即可
springboot jpa使用:写一个dao层,定义一个类// PersonDao.java@Repositorypublic interface PersonDao extends JpaRepository<PersonPO,String>, JpaSpecificationExecutor<PersonPO>{}在controller层注入该类,并调用即可默认的删除方法有:delete(实体),只能传入一个可以对应到数据库的实体,即数据库中存在一样的数据
1.1 JDBC 2
1.2关系对象映射(Object Relational Mapping,ORM) 2
1.3 Java数据对象(Java Data Object,JDO) 2
1.4 Java Persistence API(JPA) 2
2. JPA体系架构 3
清单1在非Java EE环境使用JPA接口的例子 5
清单2在容器中运行的JPA例子 5
3. Entity Bean 6
3.1定义对Entity中属性变量的访问 6
3.2主键和实体标识(Primary Key and Entity Identity) 8
4. EntityManager 9
4.1配置和获得EntityManager 9
4.2 Entity的生命周期和状态 10
4.3持久化Entity(Persist) 11
4.4获取Entity 13
4.5更新Entity 13
4.6删除Entity 14
4.7脱离/附合(Detach/Merge) 14
5. JPA Query 15
5.1 Query接口 15
5.2简单查询 16
5.3使用参数查询 17
5.4排序(order by) 17
5.5查询部分属性 18
5.6查询中使用构造器(Constructor) 18
5.7聚合查询(Aggregation) 19
5.8关联(join) 20
5.9比较Entity 22
5.10批量更新(Batch Update) 22
5.11批量删除(Batch Remove) 22
本文出处:https://www.jianshu.com/p/c84a91992c32
SpringDataJPA到目前为止已经解决了大量的问题,但依然还有一些比较重要的问题没有解决:
…批量删除和更新的操作
…事务处理问题
Spring最大的一个优点就是声明式的事务,在原来的开发环境中我们需要在beans.xml中配置事务在哪些类上有作用,现在SpringBoot已经帮助我们完成了这些配置,我们仅仅需要加几个Annotation就可以解决问题。
我们假设我们的开发环境是这样的:有两个类,一个是Classr
<input type=text name=dishes value= class=seek_product placeholder=请输入菜名/>
<button type='button' class=btn_nor onclick=seek_product()>搜索</button>
<th width=70%
chapter1:基本项目构建(可作为工程脚手架),引入web模块,完成一个简单的RESTful API
使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程
chapter2-1-1:配置文件详解:自定义属性、随机数、多环境配置等
chapter2-1-2:2.0 新特性(一):配置绑定全解析
chapter2-2-1:2.0 新特性(二):新增事件ApplicationStartedEvent
Web开发
chapter3-1-1:构建一个较为复杂的RESTful API以及单元测试
chapter3-1-2:使用Thymeleaf模板引擎渲染web视图
chapter3-1-3:使用Freemarker模板引擎渲染web视图
chapter3-1-4:使用Velocity模板引擎渲染web视图
chapter3-1-5:使用Swagger2构建RESTful API
chapter3-1-6:统一异常处理
chapter3-1-7:使用Java 8中LocalDate等时间日期类的问题解决
chapter3-1-8:扩展XML请求和响应的支持
数据访问
chapter3-2-1:使用JdbcTemplate
chapter3-2-2:使用Spring-data-jpa简化数据访问层(推荐)
chapter3-2-3:多数据源配置(一):JdbcTemplate
chapter3-2-4:多数据源配置(二):Spring-data-jpa
chapter3-2-5:使用NoSQL数据库(一):Redis
chapter3-2-6:使用NoSQL数据库(二):MongoDB
chapter3-2-7:整合MyBatis
chapter3-2-8:MyBatis注解配置详解
chapter3-2-9:使用Flyway来管理数据库版本
chapter3-2-10:使用LDAP来统一管理用户信息
chapter3-2-11:Spring Boot中增强对MongoDB的配置(连接池等)
chapter3-3-1:使用事务管理
chapter3-3-2:[分布式事务(未完成)]
chapter4-1-1:使用@Scheduled创建定时任务
chapter4-1-2:使用@Async实现异步调用
chapter4-1-3:使用@Async实现异步调用:自定义线程池
chapter4-1-4:使用@Async实现异步调用:资源优雅关闭
chapter4-1-5:使用@Async实现异步调用:使用Future以及定义超时
chapter4-2-1:默认日志的配置
chapter4-2-2:使用log4j记录日志
chapter4-2-3:对log4j进行多环境不同日志级别的控制
chapter4-2-4:使用AOP统一处理Web请求日志
chapter4-2-5:使用log4j记录日志到MongoDB
chapter4-2-6:Spring Boot 1.5.x新特性:动态修改日志级别]
chapter4-3-1:使用Spring Security
chapter4-3-2:[使用Spring Session(未完成)]
chapter4-4-1:注解配置与EhCache使用
chapter4-4-2:使用Redis做集中式缓存
chapter4-5-1:实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件
chapter5-1-1:[JMS(未完成)]
chapter5-2-1:Spring Boot中使用RabbitMQ
chapter6-1-1:使用Spring StateMachine框架实现状态机
Spring Boot Actuator监控端点小结
在传统Spring应用中使用spring-boot-actuator模块提供监控端点
Spring Boot应用的后台运行配置
Spring Boot自定义Banner
Dubbo进行服务治理
chapter9-2-1:Spring Boot中使用Dubbo进行服务治理
chapter9-2-2:Spring Boot与Dubbo中管理服务依赖