查询出来的对象ProductCategory就已经有updateTime和createTime了,然而你只是把对象的categoryType给修改了一下,修改之后就执行save方法保存了。所以它还是原来的时间。如果有一个自动更新时间的目的,那就增加一个注解

@DynamicUpdate //动态更新时间.
public class ProductCategory{
package com.imooc.sell.dataobject;

//import javax.persistence.Table;

import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Proxy; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date; /**
* 类目
* Created by zhongzh
* 2018-05-20 9:31
* s_product_category
*/
//@Table(name = "s_product_category")
@Entity//把数据库映射成对象
@Proxy(lazy = false)
@DynamicUpdate //动态更新时间.
public class ProductCategory{
/** 类目id. */
@Id//Id是主键,自增类型的。
//@GeneratedValue//相当于调用了native策略
//@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer categoryId;//字段名的命名方式也是一样的,把下划线改成为空。
/** 类目名字. */
private String categoryName; /** 类目编号. */
private Integer categoryType;
/** 创建时间. */
private Date createTime;
/** 修改时间. */
private Date updateTime;
//不要忘了Getter和Setter方法
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 +
'}';
}
}

更新之前

Hibernate: select productcat0_.category_id as category1_0_0_, productcat0_.category_name as category2_0_0_, productcat0_.category_type as category3_0_0_, productcat0_.create_time as create_t4_0_0_, productcat0_.update_time as update_t5_0_0_ from product_category productcat0_ where productcat0_.category_id=?
Hibernate: select productcat0_.category_id as category1_0_0_, productcat0_.category_name as category2_0_0_, productcat0_.category_type as category3_0_0_, productcat0_.create_time as create_t4_0_0_, productcat0_.update_time as update_t5_0_0_ from product_category productcat0_ where productcat0_.category_id=?

更新之后


    @Test
public void saveTest(){
ProductCategory productCategory = repository.getOne(2);
//ProductCategory productCategory = new ProductCategory();
//productCategory.setCategoryId(2);
//productCategory.setCategoryName("女生最爱");
//productCategory.setCategoryType(3);
//productCategory.setCategoryName("男生最爱");
//productCategory.setCategoryType(4);
//productCategory.setCategoryName("老少咸宜");
//productCategory.setCategoryType(5);
productCategory.setCategoryType(11);
repository.save(productCategory);
}
Hibernate: select productcat0_.category_id as category1_0_0_, productcat0_.category_name as category2_0_0_, productcat0_.category_type as category3_0_0_, productcat0_.create_time as create_t4_0_0_, productcat0_.update_time as update_t5_0_0_ from product_category productcat0_ where productcat0_.category_id=?
Hibernate: select productcat0_.category_id as category1_0_0_, productcat0_.category_name as category2_0_0_, productcat0_.category_type as category3_0_0_, productcat0_.create_time as create_t4_0_0_, productcat0_.update_time as update_t5_0_0_ from product_category productcat0_ where productcat0_.category_id=?
Hibernate: update product_category set category_type=? where category_id=?

更新之后


老司机带来干货了!!!!!

实体类对象不用再写getter和setter方法了。在pom.xml依赖里面引进lombok工具。lombok是印尼的一个。

        <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

添加完之后你在命令行里面进行maven打包它已经能够起作用了。但是你希望在我们那个编译器里面能够跑起来的话还是需要装一个插件才行。

Lombok Plugin是一个完全免费的一个插件。

在代码里面如何使用呢?

package com.imooc.sell.dataobject;

//import javax.persistence.Table;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Proxy; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date; /**
* 类目
* Created by zhongzh
* 2018-05-20 9:31
* s_product_category
*/
//@Table(name = "s_product_category")
@Entity//把数据库映射成对象
@Proxy(lazy = false)
@DynamicUpdate //
@Data//@Data包含生成getter、setter和toString()方法
//@Getter//如果只是需要Getter那就引入Getter
//@Setter//如果只是需要Setter那就引入Setter
//@ToString//如果只是需要ToString那就引入ToString
public class ProductCategory{
/** 类目id. */
@Id//Id是主键,自增类型的。
//@GeneratedValue//相当于调用了native策略
//@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer categoryId;//字段名的命名方式也是一样的,把下划线改成为空。
/** 类目名字. */
private String categoryName; /** 类目编号. */
private Integer categoryType;
/** 创建时间. */
private Date createTime;
/** 修改时间. */
private Date updateTime;
//不要忘了Getter和Setter方法
/*
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 +
'}';
}
*/
}

代码变得非常简洁了。

关于性能方面,代码每次运行的时候,或者是说每次请求来的时候,每次用到ProductCategory这个对象里面的getter和setter方法它都要重新生成一遍呢?其实不是的,当你程序编译好的时候,你要打成一个JAR包或者是WAR包的时候,它已经帮你干了这些事情了,它会帮你生成这些属性的getter和setter方法的代码。其实性能上和之前我们手动书写getter和setter方法是完全一模一样的。这点我们完全不用担心。

