spring boot中jpa的注解使用

spring boot中jpa的注解使用

JPA简介

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。JPA的总体思想和现有Hibernate、TopLink、JDO等ORM框架大体一致。

jpa的实体类要和数据库一一对应,比如我对一条原生的sql查询语句建立了一个实体来存放数据,假设这个实体类叫User,结果运行之后,我的数据库里面就自动建了一个User表,里面内容是空的。

基于注解的使用

JAP的注解主要有一下这些:

注解 解释
@Entity 声明类为实体或表。
@Table 声明表名。
@Basic 指定非约束明确的各个字段。
@Embedded 指定类或它的值是一个可嵌入的类的实例的实体的属性。
@Id 指定的类的属性,用于识别(一个表中的主键)。
@GeneratedValue 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值。
@Transient 指定的属性,它是不持久的,即:该值永远不会存储在数据库中。
@Column 指定持久属性栏属性。
@SequenceGenerator 指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列。
@TableGenerator 指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表。
@AccessType 这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量。
@JoinColumn 指定一个实体组织或实体的集合。这是用在多对一和一对多关联。
@UniqueConstraint 指定的字段和用于主要或辅助表的唯一约束。
@ColumnResult 参考使用select子句的SQL查询中的列名。
@ManyToMany 定义了连接表之间的多对多一对多的关系。
@ManyToOne 定义了连接表之间的多对一的关系。
@OneToMany 定义了连接表之间存在一个一对多的关系。
@OneToOne 定义了连接表之间有一个一对一的关系。
@NamedQueries 指定命名查询的列表。
@NamedQuery 指定使用静态名称的查询。

Entity类

@Entity
@Table(name = "xwj_user", schema = "test")//(name)是对应的表的名称,(schema)是你的数据库名
public class FullTable {
    @Id
    private String id;
    private String field_cn;
    @Transient
    private List<Map<String,String>> fieldAsso;
}

@Entity声明这个类是一个对应的实体类,和Bean一样

@Table只需要表名也可以,还有一下其他属性没有写出来。如果没有这个注解的话,就按类名来找数据库中的表

@Id 表示这个表的主键,如果不定义主键会出错,定义了主键一定确保唯一,我就因为用同一个实体类查询多个表,结果由于主键的问题,主键相同的数据都会当成是同一条数据,造成了一些数据的丢失。

@Transient 表示这个字段不会存储到数据库中。可以灵活得自己添加进去

@Column 定义表的字段与实体类的属性对应,如果名字相同就可以省略。

Repository 和service

前面主要是实体类的,下面介绍一下Repository (资源库)

Repository 其实就是dao,负责数据访问,主要有以下这些常用的注解

注解 介绍
@Repository 定义dao
@Query 自定义sql语句
@PersistenceContext 持久化上下文

如果不使用@Repository,也可以继承一个接口,来看一个最简单的实现。

public interface TypeRepository extends JpaRepository<Type,String> {
    @Override
    List<Type> findAll();
}

Type是自己定义的实体类,指向的是数据库中的表,Spring Data给我们提供几个Repository ,封装好了一些基本功能。

  • Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别

  • CrudRepository: 继承Repository,实现了一组CRUD相关的方法

  • PagingAndSortingRepository: 继承CrudRepository,实现了一组分页排序相关的方法

  • JpaRepository: 继承PagingAndSortingRepository,实现一组JPA规范相关的方法

  • JpaSpecificationExecutor: 比较特殊,不属于Repository体系,实现一组JPA Criteria查询相关的方法 我们自己定义的XxxxRepository需要继承JpaRepository,这样我们的XxxxRepository接口就具备了通用的数据访问控制层的能力。

接口定义的findAll方法会自动执行sql语句(select * from Type),所以不需要你写sql语句。

service层调用

@Service
public class TestService {
@Autowired
private TypeRepository typeRepository;
public List<Type> findType() {
        List<Type> types = typeRepository.findAll();
        return typs;
    }
}

service层也很简单,只需简单的注解即可。


@Query可以自定义sql

@Repository
public interface TableNameRepository extends JpaRepository<Es2Table,String>{
    @Query(value = "select * from es2table " ,nativeQuery = true)
    List<Es2Table> findAllTable();
}

也可以自定义原始的sql语句

@Repository
public class QueryEntityImpl implements QueryEntity{
    @PersistenceContext
    private EntityManager entityManager;
    @Override
    public List<FullTable> findByTablename(String tablename) {
        String sql="select *, concat(field_EN,'@','"+tablename+"') id from "+tablename;
        List<FullTable> nativeQuery = this.entityManager.createNativeQuery(sql, FullTable.class).getResultList();
        return nativeQuery;
    }
}

这边我们看到了@PersistenceContext和EntityManager:

PersistenceContext,称为持久化上下文,它一般包含有当前事务范围内的,被管理的实体对象(Entity)的数据。每一个EntityManager,都会跟一个PersistenceContext相关联。PersistenceContext中存储的是实体对象的数据,而关系数据库中存储的是记录。

EntityManager称为实体管理器 ,是管理实体的,而前面提到PersistenceContext是存储实体数据的,所以 EntityManager是维护OR映射的中间者,它可以把数据从数据库中加载到PersistenceContext中,也可以把数据从PersistenceContext中持久化到数据库,EntityManager是应用程序操纵持久化数据的接口 。

EntityManager的作用与hibernate session类似。在hibernate中,session管理着全部的持久化对象的数据。而在EJB3中,EntityManager管理着PersistenceContext,PersistenceContext正是被管理的持久化对象的集合。

上面的这个例子其实也可以不用再继承一个接口,直接使用当前类就可以了,service调用的时候就不是创建上层的接口对象,而是创建这个实现类就可以了。


自定义的sql语句也可以返回map对象

@Repository
public class FieldAssoImpl {
    @PersistenceContext
    private EntityManager entityManager;
    public List<Map<String,String>> findAll(String tablename) {
       String sql="...";
        Query nativeQuery=entityManager.createNativeQuery(sql);
  nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List resultList=nativeQuery.getResultList();
        return resultList;

    }
}

这里我传入了一个表名,然后只要拼接出正确的sql语句就可以了。可以是”select * from “+ tablename,也可以

"select * from user where name="+"'"+tablename+"'"; 

总之要确保自己的SQL语句是正确的。

参考文章

https://blog.csdn.net/wujiaqi0921/article/details/78789087

@PersistenceContext和EntityManager:
https://www.cnblogs.com/jiangu66/archive/2013/05/30/3109096.html

猜你喜欢

转载自blog.csdn.net/weixin_43094917/article/details/82502027