• Spring Boot整合Spring Data JPA


    1、JPA

    JPA是Java Persistence API的简称,中文名Java持久层API,是官方(Sun)在JDK5.0后提出的Java持久化规范。其目的是为了简化现有JAVA EE和JAVA SE应用开发工作,以及整合现有的ORM技术实现规范统一。

    JPA的总体思想和现有Hibernate、TopLink、JDO等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:

    • ORM映射元数据: 支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
    • API: 操作实体对象来执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
    • 查询语言: 通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

    JPA只是一种规范,它需要第三方自行实现其功能,在众多框架中Hibernate是最为强大的一个。从功能上来说,JPA就是Hibernate功能的一个子集。Hibernate 从3.2开始,就开始兼容JPA。同时Hibernate3.2获得了Sun TCK的JPA(Java Persistence API) 兼容认证。

    2、Spring Data JPA

    常见的ORM框架中Hibernate的JPA最为完整,因此Spring Data JPA 是采用基于JPA规范的Hibernate框架基础下提供了Repository层的实现。Spring Data Repository极大地简化了实现各种持久层的数据库访问而写的样板代码量,同时CrudRepository提供了丰富的CRUD功能去管理实体类。

    优点:

    • 丰富的API,简单操作无需编写额外的代码
    • 丰富的SQL日志输出

    缺点:

    • 学习成本较大,需要学习HQL
    • 配置复杂,虽然SpringBoot简化的大量的配置,关系映射多表查询配置依旧不容易
    • 性能较差,对比JdbcTemplate、Mybatis等ORM框架,它的性能无异于是最差的

    3、导入依赖

    在 pom.xml 中添加 spring-boot-starter-data-jpa 的依赖;

    <!-- Spring JDBC 的依赖包,使用 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa 将会自动获得HikariCP依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- MYSQL包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- 默认就内嵌了Tomcat 容器,如需要更换容器也极其简单-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 测试包,当我们使用 mvn package 的时候该包并不会被打入,因为它的生命周期只在 test 之内-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    4、连接数据库

    在application.properties中添加如下配置。值得注意的是,SpringBoot默认会自动配置DataSource,它将优先采用HikariCP连接池,如果没有该依赖的情况则选取tomcat-jdbc,如果前两者都不可用最后选取Commons DBCP2。通过spring.datasource.type属性可以指定其它种类的连接池。

    spring.datasource.url=jdbc:mysql://localhost:3306/chapter5?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
    spring.datasource.password=root
    spring.datasource.username=root
    #spring.datasource.type
    # JPA配置
    spring.jpa.hibernate.ddl-auto=update
    # 输出日志
    spring.jpa.show-sql=true
    # 数据库类型
    spring.jpa.database=mysql

    ddl-auto 几种属性:

    • create: 每次运行程序时,都会重新创建表,故而数据会丢失
    • create-drop: 每次运行程序时会先创建表结构,然后待程序结束时清空表
    • upadte: 每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新
    • validate:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错

    5、实体类

    JPA规范注解坐落在javax.persistence包下,@Id注解一定不要引用错了,否则会报错。@GeneratedValue(strategy = GenerationType.IDENTITY)自增策略,不需要映射的字段可以通过@Transient注解排除掉。

    常见的几种自增策略:

    • TABLE: 使用一个特定的数据库表格来保存主键
    • SEQUENCE: 根据底层数据库的序列来生成主键,条件是数据库支持序列。这个值要与generator一起使用,generator 指定生成主键使用的生成器(可能是orcale中自己编写的序列)。
    • IDENTITY: 主键由数据库自动生成(主要是支持自动增长的数据库,如mysql)
    • AUTO: 主键由程序控制,也是GenerationType的默认值。
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import java.io.Serializable;
    
    @Entity(name = "t_user")
    public class User implements Serializable {
    
        private static final long serialVersionUID = 8655851615465363473L;
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String username;
        private String password;
        /**
         * TODO 忽略该字段的映射
         */
        @Transient
        private String  email;
    
        // TODO  省略get set
    }

    6、Repository

    创建UserRepository数据访问层接口,需要继承JpaRepository

    import com.battcn.entity.User;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface UserRepository extends JpaRepository<User, Long> {
    
        /**
         * 根据用户名查询用户信息
         *
         * @param username 用户名
         * @return 查询结果
         */
        List<User> findAllByUsername(String username);
    }

    7、测试

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class Chapter5ApplicationTests {
    
        private static final Logger log = LoggerFactory.getLogger(Chapter5ApplicationTests.class);
    
        @Autowired
        private UserRepository userRepository;
    
        @Test
        public void test1() throws Exception {
            final User user = userRepository.save(new User("u1", "p1"));
            log.info("[添加成功] - [{}]", user);
            final List<User> u1 = userRepository.findAllByUsername("u1");
            log.info("[条件查询] - [{}]", u1);
            Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("username")));
            final Page<User> users = userRepository.findAll(pageable);
            log.info("[分页+排序+查询所有] - [{}]", users.getContent());
            userRepository.findById(users.getContent().get(0).getId()).ifPresent(user1 -> log.info("[主键查询] - [{}]", user1));
            final User edit = userRepository.save(new User(user.getId(), "修改后的ui", "修改后的p1"));
            log.info("[修改成功] - [{}]", edit);
            userRepository.deleteById(user.getId());
            log.info("[删除主键为 {} 成功] - [{}]", user.getId());
        }
    }

    原文地址:芋道源码

  • 相关阅读:
    DDD:管理“工作单元实例”的两种模式
    DDD:DDD+CQRS+高伸缩性的分布式架构
    ExtJS4.2:快捷键支持(没有你想象的那么简单)
    DDD:用 “四色原型” 进行 “职责分配”
    .NET:处理数据库事务中的并发
    Javascript:必须知道的Javascript知识点之“单线程事件驱动”
    技术交流:20130413线下交流总结,不再做苦逼的程序员
    Javascript:必须知道的Javascript知识点之“原型链”
    DDD:主键映射,你一直在使用的企业应用模式
    设计原则:重复的方式以及如何消除重复
  • 原文地址:https://www.cnblogs.com/aixing/p/13327514.html
Copyright © 2020-2023  润新知