使用Gradle构建SpringBoot工程系列:第八篇:使用spring-data-jpa 实现数据持久化

本篇文章是SpringBoot 系列文章的第八篇文章,由于本人工作原因,中断了一段时间,接下来的一段时间里,将陆续更新本系列的其他文章,回归Spring Boot技术体系,记录本人学习和使用Gradle构建spring Boot工程的过程、技术要点以及在过程中遇到的各种问题,欢迎广大程序猿共同关注学习,也欢迎大家提出自己的宝贵意见,知识在交流中碰撞,技术在交流中提升!

 Spring Data JPA

是Spring Data系列的一部分,可以轻松实现基于JPA的数据持久化操作,旨在通过提供通用接口减少持久层的编码量,提高代码质量,降低代码和SQL的维护成本,避免SQL注入等安全风险。作为开发人员只需编写Repostitory接口,Spring将自动提供实现数据库读写

Repository的概念

在Spring中有Repository的概念,repository原意指的是仓库,即数据仓库的意思。Repository居于业务层和数据层之间,将两者隔离开来,在它的内部封装了数据查询和存储的逻辑。这样设计的好处有两个:

  1. 降低层级之间的耦合:更换、升级ORM引擎(Hibernate)并不会影响业务逻辑
  2. 提高测试效率:如果在测试时能用Mock数据对象代替实际的数据库操作,运行速度会快很多

Repository和DAO的区别

DAO是传统MVC中Model的关键角色,全称是Data Access Object。DAO直接负责数据库的存取工作,乍一看两者非常类似,但从架构设计上讲两者有着本质的区别:

Repository蕴含着真正的OO概念,即一个数据仓库角色,负责所有对象的持久化管理。DAO则没有摆脱数据的影子,仍然停留在数据操作的层面上。Repository是相对对象而言,DAO则是相对数据库而言,虽然可能是同一个东西 ,但侧重点完全不同。

接下来本篇文章将针对使用CrudRepository实现Repository数据库读写:

在Gradle 的build.gradle配置文件中追加一下jpa依赖:'org.springframework.boot:spring-boot-starter-data-jpa' 

dependencies {
    compile(
            'org.springframework.boot:spring-boot-starter-actuator',
            'org.springframework.boot:spring-boot-starter-web',
            'org.springframework.boot:spring-boot-starter-data-jpa',
            'org.springframework.boot:spring-boot-devtools',
            'mysql:mysql-connector-java'
    )
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

对于使用maven的朋友可以使用一下配置:


    
       org.springframework.boot
       spring-boot-starter-parent
       1.3.3.RELEASE
    
  
    
      junit
      junit
      3.8.1
      test
    
     
       
           org.springframework.boot
           spring-boot-starter-web
       
        
      
           org.springframework.boot
           spring-boot-starter-data-jpa
       

application.yml或propertites引入数据源配置:

application.yml:

#本地环境
spring:
  profiles: local
 
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/bootdb?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
    username: root
    password: root
 
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

application.properties 

########################################################
###datasource  配置MySQL数据源;
########################################################
spring.datasource.url = jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10

########################################################
### Java Persistence Api 自动进行建表
########################################################
# 指定数据源类型
spring.jpa.database = MYSQL
# 指定是否在控制台输出SQL语句
spring.jpa.show-sql = true
# 支持自动建表 Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# 命名策略(Naming strategy):用于指定实体与表映射的命名规范,可以使用自定义策略
# 这里使用自带的策略
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# 数据库方言 stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

 

CrudRepository提供的基本的读写方法

   S save(S entity);
   Iterable save(Iterable entities);
  T findOne(ID id);
  boolean exists(ID id);
  Iterable findAll();
  Iterable findAll(Iterable ids);
  long count();
  void delete(ID id);
  void delete(T entity);
  void delete(Iterable entities);
  void deleteAll();

CrudRepository类如其名,可以胜任最基本的CRUD操作。其中save方法在可两用,参数中不存在主键时执行insert操作,存在主键则执行update操作,相当于是一个upsert操作。

创建实体类:此类即代表数据库表实体,也代表数据库表结构,可以通过注解指定实体关联关系

@Entity
public class UserInfo implements Serializable{
    private static final long serialVersionUID = 1L;
    @Id@GeneratedValue
    private long uid;//用户id;
   
    @Column(unique=true)
    private String username;//账号.
   
    private String name;//名称(昵称或者真实姓名,不同系统不同定义)
   
    private String password; //密码;
    private String salt;//加密密码的盐
   
    private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.
 
   
    @ManyToMany(fetch=FetchType.EAGER)//立即从数据库中进行加载数据;
    @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })
    private List roleList;// 一个用户具有多个角色
   
    public List getRoleList() {
       return roleList;
    }
 
    public void setRoleList(List roleList) {
       this.roleList = roleList;
    }

