javabean赋值转换,整合SpringDataJPA

当我们处于实际的开发过程中,业务会具有一定的复杂性,一个model实体贯穿持久层、服务层、控制层是很难的。所以需要进行实体对象javabean的赋值转换。(如果业务很简单用一个实体类对象可以解决,那么就直接贯穿持久层到展现层,没有必要做映射赋值转换,没必要去分VO、BO、PO。)

javabean赋值转换

首先来解释几个概念:

PO:持久对象,在进行数据库数据存取操作时使用,对应数据库中的一个表,po的每个属性与数据库表里面字段一一对应。是一个符合JavaBean规范的纯Java对象。PO对象里只有基本数据类型和String类型的属性。

BO:业务对象,它主要的作用是把业务逻辑封装为一个对象,是对数据进行检索和处理的组件。通常一个BO是由多个PO的组成的。

VO:视图对象,用于展示层,它的作用是与web页面的展示结构相对应,也是前端与后端的数据交换定义。

PO是我们在数据库中查出来的数据,VO要比PO中的数据更丰富。

PO:用来对数据库表中的数据进行存取。

public class Pets { private long id; private String name; private String varieties; private Date createTime;
} 123456复制代码类型:[java]

VO:返回给前端的数据内容。(还包含了customer的内容)

public class PetsVo { private long id; private String name; private String varieties; private Date createTime; private List<Customer> customer;
} 1234567复制代码类型:[java]

当我们向数据库中添加数据,就要将Pets,Customer(PO)分别作为PO记录插入数据库。如果需要Pets,Customer信息返回给前端做页面渲染时,只要在数据库中查询出二者的信息然后组合起来,映射转换成PetsVo返回给前端。

对象间的转换赋值:

PetsVO.setId(pets.getId());
PetsVO.setName(pets.getName());
PetsVO.setVarieties(pets.getVarieties());
PetsVO.setCreateTime(pets.getCreateTime());1234复制代码类型:[java]

如果碰到大量的字段,那这种写法将会非常的麻烦,所以我们可以考虑使用BeanUtils和Dozer。

BeanUtils:

是SpringBoot默认提供的javabean赋值转换的工具,使用方法很简单。

PetsVO petsVO = new PetsVO();
BeanUtils.copyProperties(pets,petsVO);12复制代码类型:[java]

使用BeanUtils的前提是成员变量的数据类型是相同的

Dozer:

使用方法跟BeanUtils差不多,是一个能把实体和实体之间进行转换的工具。

Mapper mapper = DozerBeanMapperBuilder.buildDefault();
PetsVO petsVO = mapper .map(pets, PetsVO.class);12复制代码类型:[java]

Dozer的功能更强大可以实现Integer、Long等基础类型与String数据类型的属性之间的转换。还可以通过xml配置的方式实现复杂的数据转换。BeanUtils的性能更好。

SpringDataJPA

SpringDataJPA是SpringData家族的一部分,基于JPA规范的基础上封装的一套JPA应用框架,底层使用了Hibernate的JPA技术实现。除了常用接口(增,删,改,查)以外,还非常的易于扩展。

首先在pom.xml文件中引入依赖:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>1234复制代码类型:[java]

之后修改application.yml文件:

spring:
  jackson:
 date-format: yyyy-MM-dd HH:mm:ss
 time-zone: GMT+8

  datasource:
 driver-class-name: com.mysql.cj.jdbc.Driver
 url: jdbc:mysql://localhost:3306/Family?useUnicode=true&characterEncoding=utf-8&useSSL=false
 username: root
 password: 123456

  jpa:
 # Hibernate 创建数据库表的时候,默认使用的数据库存储引擎是 MyISAM
 # database-platform在建表的时候将存储引擎切换为 InnoDB
 database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
 hibernate:
   # 在Hibernate每次加载的时候,都会验证数据库中的表结构是否跟model类中字段的定义是一致的,如果不一致就抛出异常
   ddl-auto: validate
   naming:
  physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
 database: mysql
 # 在日志打印出执行的sql语句
 show-sql: true1234567891011121314151617181920212223复制代码类型:[java]

在完成以上配置工作以后,我们来实现一个JPA操作数据库的例子。

我们重新配置一下model文件下的Pets.java使他的字段跟数据库中的表结构一一对应。将原来的Pets.java改名成PetsVO.java。

package com.javafamily.familydemo.model;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import javax.persistence.*;import java.util.Date;@Data@AllArgsConstructor@NoArgsConstructor@Builder// 表示当前的类是实体类,并且接受Spring Data JPA的控制管理。对应数据库中的一张表。@Entity@Table(name = "pets")public class Pets { // id 自动递增
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id; // name 不能为空,并且是唯一的,长度不能超过50
 @Column(nullable = false, unique = true, length = 50)
 private String name; // varieties 不能为空,长度不能超过50
 @Column(nullable = false, length = 50)
 private String varieties; @Column(name = "create_time")
 private Date createTime;
}1234567891011121314151617181920212223242526272829303132复制代码类型:[java]