在对象ProductCategory写一个有参构造方法这样就不用在测试类ProductCategoryRepositoryTest老是new一个ProductCategory对象之后不断地set值,代码会简洁很多。

更新之前

更新之后

Hibernate: select productcat0_.category_id as category1_0_0_, productcat0_.category_name as category2_0_0_, productcat0_.category_type as category3_0_0_, productcat0_.create_time as create_t4_0_0_, productcat0_.update_time as update_t5_0_0_ from product_category productcat0_ where productcat0_.category_id=?
Hibernate: select productcat0_.category_id as category1_0_0_, productcat0_.category_name as category2_0_0_, productcat0_.category_type as category3_0_0_, productcat0_.create_time as create_t4_0_0_, productcat0_.update_time as update_t5_0_0_ from product_category productcat0_ where productcat0_.category_id=?
Hibernate: update product_category set category_type=? where category_id=?


单元测试加断言,用assertNotEquals方法

    public static void assertNotEquals(Object unexpected, Object actual) {
assertNotEquals((String)null, unexpected, actual);
}

再次测试是否能够插入得进去,

    @Test
public void saveTest(){
//ProductCategory productCategory = repository.getOne(2);
//ProductCategory productCategory = new ProductCategory();
//productCategory.setCategoryId(2);
//productCategory.setCategoryName("女生最爱");
//productCategory.setCategoryType(3);
//productCategory.setCategoryName("男生最爱");
//productCategory.setCategoryType(4);
//productCategory.setCategoryName("老少咸宜");
//productCategory.setCategoryType(5);
//productCategory.setCategoryType(12);
ProductCategory productCategory = new ProductCategory("老少咸宜",12);
ProductCategory result = repository.save(productCategory);//返回的也是ProductCategory这个对象
//Assert.assertNotNull(result);//断言,判断是否成功,返回的result不等于null
Assert.assertNotEquals(null,result);
}

失败了。。。因为category_type有唯一约束键uqe_category_type,不能插入重复值

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [uqe_category_type]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:)
at com.sun.proxy.$Proxy89.save(Unknown Source)
at com.imooc.sell.repository.ProductCategoryRepositoryTest.saveTest(ProductCategoryRepositoryTest.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at org.junit.runners.model.FrameworkMethod$.runReflectiveCall(FrameworkMethod.java:)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:)
at org.junit.runners.ParentRunner$.run(ParentRunner.java:)
at org.junit.runners.ParentRunner$.schedule(ParentRunner.java:)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:)
at org.junit.runners.ParentRunner.access$(ParentRunner.java:)
at org.junit.runners.ParentRunner$.evaluate(ParentRunner.java:)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:)
at org.junit.runners.ParentRunner.run(ParentRunner.java:)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:)
at org.junit.runner.JUnitCore.run(JUnitCore.java:)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:)
at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:)
at com.sun.proxy.$Proxy87.persist(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:)
... more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '' for key 'uqe_category_type'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:)
at java.lang.reflect.Constructor.newInstance(Constructor.java:)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:)
at com.mysql.jdbc.Util.getInstance(Util.java:)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:)
... more

插入前

Hibernate: insert into product_category (category_name, category_type, create_time, update_time) values (?, ?, ?, ?)

插入后

之前插入失败,category_id也算增加了一次。。。。


希望测试完数据库是干净的,不要有我们测试的数据的。 使用@Transactional标签

@Test
@Transactional//事务
public void saveTest(){
//ProductCategory productCategory = repository.getOne(2);
//ProductCategory productCategory = new ProductCategory();
//productCategory.setCategoryId(2);
//productCategory.setCategoryName("女生最爱");
//productCategory.setCategoryType(3);
//productCategory.setCategoryName("男生最爱");
//productCategory.setCategoryType(4);
//productCategory.setCategoryName("老少咸宜");
//productCategory.setCategoryType(5);
//productCategory.setCategoryType(12);
ProductCategory productCategory = new ProductCategory("老少咸宜",10);
ProductCategory result = repository.save(productCategory);//返回的也是ProductCategory这个对象
//Assert.assertNotNull(result);//断言,判断是否成功,返回的result不等于null
Assert.assertNotEquals(null,result);
}

插入前:

插入后:

Hibernate: insert into product_category (category_name, category_type, create_time, update_time) values (?, ?, ?, ?)

在Servcie里面添加@Transactional注解,如果Service方法里面有抛出异常的话,它会回滚,以前产生的数据会被删除,不会留在数据库里面。单元测试里面呢,这个事务完全就是你所做的事情做完之后都会被回滚。


