SpringDataJPA对数据库的增删改查三种操作方式

发布于:2023-01-04 ⋅ 阅读:(431) ⋅ 点赞:(0)

在这里插入图片描述

jpa详解

  • spirng data jpa是spring提供的一套简化JPA开发的框架。
  • 按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。
  • Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。

(一)jpa注解使用

注解 解释
@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 定义了连接表之间有一个一对一的关系。
@NamedQuery 指定使用静态名称的查询。

(二)快速使用

1、导入依赖

        
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        

2、配置文件

    
	# 格式化显示sql语句
    spring.jpa.properties.hibernate.show_sql=true
    spring.jpa.properties.hibernate.format_sql=true
    spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect

3、项目结构

  • controller:控制层
  • entity:实体类
  • repository:持久层

    ( PS:又称dao层,在jpa中叫做repository,在mybatis中叫做mapper )

  • service:业务逻辑层
  • impl:业务逻辑层的实现类

(三)创建项目结构

1、创建entity实体类

@Data注解需事先导入Lombok依赖使用

    
	@Data
    @Entity
    @Table(name = "userinfo")
    public class Userinfo {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id", nullable = false)
        private Integer id;
        private String userName;
        private String userPass;
        private String userNick;
        private Boolean enable;
        

2、创建repository持久层

只需继承JpaRepository接口,泛型选择实体类和id的类型

    public interface UserinfoRepository extends JpaRepository<Userinfo, Integer> {
        
    }

3、创建service业务层

    public interface UserinfoService {
    
    }
    

4、创建Impl实现类

实现service接口,添加@Service注解

    @Service
    public class UserinfoServiceImpl implements UserinfoService {

    }

5、创建controller控制层

添加访问映射地址,使用@Autowired注入service

    @RestController
    @RequestMapping(value = "/userinfo")
    public class UserinfoController {
        
        @Autowired
    	private UserinfoService userinfoService;

    }

(四)第一种:单表crud操作

1、Service

    public interface UserinfoService {

        // 增---添加新用户
        void add(Userinfo userinfo);

        // 删---根据id删除用户
        void delById(Integer id);

        // 改---根据id修改用户信息
        void updataUserById(Userinfo userinfo);

        // 查---返回全部用户
        List<Userinfo> findAllUser();
        
    }

2、Impl

实现接口后重写每个方法,使用@Autowired注入业务逻辑层UserinfoRepository并调用封装好的crud操作

        @Service
        public class UserinfoServiceImpl implements UserinfoService {

        @Autowired
        private UserinfoRepository userinfoRepository;


        @Override
        public void add(Userinfo userinfo) {
            userinfoRepository.save(userinfo);
        }

        @Override
        public void delById(Integer id) {
            userinfoRepository.deleteById(id);
        }

        @Override
        public void updataUserById(Userinfo userinfo) {
            userinfoRepository.saveAndFlush(userinfo);
        }

        @Override
        public List<Userinfo> findAllUser() {
            List<Userinfo> userinfoList = userinfoRepository.findAll();
            return userinfoList;
        }
    }

3、Controller

进入controller控制层书写地址映射调用方法,并使用前端测试工具检测

    
    @RestController
    @RequestMapping(value = "/userinfo")
    public class UserinfoController {

        @Autowired
        private UserinfoService userinfoService;

        // 增---Post增加新用户
        @PostMapping("addUser")
        public void addUser(Userinfo userinfo) {
            userinfoService.add(userinfo);
        }

        // 删---Del根据Id删除一个用户
        @DeleteMapping("/delUser/{id:\\d+}")
        public void delUserById(@PathVariable Integer id) {
            userinfoService.delById(id);
        }

        // 改---Put修改用户信息
        @PutMapping("/updateUser")
        public void updateByUserId(Userinfo userinfo) {
            userinfoService.updataUserById(userinfo);
        }

        // 查---Get查询所有
        @GetMapping("/findAllUser")
        public List<Userinfo> findAllUser() {
            return userinfoService.findAllUser();
        }
    }
    

(五)第二种:sql自定义脚本操作

1、持久层repository

  • 自定义方法,加上@Query注解和自定义的sql语句
  • @Modifying涉及了数据库修改操作,和@Query一并使用

sql语句中使用 " :" 接收参数,传参需要使用@Param(“ 参数值 ”)。
sql语句中使用 " ?" 接收参数,传参需要注意下顺序不可乱。

    	// 自定义sql更新昵称,:接受参数
        @Modifying
        @Query(value = "update userinfo set user_nick = :userNick where id = :id", 						nativeQuery = true)
        void updateUserNickByUserId(@Param("id") Integer id, @Param("userNick") String 					uesrNick);

		// 自定义sql更新昵称,?接受参数
 		@Query(value = "update userinfo set user_nick = ?where id = ?", 						nativeQuery = true)
        void updateUserNickByUserId( String uesrNick , Integer id );

2、控制层controller

    
	// 改---Put根据用户ID修改昵称
    @PutMapping("/updateUser")
    public void updateByUserId(@RequestParam Integer id, @RequestParam String userNick) {
        userinfoRepository.updateUserNickByUserId(id, userNick);
    }

(六)自动关系映射

1、一对一,@OneToOne

  • 首先需要两个表的实体类,主表不包含次表外键属性,次表有一列为主表的外键属性

  • 添加question表的实体类Entity

  • 添加@OneToOne注解表示一对一关系映射

  • 使用@JoinColumn为次表中关联主表的外键字段

   
   	@Entity
    @Data
    @Table(name = "question")
    public class Question {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id", nullable = false)
        private Integer id;
        private String title;

        @OneToOne
        @JoinColumn( name = "userinfo_id" )
        private Userinfo userinfo;

    }
    

2、一对多,多对一,@OneToMany、@ManyToOne

  • 一端(Userinfo)使用@OneToMany。

  • 一端(Userinfo)使用@OneToMany注释的mappedBy="userinfo"属性表明userinfo是关系被维护端。

    @Setter
    @Getter
    @Entity
    public class Userinfo {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id", nullable = false)
        private Integer id;
        private String userName;
        private String userPass;
        private String userNick;
        private Boolean enable;

        @OneToMany(mappedBy = "userinfo")
        private List<Question> questionList;

    }
    
  • 多端(Question)使用@ManyToOne。

  • @ManyToOne表明Question是多端,@JoinColumn设置在Question表中的关联字段(外键)。

    
    @Entity
    @Setter
	@Getter
    public class Question {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id", nullable = false)
        private Integer id;
        private String title;

        @ManyToOne
        @JsonIgnore
        @JoinColumn(name = "userinfo_id")
        private Userinfo userinfo;

    }
    

(七)第三种:jpa关键字自定义方法

​ jpa封装好的方法肯定是不能满足我们的业务需求,有需求是按照特定的单词对方法名进行定义,那么Spring就会对我们写的方法名进行解析,生成对应的实例进行数据处理。

关键字 使用示例 文字说明
And findByNameAndPwd 根据用户名和密码查询
Or findByNameOrSex 根据用户名和性别查询
Is,Equals findById,findByIdEquals 根据ID查询
Between findByIdBetween 根据ID范围区间查询
LessThan findByIdLessThan 查询大于此ID的
LessThanEquals findByIdLessThanEquals 查询大于等于此ID的
GreaterThan findByIdGreaterThan 查询小于此ID的
GreaterThanEquals findByIdGreaterThanEquals 查询小于等于此ID的
IsNull findByNameIsNull 查询ID是否为null
isNotNull,NotNull findByNameNotNull 查询ID是否不为null
Like findByNameLike 根据用户名模糊查询
NotLike findByNameNotLike 不包括该用户名模糊查询
StartingWith findByNameStartingWith 确定首字用户名模糊查询
EndingWith findByNameEndingWith 确定尾字用户名模糊查询
Containing findByNameContaining 包含此字用户名模糊查询
OrderBy findByIdOrderByXDesc 根据ID查询X列倒序排序
Not findByNameNot 查找非此用户名的
In findByIdIn(Collection<?> c) 根据ID查询集合内的
NotIn findByIdNotIn(Collection<?> c) 根据ID查询不在集合内的
True findByEnableTrue 查询Enable列是否为真
False findByEnableFalse 查询Enable列是否为假

1、例子说明

 	
 	// 根据ID倒序返回启动状态
 	List<Userinfo> findByEnableIsTrueOrderByIdDesc();
	
	// 根据用户名模糊查询
    List<Userinfo> findByUserNameLike(String name);
    
  • 省略业务实现层,DDDD…

控制层调用,模糊查询带上“ % ”,意为包含用户的全部查出。


    @GetMapping("/findLike")
    public List<Userinfo> findLike(String name){
        List<Userinfo> userinfoList=userinfoService.findLike("%"+name+"%");
        return userinfoList;
    }
    

总而言之,jpa对于数据的查询,主要有三点:

  • 通过repository继承JpaRepository接口实现的crud操作。
  • 通过jpa关键字的组合来自定义方法。
  • 通过自定义sql语句脚本自定义方法。
本文含有隐藏内容,请 开通VIP 后查看