浅谈JPA

上周跳槽到了一家新公司,数据持久化层用的不是mybatis,而是用的JPA,由于以前都没有用过,所以周末学习了一下,并且做一下记录,方便以后查看。
先说说jpa是什么?
我们来看看官方回答:在这里插入图片描述
其实说白了,你可以把它当做hibernate、mybatis的同类。
学习了之后,我更觉得这是mybatis-plus的前身,提供了很多写好的crud的接口,后面总结的时候我再做一下对比。
先看看主要代码,文末会附上完整项目链接,欢迎大家下载。
1.pom.xml文件

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
    </dependencies>

当然,resource标签一些读取.yml文件之类的必须,这里就不贴了
2.application.yml文件

spring:
  datasource:
    druid:
      url: jdbc:mysql://localhost:3306/jpa_test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: root12345
      driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update #自动更新
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    show-sql: true  #日志中显示sql语句
  application:
    name: spring-data-jpa-demo
server:
  port: 2333 #端口号

3.实体映射类

package com.jpa.example.entity;

import lombok.Data;

import javax.persistence.*;

@Data
@Entity
@Table(name = "jpa_user_test")
public class UserEntity {
	/**
	*这里的属性name,我在这里编译是警告红线,这不影响我们代码的正常运行
	*至于这些注解,一看应该都能懂,想要研究的去百度一大堆
	*/
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "student")
    private String student;
}

3.TestJpaRepository.java类
这个类其实就类似于mybaits的mapper文件,里面是连接数据库的最后一层。
有些注意点,我后面会打总结。

package com.jpa.example.dao;
import com.jpa.example.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

public interface TestJpaRepository extends JpaRepository<UserEntity,Long> {

    Object findByStudentAndUserName(String userName,String student);

    @Modifying
    @Query(value = "delete from  #{#entityName} a where a.userName = ?1")
    void testDelete(String name);
}

4.Service层,controller我就不贴代码了。每个测试方法我都有注释

package com.jpa.example.service;

import com.jpa.example.dao.TestJpaRepository;
import com.jpa.example.entity.UserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
public class JpaTestServiceImpl implements JpaTestService {
    @Autowired
    TestJpaRepository testJpaRepository;
    
	//查找表中所有数据
    @Override
    public Object findAll() {
        return testJpaRepository.findAll();
    }
    
	//根据主键id查找
    @Override
    public Object findById() {
        long id = 1l;
        return testJpaRepository.findById(id);
    }

	//插入一条新数据,这里没有设置id,因为在实体类我们有个    
	//@GeneratedValue(strategy = GenerationType.AUTO)注解,帮助我们自动生成
    @Override
    public Object save() {
        UserEntity userEntity =  new UserEntity();
        userEntity.setUserName("xiaoyu");
        userEntity.setStudent("川大");
        testJpaRepository.save(userEntity);
        return null;
    }

	//修改数据,修改和插入用的都是save,区别就是有无主键id。
    @Override
    public Object update() {
        long id = 1l;
        Optional<UserEntity> byId = testJpaRepository.findById(id);
        if (byId.isPresent()) {
            UserEntity userEntity = byId.get();
            userEntity.setUserName("update 小鱼");
            testJpaRepository.save(userEntity);
            return userEntity;
        }
        return null;
    }

	//根据id删除
    @Override
    public Object delete() {
        long id = 1l;
        testJpaRepository.deleteById(id);
        return null;
    }
	
	//特殊的查找方法,这里接下来解释
    @Override
    public Object special() {
        String username = "四川";
        String student = "成都";
        return testJpaRepository.findByStudentAndUserName(username,student);
    }
	
	//根据条件去删除,这里点进去可以看到我们写的是sql语句,所以要加 @Transactional注解
	//而且在delete之类操作的时候要在TestJpaRepository加上@Modifying注解
    @Override
    @Transactional
    public Object deleteSpecial() {
        String name = "测试特殊删除";
        testJpaRepository.testDelete(name);
        return "OK";
    }
}

以上就是主要的代码,完整项目请访问我的GitHub,开箱即用,都是调试好了的代码。
做个总结吧
1.先说优点,提供了一系列封装好的方法,帮助我们少些了SQL语句,方便开发。
2.一些缺点,官方封装好的直接方法很有限,基本都是根据id操作,或者所有数据。
(1)我们上面有个特殊的查找方法,根据用户名和student来查找,用的是testJpaRepository.findByStudentAndUserName,注意findByStudentAndUserName是jpa提供的规范,只能这么写,用select、query之类的都不行,只能用find开头,然后后面的Student和UserName必须是实体类中的字段,多个条件用and连接,驼峰。很麻烦。
(2)在上面特殊的删除方法,deleteSpecial在dao层是要写SQL语句的,注解必须加,不加项目都启动不起来,除了写SQL,当然我们也可以根据JPA的规范,把方法名命名为:deleteByUserName,这样也能实现根据名字删除。

3.说说和mybatis-plus的对比,虽然都是封装了一些crud的方法,但是mybatis-plus提供了更加灵活的条件构造器,而且还有代码生成器,这方便的不是一点半点,我只想说mybatis-plus yyds,其他的自己体会。我想现在除了那种老项目,或者公司传承下来很庞大的框架,应该没有人会喜欢用JPA这东西,
但是迫于现实,我还是得用,害,卑微打工人。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值