本文主要介绍商品类目(product_category表) 的Dao和Sercice层的开发,还有lombok 工具的使用,还有几个常用的注解,以及功能测试。
开始吧。
lombok插件
@DynamicUpdate注解
@Transactional注解
JpaRepository 接口方法命名规则
断言
1、数据表结构
我们说过,本文是介绍对商品类目表的增删改查,先看一些商品类目表的结构
这是我之前测试时添加的数据
2、导入数据库依赖,安装 lombok 插件
前两个是数据库操作使用,第三个 lombok 是一个插件,可以帮我们在打包项目的时候自动生成 Setter/Getter,toString()方法之类的,而我们只需要在类上加一个注解,而不需要写那些冗余的代码。
要使用lombok,在引入上面的依赖后,还需要安装 IDEA 插件,
3、文件结构
下面的是最终的文件结构
我们一步步来讲解
现在我们要创建 product_category 表的实体类,类名需要按照驼峰法,即 ProductCategory
ProductCategory.java
有木有感觉上面的代码有点多,特别是那个 Getter/Setter 方法太多了,每新建一个类,都需要加入 Getter/Setter 方法,如果修改某个属性类型的话,也需要修改。其实我们只需要使用之前说的 lombok 工具就可以解决这个问题。
在安装了 lombok 插件和 导入了 lombok 依赖后,我们的代码可以简化很多
ProductCategory.java
更多补充
1、@Entity 注解
表示该类是一个实体类
2、@DynamicUpdate 注解
可以动态更新数据表中那些需要更新的字段,比如我们的 updateTime 这个属性对应的是数据表中 update_time 字段,这个字段虽然在数据库里写了自动更新的代码,即
但是,在这里,如果你对记录更新的时候,没有给 updateTime 属性赋值,它是不会改变的,这时我们不想看到的。
如果我们给这个类加上 @DynamicUpdate 注解,那么我们的 update_time 字段就会随更改时间而改变了。
3、@Data 注解
该注解是 lombok 的
@Data 包含了@ToString,@EqualsAndHashCode,@Getter / @Setter和@RequiredArgsConstructor的功能
4、@Id 注解
表示该属性为主键
5、@GeneratedValue
表示该属性自动生成值,这里指 的是 id 的值自增
6、无参的构造方法
正常情况,系统会默认生成一个无参的构造方法,也就是说我们这里其实是不需要写的。但是为了防止今后添加了有参的构造(此时系统不会默认生成无参的),忘记添加了无参的构造,导致报错。
总之,记得,无参的构造方法必不可少啦啦。
新建一个 ProductCategoryDao 类,这个类名倒是无所谓,你也可以叫 ProductCategoryRepository
ProductCategoryDao.java
因为本项目使用的是Spring Data JPA 对数据库操作,而且十分方便。
这里需要继承 JpaRepository 接口,这是一个访问数据库模型的超级接口。
JpaRepository<参数1,参数2> 其中参数1表示是对哪个实体(数据表)操作,参数2表示是该实体的主键属性类型。
我们继承了 JpaRepository 接口,就有了很多常用的对数据库增删改查的方法
具体有哪些方法呢?我们查看一下源码,最终找到 CrudRepository 接口
有如上方法,当然不同的方法有携带不同类型的参数的多态。
通常上面的方法还是不够我们使用,我们需要自定义一些方法。
比如我们要根据一个分类类型的列表查询一个列表的分类信息。
我们只需要写如上的接口方法,记住不需要我们写它的实现方法,系统会帮我们做,所以方法名很重要,不能错。
参考这个表格
在 Test 中新建 ProductCategoryDaoTest.java,或者直接使用 IDEA ,点击某个类名或接口名,右键选择 Go To,点击 Test,快速生成 Test 测试类。
我们对几个会用到的方法进行测试
其他补充
1、测试类需要加两个注解
@RunWith(SpringRunner.class)
@SpringBootTest
2、使用断言
我们这里使用断言来验证,如果断言错误,则会无法通过 Test
3、@Transactional 注解
因为我们通常的测试都是会在数据库中生成记录的,比如 save方法会创建一条记录,update方法修改记录。如果我们不想测试的时候在数据库里乱加内容,我们可以使用 @Transactional 注解哦。
这是测试不通过的效果
这是测试通过的效果
1、创建 CategoryService 接口
CategoryService.java
2、创建 CategoryService 实现类
这里的代码都不需要解释了吧
新建 CategoryServiceImplTest.java
这里也没啥好讲的,和之前 Dao 层测试类似。
记住注入的是 CategoryServiceImpl 就行了。
本文链接:https://liuyanzhao.com/6632.html
开始吧。
本文新关键词
lombok插件
@DynamicUpdate注解
@Transactional注解
JpaRepository 接口方法命名规则
断言
一、基本准备
1、数据表结构
我们说过,本文是介绍对商品类目表的增删改查,先看一些商品类目表的结构
这是我之前测试时添加的数据
2、导入数据库依赖,安装 lombok 插件
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-jpa</artifactId>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
前两个是数据库操作使用,第三个 lombok 是一个插件,可以帮我们在打包项目的时候自动生成 Setter/Getter,toString()方法之类的,而我们只需要在类上加一个注解,而不需要写那些冗余的代码。
要使用lombok,在引入上面的依赖后,还需要安装 IDEA 插件,
3、文件结构
下面的是最终的文件结构
我们一步步来讲解
二、实体类的创建
现在我们要创建 product_category 表的实体类,类名需要按照驼峰法,即 ProductCategory
ProductCategory.java
- package com.liuyanzhao.sell.entity;
- import org.hibernate.annotations.DynamicUpdate;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import java.util.Date;
- /**
- * @Author: 言曌
- * @Date: 2017/11/11
- * @Time: 下午4:48
- */
- @Entity
- @DynamicUpdate //可以让updateTime动态更新
- public class ProductCategory {
- //类目id
- @Id
- @GeneratedValue
- private Integer categoryId;
- //类目名字
- private String categoryName;
- //类目编号
- private Integer categoryType;
- public ProductCategory() {
- }
- //创建时间
- private Date createTime;
- //更新时间
- private Date updateTime;
- public Integer getCategoryId() {
- return categoryId;
- }
- public void setCategoryId(Integer categoryId) {
- this.categoryId = categoryId;
- }
- public String getCategoryName() {
- return categoryName;
- }
- public void setCategoryName(String categoryName) {
- this.categoryName = categoryName;
- }
- public Integer getCategoryType() {
- return categoryType;
- }
- public void setCategoryType(Integer categoryType) {
- this.categoryType = categoryType;
- }
- public Date getCreateTime() {
- return createTime;
- }
- public void setCreateTime(Date createTime) {
- this.createTime = createTime;
- }
- public Date getUpdateTime() {
- return updateTime;
- }
- public void setUpdateTime(Date updateTime) {
- this.updateTime = updateTime;
- }
- @Override
- public String toString() {
- return "ProductCategory{" +
- "categoryId=" + categoryId +
- ", categoryName='" + categoryName + '\'' +
- ", categoryType=" + categoryType +
- '}';
- }
- }
有木有感觉上面的代码有点多,特别是那个 Getter/Setter 方法太多了,每新建一个类,都需要加入 Getter/Setter 方法,如果修改某个属性类型的话,也需要修改。其实我们只需要使用之前说的 lombok 工具就可以解决这个问题。
在安装了 lombok 插件和 导入了 lombok 依赖后,我们的代码可以简化很多
ProductCategory.java
- package com.liuyanzhao.sell.entity;
- import lombok.Data;
- import org.hibernate.annotations.DynamicUpdate;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import java.util.Date;
- /**
- * @Author: 言曌
- * @Date: 2017/11/11
- * @Time: 下午4:48
- */
- @Entity
- @DynamicUpdate //可以让updateTime动态更新
- @Data //自动生成 Setter/Getter toString()
- public class ProductCategory {
- //类目id
- @Id
- @GeneratedValue
- private Integer categoryId;
- //类目名字
- private String categoryName;
- //类目编号
- private Integer categoryType;
- //创建时间
- private Date createTime;
- //更新时间
- private Date updateTime;
- public ProductCategory() {
- }
- }
更多补充
1、@Entity 注解
表示该类是一个实体类
2、@DynamicUpdate 注解
可以动态更新数据表中那些需要更新的字段,比如我们的 updateTime 这个属性对应的是数据表中 update_time 字段,这个字段虽然在数据库里写了自动更新的代码,即
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
但是,在这里,如果你对记录更新的时候,没有给 updateTime 属性赋值,它是不会改变的,这时我们不想看到的。
如果我们给这个类加上 @DynamicUpdate 注解,那么我们的 update_time 字段就会随更改时间而改变了。
3、@Data 注解
该注解是 lombok 的
@Data 包含了@ToString,@EqualsAndHashCode,@Getter / @Setter和@RequiredArgsConstructor的功能
4、@Id 注解
表示该属性为主键
5、@GeneratedValue
表示该属性自动生成值,这里指 的是 id 的值自增
6、无参的构造方法
正常情况,系统会默认生成一个无参的构造方法,也就是说我们这里其实是不需要写的。但是为了防止今后添加了有参的构造(此时系统不会默认生成无参的),忘记添加了无参的构造,导致报错。
总之,记得,无参的构造方法必不可少啦啦。
三、Dao 层的创建
新建一个 ProductCategoryDao 类,这个类名倒是无所谓,你也可以叫 ProductCategoryRepository
ProductCategoryDao.java
- package com.liuyanzhao.sell.dao;
- import com.liuyanzhao.sell.entity.ProductCategory;
- import org.springframework.data.jpa.repository.JpaRepository;
- import java.util.List;
- /**
- * @Author: 言曌
- * @Date: 2017/11/11
- * @Time: 下午4:52
- */
- public interface ProductCategoryDao extends JpaRepository<ProductCategory,Integer> {
- List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList);
- }
因为本项目使用的是Spring Data JPA 对数据库操作,而且十分方便。
这里需要继承 JpaRepository 接口,这是一个访问数据库模型的超级接口。
JpaRepository<参数1,参数2> 其中参数1表示是对哪个实体(数据表)操作,参数2表示是该实体的主键属性类型。
我们继承了 JpaRepository 接口,就有了很多常用的对数据库增删改查的方法
具体有哪些方法呢?我们查看一下源码,最终找到 CrudRepository 接口
有如上方法,当然不同的方法有携带不同类型的参数的多态。
通常上面的方法还是不够我们使用,我们需要自定义一些方法。
比如我们要根据一个分类类型的列表查询一个列表的分类信息。
- List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList);
我们只需要写如上的接口方法,记住不需要我们写它的实现方法,系统会帮我们做,所以方法名很重要,不能错。
参考这个表格
关键字 | 方法命名 | sql where字句 |
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equals | findById,findByIdEquals | where id= ? |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEquals | findByIdLessThanEquals | where id <= ? |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEquals | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,NotNull | findByNameNotNull | where name is not null |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like '?%' |
EndingWith | findByNameEndingWith | where name like '%?' |
Containing | findByNameContaining | where name like '%?%' |
OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
Not | findByNameNot | where name <> ? |
In | findByIdIn(Collection<?> c) | where id in (?) |
NotIn | findByIdNotIn(Collection<?> c) | where id not in (?) |
True | findByAaaTue | where aaa = true |
False | findByAaaFalse | where aaa = false |
IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
四、测试 Dao 层的方法
在 Test 中新建 ProductCategoryDaoTest.java,或者直接使用 IDEA ,点击某个类名或接口名,右键选择 Go To,点击 Test,快速生成 Test 测试类。
我们对几个会用到的方法进行测试
- package com.liuyanzhao.sell.dao;
- import com.liuyanzhao.sell.entity.ProductCategory;
- import org.junit.Assert;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.test.context.junit4.SpringRunner;
- import org.springframework.transaction.annotation.Transactional;
- import java.util.Arrays;
- import java.util.List;
- /**
- * @Author: 言曌
- * @Date: 2017/11/11
- * @Time: 下午4:54
- */
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class ProductCategoryDaoTest {
- @Autowired
- private ProductCategoryDao dao;
- @Test
- public void findOneTest() {
- ProductCategory productCategory = dao.findOne(1);
- System.out.println(productCategory);
- }
- @Test
- @Transactional //不在数据库中添加测试数据
- public void saveTest() {
- ProductCategory productCategory = new ProductCategory();
- productCategory.setCategoryName("零食");
- productCategory.setCategoryType(3);
- ProductCategory result = dao.save(productCategory);
- //使用断言判断
- Assert.assertNotNull(result);
- //Assert.assertNotEquals(null,result);//与上面效果一样
- }
- @Test
- public void updateTest() {
- ProductCategory productCategory = dao.findOne(2);
- productCategory.setCategoryName("饮料");
- productCategory.setCategoryType(5);
- dao.save(productCategory);
- }
- @Test
- public void findByCategoryTypeInTest() {
- List<Integer> list = Arrays.asList(1,2,3);
- List<ProductCategory> result = dao.findByCategoryTypeIn(list);
- Assert.assertNotEquals(0,result.size());
- }
- }
其他补充
1、测试类需要加两个注解
@RunWith(SpringRunner.class)
@SpringBootTest
2、使用断言
我们这里使用断言来验证,如果断言错误,则会无法通过 Test
3、@Transactional 注解
因为我们通常的测试都是会在数据库中生成记录的,比如 save方法会创建一条记录,update方法修改记录。如果我们不想测试的时候在数据库里乱加内容,我们可以使用 @Transactional 注解哦。
这是测试不通过的效果
这是测试通过的效果
五、Service 层的创建
1、创建 CategoryService 接口
CategoryService.java
- package com.liuyanzhao.sell.service;
- import com.liuyanzhao.sell.entity.ProductCategory;
- import java.util.List;
- /**
- * @Author: 言曌
- * @Date: 2017/11/11
- * @Time: 下午6:50
- */
- public interface CategoryService {
- //查询一条记录
- ProductCategory findOne(Integer categoryId);
- //查询所有记录
- List<ProductCategory> findAll();
- //查询分类列表的分类
- List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList);
- //添加分类
- ProductCategory save(ProductCategory productCategory);
- }
2、创建 CategoryService 实现类
- package com.liuyanzhao.sell.service.impl;
- import com.liuyanzhao.sell.dao.ProductCategoryDao;
- import com.liuyanzhao.sell.entity.ProductCategory;
- import com.liuyanzhao.sell.service.CategoryService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import java.util.List;
- /**
- * @Author: 言曌
- * @Date: 2017/11/11
- * @Time: 下午7:04
- */
- @Service
- public class CategoryServiceImpl implements CategoryService {
- @Autowired
- private ProductCategoryDao dao;
- @Override
- public ProductCategory findOne(Integer categoryId) {
- return dao.findOne(categoryId);
- }
- @Override
- public List<ProductCategory> findAll() {
- return dao.findAll();
- }
- @Override
- public List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList) {
- return dao.findByCategoryTypeIn(categoryTypeList);
- }
- @Override
- public ProductCategory save(ProductCategory productCategory) {
- return dao.save(productCategory);
- }
- }
这里的代码都不需要解释了吧
六、Service 层的测试
新建 CategoryServiceImplTest.java
- package com.liuyanzhao.sell.service.impl;
- import com.liuyanzhao.sell.entity.ProductCategory;
- import org.junit.Assert;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.test.context.junit4.SpringRunner;
- import java.util.Arrays;
- import java.util.List;
- import static org.junit.Assert.*;
- /**
- * @Author: 言曌
- * @Date: 2017/11/11
- * @Time: 下午7:07
- */
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class CategoryServiceImplTest {
- @Autowired
- private CategoryServiceImpl categoryService;
- @Test
- public void findOne() throws Exception {
- ProductCategory productCategory = categoryService.findOne(1);
- Assert.assertEquals(new Integer(1),productCategory.getCategoryId());
- }
- @Test
- public void findAll() throws Exception {
- List<ProductCategory> productCategoryList = categoryService.findAll();
- Assert.assertNotEquals(0,productCategoryList.size());
- }
- @Test
- public void findByCategoryTypeIn() throws Exception {
- List<ProductCategory> productCategoryList = categoryService.findByCategoryTypeIn(Arrays.asList(1,2,3));
- Assert.assertNotEquals(0,productCategoryList.size());
- }
- @Test
- public void save() throws Exception {
- ProductCategory productCategory = new ProductCategory();
- productCategory.setCategoryName("酒类");
- productCategory.setCategoryType(5);
- ProductCategory result = categoryService.save(productCategory);
- Assert.assertNotNull(result);
- }
- }
这里也没啥好讲的,和之前 Dao 层测试类似。
记住注入的是 CategoryServiceImpl 就行了。
本文链接:https://liuyanzhao.com/6632.html
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