1 SpringBootData JPA介绍
SpringData:其实SpringData就是Spring提供了一个操作数据的框架。而SpringData JPA只是SpringData框架下的一个基于JPA标准操作数据的模块。
SpringData JPA:基于JPA的标准数据进行操作。简化操作持久层的代码。只需要编写接口就可以。
2 SpringBoot整合SpringData JPA
1、导入maven依赖
在原有的SprigBoot的maven依赖的基础下加上JPA的依赖
2、application.properties文件中添加配置
3、实体类
import javax.persistence.*; @Entity @Table(name="t_users") public class Users { @Id //主键id @GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略 @Column(name="id")//数据库字段名 private Integer id; @Column(name="name") private String name; @Column(name="age") private Integer age; @Column(name="address") private String address; @ManyToOne(cascade = CascadeType.PERSIST) //表示多方 @JoinColumn(name ="role_id") //维护一个外键,外键在Users一侧 private Roles roles; public Roles getRoles() { return roles; } public void setRoles(Roles roles) { this.roles = roles; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Users{"); sb.append("id=").append(id); sb.append(", name='").append(name).append('\''); sb.append(", age=").append(age); sb.append(", address='").append(address).append('\''); sb.append(", roles=").append(roles); sb.append('}'); return sb.toString(); } }
4、编写Dao接口
import org.springframework.data.jpa.repository.JpaRepository; import com.oldlu.pojo.Users; /** * 参数一 T :当前需要映射的实体 * 参数二 ID :当前映射的实体中的OID的类型 * */ public interface UsersRepository extends JpaRepository<Users,Integer> { }
6、在pom文件中添加测试启动器的坐标
7、测试
3 SpringBoot JPA提供的核心接口
1、Repository接口
2、CrudRepository接口
3、PagingAndSortingRepository接口
4、JpaRepository接口
5、JPASpecificationExecutor接口
4 Repository接口的使用
提供了方法名称命名查询方式
提供了基于@Query注解查询与更新
1、dao层接口(方法名称命名查询方式)
import com.oldlu.pojo.Users; import org.springframework.data.repository.Repository; import java.util.List; /** * Repository接口方法名称命名查询 * */ public interface UsersRepositoryByName extends Repository<Users,Integer> { //方法名称必须要遵循驼峰式命名规则,findBy(关键字)+属性名称(首字母大写)+查询条件(首字母大写) List<Users> findByName(String name); List<Users> findByNameAndAge(String name,Integer age); List<Users> findByNameLike(String name); }
2、测试
/** * Repository */ @Test public void UsersRepositoryByName(){ List<Users> list=this.usersRepositoryByName.findByName("张三"); for (Users users:list){ System.out.println(users); } } @Test public void findByNameAndAge(){ List<Users> list=this.usersRepositoryByName.findByNameAndAge("张三",20); for (Users users:list){ System.out.println(users); } } @Test public void findByNameLike() { List<Users> list = this.usersRepositoryByName.findByNameLike("张%"); for (Users users : list) { System.out.println(users); } }
3、dao层接口编写(基于@Query注解查询与更新)
import com.oldlu.pojo.Users; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import java.util.List; /** * 〈一句话功能简述〉<br> * Repository @Query * * @author admin * @create 2019/5/22 * @since 1.0.0 */ public interface UsersRepositoryQueryAnnotation extends JpaRepository<Users,Integer> { @Query("from Users where name = ?") List<Users> queryByNameUseHQL(String name); @Query(value = "select * from t_user where name=?",nativeQuery = true) List<Users> queryByNameUseSQL(String name); @Query("update Users set name=? where id=?") @Modifying //需要执行一个更新操作 void updateUsersNameById(String name,Integer id); }
4、测试
/** * Repository--@Query测试 */ @Test public void testQueryByNameUseSQL() { List<Users> list = this.usersRepositoryQueryAnnotation.queryByNameUseSQL("张三"); for (Users users : list) { System.out.println(users); } } /** * Repository--@Query测试 */ @Test @Transactional //@Transactional与@Test 一起使用时 事务是自动回滚的。 @Rollback(false) //取消自动回滚 public void testUpdateUsersNameById() { this.usersRepositoryQueryAnnotation.updateUsersNameById("张三三", 1); }
5 CrudRepository接口的使用
CrudRepository接口,主要是完成一些增删改查的操作。注意:CrudRepository接口继承了Repository接口
1、编写dao层接口
import com.oldlu.pojo.Users; import org.springframework.data.repository.CrudRepository; public interface UsersRepositoryCrudRepository extends CrudRepository<Users,Integer> { } 123456
2、测试
@Test public void testCrudRepositorySave() { Users users=new Users(); users.setName("青衫"); users.setAge(30); users.setAddress("湖南怀化"); this.usersRepositoryCrudRepository.save(users); } @Test public void testCrudRepositoryUpdate() { Users users=new Users(); users.setId(4); users.setName("青"); users.setAge(18); users.setAddress("怀化"); this.usersRepositoryCrudRepository.save(users); } @Test public void testCrudRepositoryFindOne() { Users users=this.usersRepositoryCrudRepository.findOne(4); System.out.println(users); } @Test public void testCrudRepositoryFindAll() { List<Users> list= (List<Users>) this.usersRepositoryCrudRepository.findAll(); for (Users user:list){ System.out.println(user); } } @Test public void testCrudRepositoryDeleteById() { this.usersRepositoryCrudRepository.delete(4); }
6 PagingAndSortingRepository接口的使用
该接口提供了分页与排序的操作,注意:该接口继承了CrudRepository接口
1、编写dao层
import com.oldlu.pojo.Users; import org.springframework.data.repository.PagingAndSortingRepository; public interface UsersRepositoryPagingAndSorting extends PagingAndSortingRepository<Users,Integer> { } 123456
2、测试
@Test public void testPagingAndSortingRepositorySort() { //Order 定义了排序规则 Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id"); //Sort对象封装了排序规则 Sort sort=new Sort(order); List<Users> list= (List<Users>) this.usersRepositoryPagingAndSorting.findAll(sort); for (Users users:list){ System.out.println(users); } } @Test public void testPagingAndSortingRepositoryPaging() { //Pageable:封装了分页的参数,当前页,煤业显示的条数。注意:它的当前页是从0开始 //PageRequest(page,size):page表示当前页,size表示每页显示多少条 Pageable pageable=new PageRequest(1,2); Page<Users> page=this.usersRepositoryPagingAndSorting.findAll(pageable); System.out.println("数据的总条数:"+page.getTotalElements()); System.out.println("总页数:"+page.getTotalPages()); List<Users> list=page.getContent(); for (Users users:list){ System.out.println(users); } } @Test public void testPagingAndSortingRepositorySortAndPaging() { Sort sort=new Sort(new Sort.Order(Sort.Direction.DESC,"id")); Pageable pageable=new PageRequest(0,2,sort); Page<Users> page=this.usersRepositoryPagingAndSorting.findAll(pageable); System.out.println("数据的总条数:"+page.getTotalElements()); System.out.println("总页数:"+page.getTotalPages()); List<Users> list=page.getContent(); for (Users users:list){ System.out.println(users); } }
7 JpaRepository接口
该接口继承了PagingAndSortingRepository。对继承的父接口中方法的返回值进行适配。
1、dao层接口编写
/** * 参数一 T :当前需要映射的实体 * 参数二 ID :当前映射的实体中的OID的类型 * */ public interface UsersRepository extends JpaRepository<Users,Integer> { }
2、测试
/** * JpaRepository 排序测试 */ @Test public void testJpaRepositorySort() { //Order 定义了排序规则 Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id"); //Sort对象封装了排序规则 Sort sort=new Sort(order); List<Users> list= this.usersRepository.findAll(sort); for (Users users:list){ System.out.println(users); } }
8 JPASpecificationExecutor接口
该接口主要是提供了多条件查询的支持,并且可以在查询中添加排序与分页。注意JPASpecificationExecutor是单独存在的。完全独立
1、dao层接口编写
import com.oldlu.pojo.Users; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; /** * 〈一句话功能简述〉<br> * JpaSpecificationExecutor * * @author admin * @create 2019/5/23 * @since 1.0.0 */ public interface UserRepositorySpecification extends JpaRepository<Users,Integer>,JpaSpecificationExecutor<Users> { }
2、测试
/** * JpaSpecificationExecutor 单条件查询 */ @Test public void testJpaSpecificationExecutor1() { /** * Specification:用于封装查查询条件 */ Specification<Users> spec=new Specification<Users>() { //Predicate:封装了单个查询条件 /** * @param root 对查询对象属性的封装 * @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order * @param criteriaBuilder 查询条件的构造器 * @return */ @Override public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //where name="张三" /** * 参数一:查询的属性 * 参数二:条件的值 */ Predicate predicate=criteriaBuilder.equal(root.get("name"),"张三"); return predicate; } }; List<Users> list=this.userRepositorySpecification.findAll(spec); for (Users users:list){ System.out.println(users); } } /** * JpaSpecificationExecutor 多条件查询方式一 */ @Test public void testJpaSpecificationExecutor2() { /** * Specification:用于封装查查询条件 */ Specification<Users> spec=new Specification<Users>() { //Predicate:封装了单个查询条件 /** * @param root 对查询对象属性的封装 * @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order * @param criteriaBuilder 查询条件的构造器 * @return */ @Override public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //where name="张三" and age=20 /** * 参数一:查询的属性 * 参数二:条件的值 */ List<Predicate> list=new ArrayList<>(); list.add(criteriaBuilder.equal(root.get("name"),"张三")); list.add(criteriaBuilder.equal(root.get("age"),20)); Predicate[] arr=new Predicate[list.size()]; return criteriaBuilder.and(list.toArray(arr)); } }; List<Users> list=this.userRepositorySpecification.findAll(spec); for (Users users:list){ System.out.println(users); } } /** * JpaSpecificationExecutor 多条件查询方式二 */ @Test public void testJpaSpecificationExecutor3() { /** * Specification:用于封装查查询条件 */ Specification<Users> spec=new Specification<Users>() { //Predicate:封装了单个查询条件 /** * @param root 对查询对象属性的封装 * @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order * @param criteriaBuilder 查询条件的构造器 * @return */ @Override public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //where name="张三" and age=20 /** * 参数一:查询的属性 * 参数二:条件的值 */ /*List<Predicate> list=new ArrayList<>(); list.add(criteriaBuilder.equal(root.get("name"),"张三")); list.add(criteriaBuilder.equal(root.get("age"),20)); Predicate[] arr=new Predicate[list.size()];*/ //(name='张三' and age=20) or id=2 return criteriaBuilder.or(criteriaBuilder.and(criteriaBuilder.equal(root.get("name"),"张三"),criteriaBuilder.equal(root.get("age"),20)),criteriaBuilder.equal(root.get("id"),1)); } }; Sort sort=new Sort(new Sort.Order(Sort.Direction.DESC,"id")); List<Users> list=this.userRepositorySpecification.findAll(spec,sort); for (Users users:list){ System.out.println(users); } }
9 实际开发遇到的问题
9.1 org.springframework.data.mapping.PropertyReferenceException: No property created found for type
错误原因:
org.springframework.data.domain.Sort
Sort sort=new Sort(Sort.Direction.DESC,“created_time”);//此处使用了数据库的字段名
public Sort(Sort.Direction direction, String... properties) {//property对应的是table orm后的Java对象的字段名 this(direction, (List)(properties == null?new ArrayList():Arrays.asList(properties))); }
Sort sort=new Sort(Sort.Direction.DESC,“createdTime”);//table表字段对应的java对象字段名
2017-01-15 20:09:26.396 DEBUG 8604 --- [nio-8080-exec-1] org.hibernate.loader.Loader : Result set row: 0 2017-01-15 20:09:26.396 DEBUG 8604 --- [nio-8080-exec-1] org.hibernate.loader.Loader : Result row: 2017-01-15 20:09:26.410 ERROR 8604 --- [nio-8080-exec-1] com.global.GlobalHandler : No property created found for type DailyNews! org.springframework.data.mapping.PropertyReferenceException: No property created found for type DailyNews! at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:77) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.QueryUtils.toJpaOrder(QueryUtils.java:542) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.QueryUtils.toOrders(QueryUtils.java:496) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:169) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:137) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:49) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:136) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:78) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:193) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:82) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:482) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.12.6.RELEASE.jar:na] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) ~[spring-tx-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) ~[spring-data-jpa-1.10.6.RELEASE.jar:na] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE] at com.sun.proxy.$Proxy98.findByStatus(Unknown Source) ~[na:na]
9.2 插入数据时 Duplicate entry ‘admin’ for key ‘name’
插入时看字段是否有Unique索引,或者唯一主键.
Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry ‘admin’ for key ‘username’ The error may involve com.db.sys.dao.SysUserDao.insertObject-Inline The error occurred while setting parameters SQL: insert into sys_users (username,password,deptId,email,mobile,salt,valid, createdTime,modifiedTime,createdUser,modifiedUser) values (?,?,?,?,?,?,?, now(),now(),?,?) Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry ‘admin’ for key ‘username’ ; SQL []; Duplicate entry ‘admin’ for key ‘username’; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry ‘admin’ for key ‘username’ at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:239) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73) at org.mybatis.spring.SqlSessionTemplate S q l S e s s i o n I n t e r c e p t o r . i n v o k e ( S q l S e s s i o n T e m p l a t e . j a v a : 446 ) a t c o m . s u n . p r o x y . SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446) at com.sun.proxy. SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)atcom.sun.proxy.Proxy643.insert(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278) at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:51) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) at com.sun.proxy. P r o x y 645. i n s e r t O b j e c t ( U n k n o w n S o u r c e ) a t c o m . d b . s y s . s e r v i c e . i m p l . S y s U s e r S e r v i c e I m p l . s a v e O b j e c t ( S y s U s e r S e r v i c e I m p l . j a v a : 102 ) a t c o m . d b . s y s . c o n t r o l l e r . S y s U s e r C o n t r o l l e r . d o S a v e O b j e c t ( S y s U s e r C o n t r o l l e r . j a v a : 56 ) a t s u n . r e f l e c t . N a t i v e M e t h o d A c c e s s o r I m p l . i n v o k e 0 ( N a t i v e M e t h o d ) a t s u n . r e f l e c t . N a t i v e M e t h o d A c c e s s o r I m p l . i n v o k e ( U n k n o w n S o u r c e ) a t s u n . r e f l e c t . D e l e g a t i n g M e t h o d A c c e s s o r I m p l . i n v o k e ( U n k n o w n S o u r c e ) a t j a v a . l a n g . r e f l e c t . M e t h o d . i n v o k e ( U n k n o w n S o u r c e ) a t o r g . s p r i n g f r a m e w o r k . w e b . m e t h o d . s u p p o r t . I n v o c a b l e H a n d l e r M e t h o d . d o I n v o k e ( I n v o c a b l e H a n d l e r M e t h o d . j a v a : 205 ) a t o r g . s p r i n g f r a m e w o r k . w e b . m e t h o d . s u p p o r t . I n v o c a b l e H a n d l e r M e t h o d . i n v o k e F o r R e q u e s t ( I n v o c a b l e H a n d l e r M e t h o d . j a v a : 133 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . m v c . m e t h o d . a n n o t a t i o n . S e r v l e t I n v o c a b l e H a n d l e r M e t h o d . i n v o k e A n d H a n d l e ( S e r v l e t I n v o c a b l e H a n d l e r M e t h o d . j a v a : 97 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . m v c . m e t h o d . a n n o t a t i o n . R e q u e s t M a p p i n g H a n d l e r A d a p t e r . i n v o k e H a n d l e r M e t h o d ( R e q u e s t M a p p i n g H a n d l e r A d a p t e r . j a v a : 827 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . m v c . m e t h o d . a n n o t a t i o n . R e q u e s t M a p p i n g H a n d l e r A d a p t e r . h a n d l e I n t e r n a l ( R e q u e s t M a p p i n g H a n d l e r A d a p t e r . j a v a : 738 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . m v c . m e t h o d . A b s t r a c t H a n d l e r M e t h o d A d a p t e r . h a n d l e ( A b s t r a c t H a n d l e r M e t h o d A d a p t e r . j a v a : 85 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . D i s p a t c h e r S e r v l e t . d o D i s p a t c h ( D i s p a t c h e r S e r v l e t . j a v a : 967 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . D i s p a t c h e r S e r v l e t . d o S e r v i c e ( D i s p a t c h e r S e r v l e t . j a v a : 901 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . F r a m e w o r k S e r v l e t . p r o c e s s R e q u e s t ( F r a m e w o r k S e r v l e t . j a v a : 970 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . F r a m e w o r k S e r v l e t . d o P o s t ( F r a m e w o r k S e r v l e t . j a v a : 872 ) a t j a v a x . s e r v l e t . h t t p . H t t p S e r v l e t . s e r v i c e ( H t t p S e r v l e t . j a v a : 648 ) a t o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . F r a m e w o r k S e r v l e t . s e r v i c e ( F r a m e w o r k S e r v l e t . j a v a : 846 ) a t j a v a x . s e r v l e t . h t t p . H t t p S e r v l e t . s e r v i c e ( H t t p S e r v l e t . j a v a : 729 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . A p p l i c a t i o n F i l t e r C h a i n . i n t e r n a l D o F i l t e r ( A p p l i c a t i o n F i l t e r C h a i n . j a v a : 292 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . A p p l i c a t i o n F i l t e r C h a i n . d o F i l t e r ( A p p l i c a t i o n F i l t e r C h a i n . j a v a : 207 ) a t o r g . a p a c h e . t o m c a t . w e b s o c k e t . s e r v e r . W s F i l t e r . d o F i l t e r ( W s F i l t e r . j a v a : 52 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . A p p l i c a t i o n F i l t e r C h a i n . i n t e r n a l D o F i l t e r ( A p p l i c a t i o n F i l t e r C h a i n . j a v a : 240 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . A p p l i c a t i o n F i l t e r C h a i n . d o F i l t e r ( A p p l i c a t i o n F i l t e r C h a i n . j a v a : 207 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . S t a n d a r d W r a p p e r V a l v e . i n v o k e ( S t a n d a r d W r a p p e r V a l v e . j a v a : 212 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . S t a n d a r d C o n t e x t V a l v e . i n v o k e ( S t a n d a r d C o n t e x t V a l v e . j a v a : 94 ) a t o r g . a p a c h e . c a t a l i n a . a u t h e n t i c a t o r . A u t h e n t i c a t o r B a s e . i n v o k e ( A u t h e n t i c a t o r B a s e . j a v a : 492 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . S t a n d a r d H o s t V a l v e . i n v o k e ( S t a n d a r d H o s t V a l v e . j a v a : 141 ) a t o r g . a p a c h e . c a t a l i n a . v a l v e s . E r r o r R e p o r t V a l v e . i n v o k e ( E r r o r R e p o r t V a l v e . j a v a : 80 ) a t o r g . a p a c h e . c a t a l i n a . v a l v e s . A b s t r a c t A c c e s s L o g V a l v e . i n v o k e ( A b s t r a c t A c c e s s L o g V a l v e . j a v a : 620 ) a t o r g . a p a c h e . c a t a l i n a . c o r e . S t a n d a r d E n g i n e V a l v e . i n v o k e ( S t a n d a r d E n g i n e V a l v e . j a v a : 88 ) a t o r g . a p a c h e . c a t a l i n a . c o n n e c t o r . C o y o t e A d a p t e r . s e r v i c e ( C o y o t e A d a p t e r . j a v a : 502 ) a t o r g . a p a c h e . c o y o t e . h t t p 11. A b s t r a c t H t t p 11 P r o c e s s o r . p r o c e s s ( A b s t r a c t H t t p 11 P r o c e s s o r . j a v a : 1152 ) a t o r g . a p a c h e . c o y o t e . A b s t r a c t P r o t o c o l Proxy645.insertObject(Unknown Source) at com.db.sys.service.impl.SysUserServiceImpl.saveObject(SysUserServiceImpl.java:102) at com.db.sys.controller.SysUserController.doSaveObject(SysUserController.java:56) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1152) at org.apache.coyote.AbstractProtocol Proxy645.insertObject(UnknownSource)atcom.db.sys.service.impl.SysUserServiceImpl.saveObject(SysUserServiceImpl.java:102)atcom.db.sys.controller.SysUserController.doSaveObject(SysUserController.java:56)atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)atsun.reflect.NativeMethodAccessorImpl.invoke(UnknownSource)atsun.reflect.DelegatingMethodAccessorImpl.invoke(UnknownSource)atjava.lang.reflect.Method.invoke(UnknownSource)atorg.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)atorg.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)atorg.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)atorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)atorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)atorg.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)atorg.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)atorg.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)atorg.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)atorg.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:648)atorg.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:729)atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)atorg.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)atorg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)atorg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)atorg.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492)atorg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)atorg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)atorg.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)atorg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)atorg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)atorg.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1152)atorg.apache.coyote.AbstractProtocolAbstractConnectionHandler.process(AbstractProtocol.java:684) at org.apache.tomcat.util.net.NioEndpoint S o c k e t P r o c e s s o r . d o R u n ( N i o E n d p o i n t . j a v a : 1539 ) a t o r g . a p a c h e . t o m c a t . u t i l . n e t . N i o E n d p o i n t SocketProcessor.doRun(NioEndpoint.java:1539) at org.apache.tomcat.util.net.NioEndpoint SocketProcessor.doRun(NioEndpoint.java:1539)atorg.apache.tomcat.util.net.NioEndpointSocketProcessor.run(NioEndpoint.java:1495) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor W o r k e r . r u n ( U n k n o w n S o u r c e ) a t o r g . a p a c h e . t o m c a t . u t i l . t h r e a d s . T a s k T h r e a d Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread Worker.run(UnknownSource)atorg.apache.tomcat.util.threads.TaskThreadWrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source) Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry ‘admin’ for key ‘username’ at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) at com.mysql.jdbc.Util.getInstance(Util.java:408) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192) at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:498) at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:44) at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:69) at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48) at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:105) at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:71) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:152) at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:141) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) … 45 more
9.3 Spring Data JPA@Transient 理解
transient使用小结
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
科普下序列化反序列化持久层持久化,序列化实体类变成json等格式,反序列化就是json变成实体类,持久层就是保存到数据库,持久化保存到数据库的数据的特性。
transient的作用
我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。
然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
简单地说,@transient 就是在给某个javabean上需要添加个属性,但是这个属性你又不希望给存到数据库中去,仅仅是做个非静态的临时变量,用一下。不修改已经存在数据库的数据的数据结构。注意记得getter和setter!
9.4 更新问题
有时候更新操作会把null值也进行更新,将更新的字段填满,将需要更改的字段重新赋值即可
/** * 更新开庭人员状态 */ @ApiOperation(value = "1. 更新开庭人员状态或新增开庭人员", notes = "1. 更新开庭人员状态或新增开庭人员") @PostMapping("/save") public Object save(@RequestBody SchedulingMember schedulingMember) { Long id = schedulingMember.getId(); if (id != null) { SchedulingMember schedulingMemberUpdate = schedulingMemberRepository.findById(id).get(); BeanUtils.copyProperties(schedulingMember, schedulingMemberUpdate, getNullPropertyNames(schedulingMember)); return schedulingMemberRepository.save(schedulingMemberUpdate); } else { return schedulingMemberRepository.save(schedulingMember); } }
9.5 spring data jpa返回结果无法转换
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object[]] to type [com.jzh.graduation.entity.SysPermission] for value ‘{1, 权限管理, /sys/permission/**}’; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Integer] to type [com.jzh.graduation.entity.SysPermission]
原因:返回结果应该转换为对象SysPermission,JPA原生sql写在SysUserDao下(返回结果转换为SysUser),返回结果无法转换,应该写在SysPermissionDao下。