Spring data JPA的使用

依赖

		<!-- JPA -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<!-- WEB -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- ORACLE,直接导入不起作用,下jar文件打包成maven的坐标 -->
		<dependency>
			<groupId>com.oracle</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>11.2.0.3</version>
		</dependency>

配置文件

spring.datasource.url=jdbc:oracle:thin:@ip:port:orcl
spring.datasource.username=111
spring.datasource.password=111
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.hibernate.ddl-auto=create
#create每次都会重新创建数据库表,update有表不会重新创建会刷新字段,没有表会重新创建表。
spring.jpa.show-sql=true
#打印执行的SQl

实体

@Entity,作用在类上,表示与数据库的表(默认类名)映射。可以使用name指定表。
@Table,作用在类上,表示指定数据库的表,跟@Entity的name属性功能差不多。
@Id,作用在属性上,标识该属性是主键,与数据库表的主键对应。(一般都得写)
@Column,作用在属性上,标识该属性是普通属性与数据库表字段对应(默认属性名对应,属性名驼峰命名和表的字段下划线命名可以对应),可以用name属性指定与数据库表字段的对应。(属性名跟表的字段名对应可以不写)
Mysql主键生成策略:
@GeneratedValue():整形自增。

Oracle主键生成策略:
整形,序列的方式:

@GeneratedValue(generator = "sequenceGenerator")//随便写个主键策略名称
@GenericGenerator(
		name = "sequenceGenerator", //与上边对应
		strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",//主键生成策略
		parameters = {
				@Parameter(name = "sequence_name", //传递参数(sequence_name表示创建序列)
						value = "SEQ_CUSTOMER_ID")//序列名称,ddl为update或者create时自动创建
				}
		)

字符串主键,uuid的方式:

@GenericGenerator(name="sequeneceGenerator",strategy="uuid")
@GeneratedValue(generator="sequeneceGenerator")

表的联系,一对多:

	 * 1.声明关系
	 * 		@ManyToOne or @OneToMany
	 * 			targetEntity:对方字节码对象
	 * 2.配置外键
	 * 		@JoinColumn
	 * 			name:在多的一方生成数据库的外键名称
	 * 			referencedColumnName:自己表的主键名称(外键数据来源)
	 * 3.放弃外键维护
	 * 		mappedBy:去掉外键维护后应该指定与关联对象的属性名称
	 * 4.级联操作
	 * 		cascade:表示执行什么操作时,的级联操作
	 * 				1.删除:删除所有关联对象
	 * 				2.查找:查找关联对象
	 * 				...
	 * 注意:一的那边放弃外键维护

一的实体配置:
@OneToMany(targetEntity=Order.class,mappedBy="customers",cascade=CascadeType.ALL)
private List<Order> orders;

多的实体配置:
@ManyToOne(targetEntity = Customer.class)
@JoinColumn(name = "customer_id", referencedColumnName = "id")
private Customer customers = new Customer();

持久层Repository

* JpaRepository<实体类名称,主键类型>
* 继承JpaRepository这个接口,这个类已经放到spring容器中了。
* JpaRepository内置了数据库表的操作函数
public interface CustomerRepository extends JpaRepository<Customer, Long> {
* 自定义sql语句
* nativeQuery=true,开启原生sql查询
* Paramz指定参数名称
* @Modifying 允许修改(增删改要加)
* @Transactional开启事务,注意是org.springframework.transaction.annotation.Transactional
	@Query(value="select l.id,l.age,l.create_time,l.name from L_TEST l where l.age>:age",nativeQuery=true)
	List<Customer> findByMinAge(@Param("age")Integer age);
}

服务层ServiceImpl

第一步:加个@Service把类放到spring容器中去。
介绍持久层的函数。
save(entity):保存或者更新一个对象,当entity没有主键时新增数据并且将数据库自增的主键返回到entity中,有主键时更新数据。
deleteById(id):根据id删除一条数据,id不存在抛出异常。
findById(id):根据id查找数据,数据库id不存在跑出异常。一般用法:

* 表示根据id查找数据,查不到返回nullOrder order = orderRepository.findById(id).orElse(null);

findAll():查全部。

JPA的语法规则

JPA会根据函数的名称去执行特定的语法规则,非常的方便快捷。

1.按实体的字段查询(注意驼峰)
findBy(第一个条件)And(第二个条件)***

* 查询指定年龄的用户
List<User> findByAge(String age);
* 查询指定年龄和指定名称的用户
List<User> findByAgeAndName(String age,String name);

