1.什么是JPA?
JPA全称是Java Persistence API的简称,中文名是:java持久层API,是JDK5.0注解或XML描述对象-关系表的映射关系,并将运行器的试题对象持久化到数据库中,可以理解为,java代码操作对象,实现对数据库的简介操作。
提到映射,还是对象-关系表,那我们可以聊一下ORM。
那ORM又是什么?
ORM全称是Object Relational Mapping,中文名对象关系映射,跟JPA原理一样,也是通过操作对象操作数据库,因为JPA是基于ORM封装的。
常见的ORM框架有:Hiberate TopLink OpenJPA
可能有点抽象,举个例子,众所周知,数据库的驱动有很多,最出名的是MySQL和Oracle这两个驱动,我们平常写代码经常会说到JDBC,没错,我们操作数据库,一般是通过JDBC调用驱动来操作的,也就是说,可以把JDBC理解成食物链的顶端。
JPA通过ORM的框架,也是一跃成为另一个食物链的顶端。
2.JPA有哪些常用注解呢?
我们可以看一下实体类的代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity //标注实体类
@Table(name = "user") //关联表
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Integer id;
@Column
private String username;
@Column
private String birthday;
@Column
private String sex;
@Column
private String address;
}
上面的三个注解是lombok的注解:
@Data是getter和setter方法,
@AllArgsConstructor是有参构造
@NoArgsConstructor是无参构造
@Entity是指定当前是实例类
@Column说明该属性与数据库字段的对应关系,如果字段与属性名一样,则可以省略
@Table(name = "user") 指定我们操作的表名是user表
@Id指定当前字段是主键id @GeneratedValue(strategy = GenerationType.IDETITY)指定当前主键id自增(这里选择不一定非要自增,strategy有四种属性可以选择)
public enum GenerationType {
TABLE,
SEQUENCE,
IDENTITY,
AUTO;
private GenerationType() {
}
}
3.JPA的核心配置文件
江湖有言,每个框架都有自己的配置文件,JPA也不例外,它的位置是在java工程下的src下的resources文件夹下面,创建一个MATA-INF的文件夹,在此文件夹下创建一个名为persistence.xml的配置文件。
文件里面猜到可以猜到一半,是不是肯定要配置数据库。不然没有驱动没有地址,去哪里找这个数据表嘞。
这个网上一抓一大把,这里就不扯配置文件的代码了。
4.CRUD的基本操作
这是每次增删改查都会执行的代码,我这边把它提取出来,你可以理解为这里的意思是
在操作之前链接数据库,开启事务
在操作方法之后,提交事务,关闭资源。
private EntityManagerFactory factory=null;
private EntityManager manager=null;
private EntityTransaction tx=null;
@Before
public void before(){
factory = Persistence.createEntityManagerFactory("mysql");
manager = factory.createEntityManager();
tx = manager.getTransaction();
tx.begin();
}
@After
public void after(){
tx.commit();
manager.close();
factory.close();
}
那我们来看看核心代码
新增的代码
@Test
public void test01(){
User user=new User();
user.setUsername("zx");
user.setAddress("揭西");
user.setBirthday("2020-20-20");
user.setSex("男");
manager.persist(user);
}
查询所有数据的代码
@Test
public void test1() throws Exception{
String jpql="from User";
Query query = manager.createQuery(jpql);
List<User> userList = query.getResultList();
for (User user : userList) {
System.out.println(user);
}
}
注意一下,这个"from User",User是实体类,不要写成表名user
这里没有举name多的例子,当然,也是可以采用sql语句的,这是特殊情况,所有还是大写的User
//统计查询
@Test
public void test4() throws Exception{
String jpql="select count(*) from User";
Query query = manager.createQuery(jpql);
Object count = query.getSingleResult();
System.out.println(count);
}
5.SpringDataJPA
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,通俗易懂来说,之前的JPA已经站在了number One的位置,但是SPringDataJPA还在它上面,直接走上人生巅峰了。
实体类的话和JPA一样,这里说一下dao接口;
/**
* JpaRepository<实体类,id的类型>:普通增删改查
* JpaSpecificationExecutor<实体类>:用于复杂多条件查询
*/
@Repository
public interface UserDao extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
}
但是CRUD就和JPA不太一样了。
它有很多方式实现
@Repository
public interface UserDao extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
//这里的User是entity中实体类,不是数据库的表名
@Query("from User")
List<User> findAll();
@Query("from User where id=?1")
Optional<User> findById(Integer id);
@Query("update User set username=?1 where id=?2")
@Modifying
//防止回滚
void update(String username, Integer id);
//原始的sql数据,这里的标就是数据库表user
@Query(value = "select * from user where id= ?1", nativeQuery = true)
User findById_SQL(Integer id);
@Query(value = "delete from user where id=?1", nativeQuery = true)
@Modifying
void deleteById_SQL(int id);
//命名规则查询
User findByUsername(String username);
List<User> findByUsernameLike(String username);
List<User> findByUsernameLikeOrderByIdDesc(String username);
}
1.可以像JPA一样,查询全部直接“from User”
2.写入sql语句,注意一下,删改这些操作我们都要防止它回滚
3.SpringDataJPA提供了一些命名规则,只要方法名写对了,直接什么sql都不用写,调用这个方法就ok了
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring.xml")
public class Demo01 {
@Autowired
private UserDao userDao;
//命名规则查询
@Test
public void test001() throws Exception{
User user = userDao.findByUsername("李四");
System.out.println(user);
}
}
这篇文章不是很详细,对这两个有大概的了解即可。