在上文中写了关于Spring boot 2.0下 关于 mybatis 多数据源的配置,接下来小篇幅的介绍下
JPA 在项目中如何去使用什么
首页我们了解一些什么是JPA :
JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分。但它又不限于EJB 3.0,你可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化标准规范,由此可见,经过这几年的实践探索,能够脱离容器独立运行,方便开发和测试的理念已经深入人心了。Hibernate3.2+、TopLink 10.1.3以及OpenJPA都提供了JPA的实现。
JPA的总体思想和现有Hibernate、TopLink、JDO等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:
ORM映射元数据
JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
API
用来操作实体对象,执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
优势:
标准化
JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
容器级特性的支持
JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。
简单方便
JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java 类一样简单,没有任何的约束和限制,只需要使用 javax.persistence.Entity进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成。
查询能力
JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
高级特性
JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
那么在Spring boot 2.0中 它又是如何使用的呢
在pom 文件中
依赖于spring boot 这个框架中已经集成了,2.0的版本中 依赖于
hibernate 5.0 版本以上
看下项目在启动之后 的效果
说明 笔者使用的 spring boot 2.0.1 集成了 hibernate 5.2.16
在application.iml 中是如何体现他的配置的
下面我们来看几个具体的例子
UserController :
@RestController
@RequestMapping("/system/user")
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/{keywords}")
public List<Hr> getUsersByKeywords(@PathVariable(required = false) String keywords) {
List<Hr> users = userService.getUsersByKeywords(keywords);
return users;
}
@RequestMapping("/jpatest/{id}")
public List<String> getPlaysByKeywords(@PathVariable(required = false) long id) {
List<String> ids = userService.getAllTeamPlayers(id);
return ids;
}
}
实体bean
@Entity
public class Player {
@Id
@SequenceGenerator(name = "SEQ_ANSWER_OPTION", sequenceName = "SEQ_ANSWER_OPTION", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ANSWER_OPTION")
@Column(name = "ID", unique = true, nullable = false, precision = 18, scale = 0)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "num")
private int num;
@Column(name = "position")
private String position;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id", nullable = false)
private Team team;
public Player() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getPosition() {
return position;
}
UserService:
@Service
@Transactional
public class UserService {
@Autowired
UserMapper userMapper;
@Autowired
private PlayerRepository playerRepository;
@Autowired
private TeamRepository teamRepository;
public List<Hr> getUsersByKeywords(String keywords) {
try{
return userMapper.getUsersByKeywords(keywords);
}catch(Exception e){
e.printStackTrace();
}
return null;
}
public List<String> getAllTeamPlayers(long teamId) {
List<String> result = new ArrayList<String>();
List<Player> players = playerRepository.findByTeamId(teamId);
for (Player player : players) {
result.add(player.getName());
}
return result;
}
public void addBarcelonaPlayer(String name, String position, int number) {
Team barcelona = teamRepository.findByPlayers(11);
Player newPlayer = new Player();
newPlayer.setName(name);
newPlayer.setPosition(position);
newPlayer.setNum(number);
newPlayer.setTeam(barcelona);
playerRepository.save(newPlayer);
}
在这个例子中 由于笔者把mybatis 和jpa 的使用同时放在了一起
一般在项目中不建议这么去实现,两种持久化的框架使用的 sessionfactory 并不是同一个
事务控制会有问题。
这里的 以 PlayerRepository 为例
PlayerRepository :
import com.xdf.newcrm.bean.entity.*;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface PlayerRepository extends CrudRepository<Player, Long> {
List<Player> findByTeamId(long teamId);
}
CrudRepository 这个类的源代码 实现了很多对CRUD 的操作,对象都是泛型
源码内容
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S var1);
<S extends T> Iterable<S> saveAll(Iterable<S> var1);
Optional<T> findById(ID var1);
boolean existsById(ID var1);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> var1);
long count();
void deleteById(ID var1);
void delete(T var1);
void deleteAll(Iterable<? extends T> var1);
void deleteAll();
}
所以说基本的操作在不需要我们去关注 直接就可以去使用了
有兴趣可以自己动手试试