2.in条件查询
findBy(条件)In

* 查询用户id在ids中的用户
List<User> findByIdsIn(List<String> ids);
* 查询用户id在ids中并且指定名称的用户
List<User> findByIdsInAndUserName(List<String> ids,String name);

JPA过滤查询

实体:
@Entity
@Table(name = "T_ARTICLE")
public class Article {
	@Id
	@GeneratedValue(generator = "uuid") 
	@GenericGenerator(name = "uuid", strategy = "uuid")
	private String id;
	private String code;
	private Timestamp createTime;
	private Boolean flag;
	@OneToOne(optional=true)
    @JoinColumn(name="school_id", unique=false, nullable=true, updatable=true)
	private School school;
}
持久层:
public interface ArticleRepository extends JpaRepository<Article, String>, JpaSpecificationExecutor<Article> {
}	
构造过滤条件:
public Specification<Article> getSpecificationByParams(String id,String code,Timestamp createTime,Boolean flag){
		return new Specification<Article>() {
			private static final long serialVersionUID = 1L;
			@Override
			public Predicate toPredicate(Root<Article> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				//去重查询
				query.distinct(true);
				List<Predicate> predicates = new ArrayList<Predicate>();
				//or条件空值判断
				predicates.add(cb.or(cb.isFalse(root.<Boolean>get("flag")),cb.isNull(root.get("delFlag"))));
				//等值判断
				if(null != code&& !"".equals(code)) {
					predicates.add(cb.equal(root.<String>get("code"), code));
				}
				//or 条件
				if(null != code && !"".equals(code)) {
					String[] codes = code.split("-");
					List<Predicate> preOr = new ArrayList<Predicate>();
					for (String c: codes) {
						preOr.add(cb.equal(root.<String>get("c"), c));
					}
					Predicate[] pr = preOr.toArray(new Predicate[]{});
					predicates.add(cb.or(pr));
				}
				//大于等于
				if(null != startTime) {
					predicates.add(cb.greaterThanOrEqualTo(root.<Timestamp>get("updateTime"), createTime));
				}
				//小于
				if(null != endTime) {
					predicates.add(cb.lessThanOrEqualTo(root.<Timestamp>get("updateTime"), createTime));
				}
				//模糊查询
				if(null != code && !"".equals(code)) {
					predicates.add(cb.like(root.<String>get("code"), "%"+code+"%"));
				}
				
				//多表关联
				Subquery<String> articleSemiQ = getMagazineFavTypeSubquery.(query,cb,creditCode)
				
				//若是配置对象
				predicates.add(root.<Long> get("school").get("id").in(schoolId));
				predicates.add(root.get("id").in(articleSemiQ));
			//返回结果
				return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
			}
		};
	}

public Subquery<String> getMagazineFavTypeSubquery(CriteriaQuery<?> query, CriteriaBuilder cb, String code) {
		//设置返回值类型
		Subquery<String> semiQ = query.subquery(String.class);
		//实体类
		Root<Favoriten> semiRoot = semiQ.from(Favoriten.class);
		//返回字段
		semiQ.select(semiRoot.get("id"));
		//设置过滤条件
		List<Predicate> subQPredicates = new ArrayList<>();
		subQPredicates.add(cb.equal(semiRoot.get("code"), code));
		//返回值
		semiQ.where(subQPredicates.toArray(new Predicate[subQPredicates.size()]));
		return semiQ;
	}
添加分页条件:
1.单个分页
PageRequest pageParam = PageRequest.of(pageNum,pageSize,Sort.by(Direction.DESC,"updateTime"));
2.多个分页
List<Order> sortlist = new ArrayList<>();
sortlist.add(new Order(Direction.DESC,"publishTime"));
sortlist.add(new Order(Direction.ASC, "typeId"));
sortlist.add(new Order(Direction.DESC, "issue"));
Sort sort = Sort.by(sortlist);
Pageable pageParam = PageRequest.of(pageNum, pageSize, sort);
查询结果:
Page<Article> articlePages = this.articleRepository.findAll(specification, pageParam);

调用存储过程

	@PersistenceContext
	private EntityManager em;
	String a = "";
	String b = "";
	boolean result = true;
	Query query = em.createNativeQuery("{call tmp_test(:p1,:p2)}");
	query.setParameter("p1", a);
	query.setParameter("p2", b);
	query.executeUpdate();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值