一次性查的,查商品列表的时候,先查商品,再查类目,肯定是一次性查的。而不是分很多次,而且我们是通过category_type类目编号来查的。categoryType的list来查类目。

package com.imooc.sell.repository;

import com.imooc.sell.dataobject.ProductCategory;
//import org.springframework.data.domain.Example;
import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; //import java.util.Locale; //import java.util.Optional; /**
* Created by zhongzh
* 2018-05-25 9:49
* 主键是Integer类型的
*/
public interface ProductCategoryRepository extends JpaRepository<ProductCategory,Integer> {
List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList); }
package com.imooc.sell.repository;

import com.imooc.sell.dataobject.ProductCategory;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
//import org.springframework.boot.SpringApplication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import javax.transaction.Transactional;
import java.util.Arrays;
import java.util.List; //import static org.junit.Assert.*; @RunWith(SpringRunner.class)
@SpringBootTest
public class ProductCategoryRepositoryTest {
@Autowired
private ProductCategoryRepository repository;
@Test
public void findOneTest() {
ProductCategory productCategory = repository.getOne(1);
//ProductCategory productCategory = repository.findById(1);
System.out.println(productCategory.toString());
}
@Test
@Transactional//事务
public void saveTest(){
//ProductCategory productCategory = repository.getOne(2);
//ProductCategory productCategory = new ProductCategory();
//productCategory.setCategoryId(2);
//productCategory.setCategoryName("女生最爱");
//productCategory.setCategoryType(3);
//productCategory.setCategoryName("男生最爱");
//productCategory.setCategoryType(4);
//productCategory.setCategoryName("老少咸宜");
//productCategory.setCategoryType(5);
//productCategory.setCategoryType(12);
ProductCategory productCategory = new ProductCategory("老少咸宜",10);
ProductCategory result = repository.save(productCategory);//返回的也是ProductCategory这个对象
//Assert.assertNotNull(result);//断言,判断是否成功,返回的result不等于null
Assert.assertNotEquals(null,result);
}
@Test
public void findByCategoryTypeInTest(){
List<Integer> list = Arrays.asList(2,12,11);
List<ProductCategory> result = repository.findByCategoryTypeIn(list);
//集合的元素大于0就是成功了
Assert.assertNotEquals(0
,result.size());
}
}

测试一下

Hibernate: select productcat0_.category_id as category1_0_, productcat0_.category_name as category2_0_, productcat0_.category_type as category3_0_, productcat0_.create_time as create_t4_0_, productcat0_.update_time as update_t5_0_ from product_category productcat0_ where productcat0_.category_type in (? , ? , ?)

org.springframework.orm.jpa.JpaSystemException: No default constructor for entity:  : com.imooc.sell.dataobject.ProductCategory; nested exception is org.hibernate.InstantiationException: No default constructor for entity:  : com.imooc.sell.dataobject.ProductCategory

    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:)
at com.sun.proxy.$Proxy90.findByCategoryTypeIn(Unknown Source)
at com.imooc.sell.repository.ProductCategoryRepositoryTest.findByCategoryTypeInTest(ProductCategoryRepositoryTest.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at org.junit.runners.model.FrameworkMethod$.runReflectiveCall(FrameworkMethod.java:)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:)
at org.junit.runners.ParentRunner$.run(ParentRunner.java:)
at org.junit.runners.ParentRunner$.schedule(ParentRunner.java:)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:)
at org.junit.runners.ParentRunner.access$(ParentRunner.java:)
at org.junit.runners.ParentRunner$.evaluate(ParentRunner.java:)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:)
at org.junit.runners.ParentRunner.run(ParentRunner.java:)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:)
at org.junit.runner.JUnitCore.run(JUnitCore.java:)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:)
Caused by: org.hibernate.InstantiationException: No default constructor for entity: : com.imooc.sell.dataobject.ProductCategory
at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:)
at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.instantiate(AbstractEntityTuplizer.java:)
at org.hibernate.persister.entity.AbstractEntityPersister.instantiate(AbstractEntityPersister.java:)
at org.hibernate.internal.SessionImpl.instantiate(SessionImpl.java:)
at org.hibernate.internal.SessionImpl.instantiate(SessionImpl.java:)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:)
at org.hibernate.loader.Loader.getRow(Loader.java:)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:)
at org.hibernate.loader.Loader.processResultSet(Loader.java:)
at org.hibernate.loader.Loader.doQuery(Loader.java:)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:)
at org.hibernate.loader.Loader.doList(Loader.java:)
at org.hibernate.loader.Loader.doList(Loader.java:)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:)
at org.hibernate.loader.Loader.list(Loader.java:)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:)
at org.hibernate.query.Query.getResultList(Query.java:)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:)
at com.sun.proxy.$Proxy93.getResultList(Unknown Source)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:)
... more

因为查询的时候需要实体类对象有一个无参的构造方法才行。

package com.imooc.sell.dataobject;