之后在Dao文件夹下创建PetsRepository.java编写数据库操作端口:

package com.javafamily.familydemo.dao;import com.javafamily.familydemo.model.Pets;import org.springframework.data.jpa.repository.JpaRepository;// 尖括号里表示的是要操作的数据库表对应的实体PO和实体主键的类型public interface PetsRepository extends JpaRepository<Pets, Long> {

}123456789复制代码类型:[java]

JpaRepository<Pets,Long>为我们提供了增删改查功能。

之后来改写Service文件下的petsService.java和PetsServiceImpl.java:

package com.javafamily.familydemo.service;import com.javafamily.familydemo.model.PetsVO;import java.util.List;public interface PetsService { PetsVO savePets(PetsVO pets); void deletePets(long id); void updatePets(PetsVO pets); PetsVO getPets(Long id); List<PetsVO> getAll();
}1234567891011121314151617复制代码类型:[java]
package com.javafamily.familydemo.service;import com.javafamily.familydemo.dao.PetsRepository;import com.javafamily.familydemo.model.Pets;import com.javafamily.familydemo.model.PetsVO;import com.javafamily.familydemo.utils.DozerUtils;import org.dozer.Mapper;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.List;import java.util.Optional;@Servicepublic class PetsServiceImpl implements PetsService { @Resource
 private PetsRepository petsRepository; @Resource
 private Mapper dozerMapper; public PetsVO savePets(PetsVO pets) {
  Pets petsPO = dozerMapper.map(pets, Pets.class);  // 通过insert,保存一个对象
  petsRepository.save(petsPO);  return pets;
 } @Override
 public void deletePets(long id) {  // 通过id删除数据库内容
  petsRepository.deleteById(id);
 } @Override
 public void updatePets(PetsVO pets) {
  Pets petsPO = dozerMapper.map(pets,Pets.class);  // 更新一个对象,使用save方法
  petsRepository.save(petsPO);
 } @Override
 public PetsVO getPets(Long id) {  // Optional<> 表示可能查到记录,也可能查不到
  Optional<Pets> pets = petsRepository.findById(id);  // 通过id查找一条数据
  return dozerMapper.map(pets.get(),PetsVO.class);
 } @Override
 public List<PetsVO> getAll() {
  List<Pets> petsList = petsRepository.findAll();  //查询表的所有数据
  return DozerUtils.mapList(petsList,PetsVO.class);
 }
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859复制代码类型:[java]

在com.javafamily.familydemo文件下创建utils文件夹,并且在其中创建DozerUtils.java

package com.javafamily.familydemo.utils;import com.google.common.collect.Lists;import org.dozer.DozerBeanMapperBuilder;import org.dozer.Mapper;import java.util.Collection;import java.util.Iterator;import java.util.List;public class DozerUtils { static Mapper mapper = DozerBeanMapperBuilder.buildDefault(); public static <T> List<T> mapList(Collection sourceList, Class<T> destinationClass) {

  List destinationList = Lists.newArrayList();  for (Iterator i$ = sourceList.iterator(); i$.hasNext(); ) {
   Object sourceObject = i$.next();
   Object destinationObject = mapper.map(sourceObject, destinationClass);
   destinationList.add(destinationObject);
  }  return destinationList;
 }
}12345678910111213141516171819202122232425复制代码类型:[java]

最后我们把数据库中的数据全部删除,并使用postman进行测试:

添加的数据成功出现在数据库中。

数据库中的数据被查询出来。

之后我们将varieties修改为red:

数据被修改成功:

最后删除这条数据:

数据被成功删除:

通过关键字查询接口

如果我们想要通过name来进行数据查询,那么就要编写关键字查询接口。

在PetsRepository中添加代码:

package com.javafamily.familydemo.dao;import com.javafamily.familydemo.model.Pets;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;// 尖括号里表示的是要操作的数据库表对应的实体PO和实体主键的类型public interface PetsRepository extends JpaRepository<Pets, Long> { // jpa会根据这条代码自动生成SQL语句
 Pets findPetsBy(String name);
}1234567891011复制代码类型:[java]

其他具体的关键字,使用方法和生产成SQL:

之后我们编写一个测试类用来对关键字搜索功能进行测试:

package com.javafamily.familydemo;import com.javafamily.familydemo.dao.PetsRepository;import com.javafamily.familydemo.model.Pets;import org.junit.jupiter.api.Test;import org.junit.jupiter.api.extension.ExtendWith;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit.jupiter.SpringExtension;import javax.annotation.Resource;@ExtendWith(SpringExtension.class)@SpringBootTestpublic class KeyWordsTest { @Resource
 private PetsRepository petsRepository; @Test
 public void Test() {
  Pets pets = petsRepository.findPetsByName("fish");
  System.out.println(pets);
 }
}1234567891011121314151617181920212223复制代码类型:[java]

向数据库中添加两条数据:

执行代码打印结果:

这时我们就通过关键字完成了查询。

(0)

相关推荐