SpringBoot(三)springboot整合SpringDataJPA

        在我们的项目开发中,数据库的访问及存储都是最为核心的部分,SpringBoot为我们提供了多种数据库来做数据的存储及读取。目前企业开发中应用最为广泛的数据库有,关系型数据库MySQL,oracle,sqlserver,非关系型数据库redis,mongodb等。
        本章将通过使用SpringBoot访问MySQL结合SpringDataJPA完成CRUD(Create,Read,Update,Delete)简单操作。

  一 、什么是SpringDataJPA

    Spring Data是一个用于简化数据库访问,并支持云服务的开源框架,其主要目标是使得对数据的访问变得方便快捷。Spring Data包含多个子项目,spring-data-jpa就是其子项目之一。

     JPA(Java Persistence API)是一种Java持久化解决方案,负责把数据保存到数据库,实际上它就是一种标准、规范,而不是具体的实现。JPA属于重量级的,因为它需要运行在JAVA EE容器中,而Spring Data JPA提供了轻量级的实现,在任何servlet容器中都可以运行。
     Spring Data JPA相对于JAVA EE中的JPA,配置更简单,以轻量级的方式实现了部分在 EJB 容器环境下才具有的功能,将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,并且极大的简化了数据库访问层的代码。

官网地址:http://projects.spring.io/spring-data-jpa/

   二、springboot整合SpringDataJPA

    1. 创建数据库表

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    2.  添加依赖

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.45</version>
    </dependency>
    <!--入JPA的依赖关系-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    3.  配置数据源

spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=
#jpa连接的数据库类型
spring.jpa.database=mysql

    4. 编写实体类

import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

/*
 * @author uv
 * @date 2018/9/14 14:29
 *
 */
@Entity // 对实体注释。任何Hibernate映射对象都要有这个注释
@Table(name = "user") //@Table注释指定了Entity所要映射带数据库表
@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // 主键生成策略
    private int id;
    private String name;
    private String password;

//    @Transient //在进行单表的增删改查的时候即忽略这个字段
//    private int age;

    //get,set 方法
}

     5. 编写dao接口

package com.uv.boot.dao;
/*
 * @author uv
 * @date 2018/9/14 16:28
 *
 */

import com.uv.boot.entity.User;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

// JpaRepository<User,Integer> 查找的实体类和主键的数据类型
public interface UserDao extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User>,Serializable {
    
}

       我们并不需要做其他的任何操作了,因为SpringBoot以及SpringDataJPA会为我们全部搞定,SpringDataJPA内部使用了类代理的方式让继承了它接口的子接口都以spring管理的Bean的形式存在。

       JpaRepository的源码,默认的CRUD有如下方法:

@NoRepositoryBean //此注解表示不进行实体类与表的映射,多用于实体类的父类
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    
    List<T> findAll();  //查询所有数据

    List<T> findAll(Sort var1);  //按条件查询

    List<T> findAll(Iterable<ID> var1); 

    <S extends T> List<S> save(Iterable<S> var1);

    void flush();

    <S extends T> S saveAndFlush(S var1);

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    T getOne(ID var1);

    <S extends T> List<S> findAll(Example<S> var1);

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

SpringDataJpa可以根据方法自动映射成Sql语句,真正的实现不用写一句Sql语句,映射关系如下:

      6. 编写UserService和UserController

package com.uv.boot.service;

import com.uv.boot.dao.UserDao;
import com.uv.boot.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/*
 * @author uv
 * @date 2018/9/14 14:56
 *
 */
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public void insertUser(User user) {
        userDao.save(user);
    }

    public User getUser(int id) {
        return userDao.getOne(id);
    }
}
package com.uv.boot.controller;

import com.uv.boot.entity.User;
import com.uv.boot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

/*
 * @author uv
 * @date 2018/9/14 14:59
 *
 */
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("insertuser")
    public void insertUser(User user) {
        userService.insertUser(user);
    }

    @GetMapping("getuser")
    public User getUser(int id) {
        return userService.getUser(id);
    }

}

      7. 启动类添加扫描

@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.uv.boot.dao"})	//扫描repository
@EntityScan(basePackages = {"com.uv.boot.entity"})	//扫描entity实体
public class BootApplication {

	public static void main(String[] args) {
		SpringApplication.run(BootApplication.class, args);
	}
}

     8. 测试

    9. 在测试中出现的异常

"exception": "org.springframework.http.converter.HttpMessageNotWritableException",
    "message": "Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.uv.boot.entity.User_$$_jvst166_0[\"handler\"])",

      解决:

      hibernate延时加载
    因为jsonplugin用的是Java的内审机制.hibernate会给被管理的pojo加入一个hibernateLazyInitializer属性,jsonplugin会把  hibernateLazyInitializer也拿出来操作,并读取里面一个不能被反射操作的属性就产生了这个异常. 然后在类型上面将hibernateLazyInitializer进行忽略。

因此在User实体类上添加:@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })

猜你喜欢

转载自blog.csdn.net/qq_22200097/article/details/82704718
今日推荐