创建接口实现类:

/**
* UserInfo持久化类:实现CrudRepository,接口,并制定接口泛型,即与指定的实体表进行绑定;
* @author 
* @version v.0.1
*/
public interface UserInfoRepository extends CrudRepository{
  
   /**通过username查找用户信息;此处无需写出具体sql,但方法名称必须符合命名策略
    * 
    */
   public UserInfo findByUsername(String username);
  
}

创建Service层实现:此处service接口层可自行定义,此处仅代表示例

/**
 * service层可直接注入 我们实现Repostitory接口
 */
@Service
public class UserInfoServiceImpl implements UserInfoService{
   
    @Resource
    private UserInfoRepository userInfoRepository;
   
    @Override
    public UserInfo findByUsername(String username) {
       System.out.println("UserInfoServiceImpl.findByUsername()");
       return userInfoRepository.findByUsername(username);
    }
    /**
     * 这里的save方法是CrudRepository默认提供的
     */
	@Override
	public void UserInfoSave(UserInfo userInfo) {
		System.out.println("UserInfoServiceImpl.UserInfoSave()");
		 userInfoRepository.save(userInfo);
	}
    
   
}

编写Controller层实现: 

@Controller
@RequestMapping("/userInfo")
public class UserInfoController {
	@Autowired
    UserInfoService userInfoService;
    /**
     * 用户查询.使用自定义方法
     * @return
     */
    @RequestMapping(value="/user",method=RequestMethod.GET)
    public String userInfo(@RequestParam String username){
    	userInfoService.findByUsername(username);
       return "userInfo";
    }
   
    /**
     * 用户添加 使用系统自带方法;
     * @return
     */
    @RequestMapping(value="/user",method=RequestMethod.POST)
    public String userInfoAdd(@RequestBody UserInfo userInfo){
    	userInfoService.userInfoSave(userInfo);
       return "userInfoAdd";
    }
   
}

以上是本篇文章的相关实战代码,通过以上实现,启动SpringBoot应用,会自动创建UserInfo表,

使用Gradle构建SpringBoot工程系列:第八篇:使用spring-data-jpa 实现数据持久化_第1张图片可以通过POSTMAN等软件进行接口测试:

新增用户信息:

使用Gradle构建SpringBoot工程系列:第八篇:使用spring-data-jpa 实现数据持久化_第2张图片

查询我们新增的用户信息:'127.0.0.1:8080/userinfo?username=zhangsan',得到以下结果:

使用Gradle构建SpringBoot工程系列:第八篇:使用spring-data-jpa 实现数据持久化_第3张图片

扩展:Spring Boot 也提供了其他Repository接口,例如:JpaRepository

JpaRepository继承自CrudRepostitory,并提供的基本方法:

  List findAll();
  List findAll(Sort sort);
  List findAll(Iterable ids);
   List save(Iterable entities);
  void flush();
   S saveAndFlush(S entity);
  void deleteInBatch(Iterable entities);
  void deleteAllInBatch();
  T getOne(ID id);
  @Override
   List findAll(Example example);
  @Override
   List findAll(Example example, Sort sort);

JpaRepository则进一步扩展了部分功能:

  1. 查询列表(返回值为List)
  2. 批量删除
  3. 强制同步
  4. Example查询

在接下来的文章中将进行实践,敬请期待

 

你可能感兴趣的:(使用Gradle构建SpringBoot工程系列:第八篇:使用spring-data-jpa 实现数据持久化)