1. Tymeleaf
与jpa
依赖问题
SpringBoot 2.0.4版本下,pom.xml
文件中添加Thymeleaf
依赖后,首行<object>
标签有红色下划线报错,错误信息大意为无法解决Tymeleaf
版本问题,且External Liabraires
下没有Spring-boot-start-thymeleaf
包。这是由于Tymeleaf
没有对应于该版本的依赖,更换SpringBoot
版本即可。另外,该版本的jpa
依赖貌似也有问题,运行时会抛出异常。
2. jpa
实体类中字段注解与表中字段对应问题。
jpa
中,实体类中的字段通过@ Column
注解与表中字段关联。如:
@Column(name="age",nullable=false)
private String userAge;
表示实体类中的userAge
属性与表中的age
字段相对应,若注解中不加name
标注,则默认属性名与字段名一致。但存在问题是,当表中字段采用小驼峰式命名规则时,当调用jpa
的查询语句时,会自动将驼峰式命名转化为下划线式命名,且优先级高于注解。
例,若实体类中有属性userName
,对应表中的相应字段也为userName
,且实体类中有注解:
@Column(name="userName",nullable=false)
private String userName;
则在查询时,返回的查询结果中不会具有userName
属性,而是会自动将其属性名转化为user_name
,此时,jpa
要将返回结果装载到实体类以返回时,由于实体类中没有user_name
属性,就会报错,实体类中的注解在这种情况下也相当于失去了作用。
总结此问题,jpa
默认在数据库中采用下划线式命名规则,在实体类中默认采用小驼峰式命名规则,且会自动转换,因此,在建表时,表中字段应统一采用下划线式命名规则。
3. jpa
中Respository
接口抛出空指针异常问题
为代码更加规范,在定义完实体类的Respository
接口后,再定义service
接口与serviceIpml
实现类对Respositoy
进行进一步封装,在serviceIpml
实现类中调用Respository
进行数据库操作时,抛出NullPointerException
异常。这是由于调用Repository
接口的类须为可以被Spring
装载的Bean
,在serviceImpl
中加入注解@ Service
即可。如:
//Repository接口
public interface UserRepository extends CrudRepository<UserEntity,Long> {
Optional<UserEntity> findByName(@Param("name") String name);
Optional<UserEntity> findByNameAndPass(@Param("name") String name,@Param("pass") String pass);
Optional<UserEntity> findByEmail(@Param("email") String email);
}
//service接口
public interface UserService {
List<UserEntity> findAll();
UserEntity findById(Long id);
UserEntity findByName(String name);
}
//serviceImpl实现类,需加@Service注解
@Service
public class UserServiceImpl implements UserService {
@Autowired private UserRepository userRep;
@Override
public List<UserEntity> findAll() {
List<UserEntity> userList=new LinkedList<>();
userRep.findAll().forEach(userList::add);
return userList;
}
@Override
public UserEntity findById(Long id) {
return userRep.findById(id).orElse(null);
}
@Override
public UserEntity findByName(String name) {
return userRep.findByName(name).orElse(null);
}
}
4. 采用@ Query
注解自定义查询方法时报错
如自定义按时间范围查询的方法如下:
@Query(value = "select * from bill where create_time>=?1 and ?2>=create_time")
fun findTimeRange(startTime:Timestamp,endTime:Timestamp):Iterable<Bill>?
对该方法执行单元测试时,会报如下关键错:
解决方法为加入nativeQuery = true
字段说明:
@Query(value = "select * from bill where create_time>=?1 and ?2>=create_time",nativeQuery = true)
fun findTimeRange(startTime:Timestamp,endTime:Timestamp):Iterable<Bill>?