//import javax.persistence.Table;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Proxy; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date; /**
* 类目
* Created by zhongzh
* 2018-05-20 9:31
* s_product_category
*/
//@Table(name = "s_product_category")
@Entity//把数据库映射成对象
@Proxy(lazy = false)
@DynamicUpdate //
@Data//@Data包含生成getter、setter和toString()方法
//@Getter//如果只是需要Getter那就引入Getter
//@Setter//如果只是需要Setter那就引入Setter
//@ToString//如果只是需要ToString那就引入ToString
public class ProductCategory{
/** 类目id. */
@Id//Id是主键,自增类型的。
//@GeneratedValue//相当于调用了native策略
//@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer categoryId;//字段名的命名方式也是一样的,把下划线改成为空。
/** 类目名字. */
private String categoryName; /** 类目编号. */
private Integer categoryType;
/** 创建时间. */
private Date createTime;
/** 修改时间. */
private Date updateTime;
//不要忘了Getter和Setter方法
/*
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 +
'}';
}
*/ public ProductCategory(String categoryName, Integer categoryType) {
this.categoryName = categoryName;
this.categoryType = categoryType;
} public ProductCategory() {
super();
}
}

大家一定要注意单元测试,你看你测试就测出那么多问题。你如果不测的话到了Service层,所以还是得多测试才行啊。

-- ::05.370  INFO  --- [           main] o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select productcat0_.category_id as category1_0_, productcat0_.category_name as category2_0_, productcat0_.category_type as category3_0_, productcat0_.create_time as create_t4_0_, productcat0_.update_time as update_t5_0_ from product_category productcat0_ where productcat0_.category_type in (? , ? , ?)
-- ::06.594 INFO --- [ Thread-] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@7dfd3c81: startup date [Sat May :: CST ]; root of context hierarchy
Hibernate: select productcat0_.category_id as category1_0_, productcat0_.category_name as category2_0_, productcat0_.category_type as category3_0_, productcat0_.create_time as create_t4_0_, productcat0_.update_time as update_t5_0_ from product_category productcat0_ where productcat0_.category_type in (? , ? , ?)
-- ::54.773  INFO  --- [           main] o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select productcat0_.category_id as category1_0_, productcat0_.category_name as category2_0_, productcat0_.category_type as category3_0_, productcat0_.create_time as create_t4_0_, productcat0_.update_time as update_t5_0_ from product_category productcat0_ where productcat0_.category_type in (? , ? , ?)

    @Test
public void findByCategoryTypeInTest(){
List<Integer> list = Arrays.asList(2,12,11);
List<ProductCategory> result = repository.findByCategoryTypeIn(list);
//集合的元素大于0就是成功了
Assert.assertNotEquals(0,result.size());
}

回顾一下我们做了哪些事情?在pom.xml引入了MySQL和data-jpa的依赖。引入了之后在application.yml做数据库的配置。配置了之后我们创建了一个表的映射:com.imooc.sell.dataobject.ProductCategory。注解也讲过了。

然后写DAO层的代码:com.imooc.sell.repository.ProductCategoryRepository。写了之后进行单元测试:com.imooc.sell.repository.ProductCategoryRepositoryTest。

然后就是插件lombok,可以节省开发时间。

最新文章

  1. 使用Zabbix监控Oracle数据库
  2. 10道javascript笔试题
  3. 布隆过滤器的概述及Python实现
  4. Spring使用非applicationContext.xm 默认名的配置文件的配置
  5. 9、SQL Server 操作数据
  6. LeetCode Two Sum III - Data structure design
  7. inline-block使标签间出现空白
  8. labview 中的一些简写全称
  9. 解密FFmpeg播放状态控制内幕
  10. Java虚拟机专题
  11. 2、Khala的安装
  12. OpenResty知识汇集
  13. idea 找不到classpath 为resource下的xml
  14. python实现将base64编码的图片下载到本地
  15. StringBuffer 可变参数拼接
  16. ARMV8 datasheet学习笔记4:AArch64系统级体系结构之存储模型
  17. JAVA_HOME 设置为JDK 7无效
  18. 1109 Group Photo
  19. Java模式—适配器模式
  20. CI框架 -- 核心文件 之 Lang.php(加载语言包)

热门文章

  1. 九度oj 题目1180:对称矩阵
  2. 《C语言程序设计(第四版)》阅读心得(二)
  3. poj3440--Coin Toss(几何上的概率)
  4. view属性大全
  5. Linux 攻击防护基础排查
  6. Ubuntu 16.04安装RapidSVN
  7. Ubuntu 16.04安装Markdown编辑器MarkMyWords
  8. 英特尔固态盘 说明书PDF
  9. Connection节点配置错误解决方案
  10. delphi的一些语法知识 以及参数传递问题,按引用方式传递参数,按值方式传递参数