zoukankan      html  css  js  c++  java
  • Spring Data JPA

    原文:https://segmentfault.com/a/1190000015266872?utm_source=tag-newest

    在我们的实际开发的过程中,无论多复杂的业务逻辑到达持久层都回归到了“增删改查”的基本操作,可能会存在关联多张表的复杂sql,但是对于单表的“增删改查”也是不可避免的,大多数开发人员对于这个简单而繁琐的操作都比较烦恼。

      为了解决这种大量枯燥的简单数据库操作,大致的解决该问题的有三种方式
    1、使用类似Hibernate的ORM框架,通过Hibernate完成java实体类和数据库之间的映射,完成简单的单表的“增删改查”

    2、使用代码生成工具生成单表的“增删改查”代码,省去我们手动编写的过程(我将在后面的文章中给出可定制化生成代码方法,敬请关注!)

    3、使用Spring-data-jpa这样的技术,它实现了模板Dao层,只需要在Dao,通过继承一个接口,就可轻松完成“增删改查”,具体使用方法如下:

    一、在pom.xml文件中添加如下依赖

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

    二、在application.yml文件中配置数据库信息和jpa信息(注意:不同的SpringBoot版本jpa配置的方法可能会有不同)

    spring:    
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
        username: root
    
        password: 123456
    
      jpa:
        hibernate:
          ddl-auto: update

      个人推荐使用yml格式的配置文件,看起来更加清晰简单(注意:每个配置属性的缩进是两个空格,这点一定要注意,不然会出现配置错误的情况,也可以在开发工具中安装相关的yml的插件方便查看)。

    jpa的配置后 jpa.hibernate.ddl-auto= update,在其他低版本的SpringBoot中也有使用spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop 这种配置的,具体根据版本而定。该配置的主要作用是:自动创建、更新、验证数据库结构

    1、create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因(一般只会在第一次创建时使用)

    2、create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除

    3、update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会

    4、validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值

    三、创建实体

    创建一个User类,配置好上面的信息后,启动项目,对应的数据库就会自动生成对应的表结构。@Table、@Entity、@Id等注解是jpa的相关知识,后面的文章将详细讲述。

    @Table(name = "t_user")
    @Entity
    public class User {
        @Id
        @GeneratedValue
    
        private Long id;
    
        @Column
        private String name;//姓名
        
        @Column
        private Integer age;//年龄
    
         // .....
    }

    四、创建数据库访问Dao层

    @Repository
    public interface UserRepository  extends JpaRepository<User,Long>{
    
        /**
         * 根据年纪查询用户
         * @param age
         * @return
         */
        User findByAge(Integer age);
    
        /**
         * 根据年纪和姓名查询
         * @param name
         * @param age
         * @return
         */
        User findByNameAndAge(String name, Integer age);
    
        /**
         * 对于复杂查询可以使用@Query 编写sql
         * @param name
         * @return
         */
        @Query("from User u where u.name=:name")
        User findUser(@Param("name") String name);
        
    }

      该Dao成继承了JpaRepository接口,指定了需要操作的实体对象和实体对象的主键类型,通过查看JpaRepository接口源码可以看到,里面已经封装了创建(save)、更新(save)、删除(delete)、查询(findAll、findOne)等基本操作的函数,使用起来非常方便了,但是还是会存在一些复杂的sql,spring-data-jpa还提供了一个非常方便的方式,通过实体属性来命名方法,它会根据命名来创建sql查询相关数据,对应更加复杂的语句,还可以用直接写sql来完成,具体例子如上所示。

    五、单元测试
    使用junit进行单元测试,代码如下

    /**
     * 
     * @author 明天的地平线
     * 
     * SpringBoot 之前的版本配置单元测试类时使用       @SpringApplicationConfiguration(Application.class)
     * SpringBoot 1.5.9  改用@SpringBootTest(classes = Application.class)
     * 
     */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = Application.class)
    public class JpaTest {
    
        @Autowired
        private UserRepository userRepository;
        
        /**
         * 新增用户
         * @throws Exception
         */
        @Test
        public void testAddUser() throws Exception {
            User user = new User();
            user.setName("zhangsan");
            user.setAge(12);
            userRepository.save(user);
            
            User user2 = new User();
            user2.setName("lishi");
            user2.setAge(22);
            userRepository.save(user2);
        }
        
        /**
         * 删除用户(根据对象删除时,必须要有ID属性)
         * @throws Exception
         */
        @Test
        public void testDelUser() throws Exception {
            User user = new User();
            user.setId(1L);
            user.setName("zhangsan");
            user.setAge(12);
            userRepository.delete(user);
        }
        
        /**
         * 修改用户信息
         * @throws Exception
         */
        @Test
        public void testUpdUser() throws Exception {
            User user = new User();
            user.setId(2L);
            user.setName("zhangsan11");
            user.setAge(122);
            userRepository.save(user);
        }
        
        /**
         * 查询用户
         * @throws Exception
         */
        @Test
        public void testQueryUser() throws Exception {
            User user = userRepository.findByAge(22);
            System.out.println(user.getName());
            
            User user2 = userRepository.findByNameAndAge("lishi", 22);
            System.out.println(user2.getName());
            
            User user3 = userRepository.findUser("zhangsan11");
            System.out.println(user3.getName());
        }
        
        /**
         * 查询所有用户
         * @throws Exception
         */
        @Test
        public void testQueryUserList() throws Exception {
            List<User> list = userRepository.findAll();
            for (User user : list) {
                System.out.println(user.getName());
            }
        }
        
    
    }

    数据库数据如下:

  • 相关阅读:
    解决xcode5升级后,Undefined symbols for architecture arm64:问题
    第8章 Foundation Kit介绍
    app 之间发送文件 ios
    iphone怎么检测屏幕是否被点亮 (用UIApplication的Delegate)
    CRM下载对象一直处于Wait状态的原因
    错误消息Customer classification does not exist when downloading
    How to resolve error message Distribution channel is not allowed for sales
    ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX这些东东是什么鬼
    有了Debug权限就能干坏事?小心了,你的一举一动尽在系统监控中
    SAP GUI和Windows注册表
  • 原文地址:https://www.cnblogs.com/xiayule/p/jpa1.html
Copyright © 2011-2022 走看看