自己动手搭建一下spring boot的项目,中途遇到了几个问题,在这里记录一下!
一、关于数据库中的表设计的问题
1、设计表的时候一定要添加的两个字段created updated 创建时间与更新时间 这两个字段是必须的
2、数据库的表字段设计一定要规范,因为如果使用分页助手的话,你的表字段设计不规范,会存在很多问题
比如:我的book_info 表中的字段 有一个是pubInfo 驼峰命名法,但是其他的是book_name、img_url 下划线命名法,造成使用通用mapper以及分页助手的时候,会造成找不到pub_info
这一列,我猜可能他的插件的内部是使用的下划线命名法的字段吧,这种东西一定要在设计之前考虑到,规范的是使用下划线那种命名的方法
...这个是可以自己设置的。在实体类中用注解的方式来设置table的名称以及column的名称,害得我重新设计了一张表,不过,最好约束自己遵守规范
3、设计数据库表的字段的时候一定要设置字符集,最好就是通用的utf-8,避免以后数据插入数据库的时候出现乱码的问题
二、项目搭建中问题
集成一下通用mapper以及分页助手以及数据池,优化一下数据库连接访问,通用mapper以及分页助手可以简化很多代码,提高开发效率
1、分页助手的版本问题
正确的maven中的依赖各个版本号:
1 <!--通用mapper --> 2 <dependency> 3 <groupId>tk.mybatis</groupId> 4 <artifactId>mapper-spring-boot-starter</artifactId> 5 <version>1.1.0</version> 6 </dependency> 7 <!--pagehelper分页助手 --> 8 <dependency> 9 <groupId>com.github.pagehelper</groupId> 10 <artifactId>pagehelper-spring-boot-starter</artifactId> 11 <version>1.2.10</version> 12 </dependency> 13 <!--阿里巴巴数据源 --> 14 <dependency> 15 <groupId>com.alibaba</groupId> 16 <artifactId>druid</artifactId> 17 <version>1.0.25</version> 18 </dependency>
这里面需要注意的是分页助手,这个之前用的是1.1.0,但是和最新的2.1.7的springboot整合的时候回报错,重现了一下错误信息:
1 org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration‘: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration] from ClassLoader [[email protected]] 2 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:570) 3 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) 4 at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) 5 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 6 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) 7 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) 8 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845) 9 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) 10 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) 11 at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) 12 at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:743) 13 at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:390) 14 at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) 15 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1214) 16 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1203) 17 at com.example.demo.web.DemoWebApplication.main(DemoWebApplication.java:18) 18 Caused by: java.lang.IllegalStateException: Failed to introspect Class [com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration] from ClassLoader [[email protected]] 19 at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:760) 20 at org.springframework.util.ReflectionUtils.doWithLocalFields(ReflectionUtils.java:692) 21 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.buildResourceMetadata(CommonAnnotationBeanPostProcessor.java:365) 22 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:350) 23 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:298) 24 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1077) 25 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:567) 26 ... 15 common frames omitted 27 Caused by: java.lang.NoClassDefFoundError: Lorg/springframework/boot/bind/RelaxedPropertyResolver; 28 at java.lang.Class.getDeclaredFields0(Native Method) 29 at java.lang.Class.privateGetDeclaredFields(Class.java:2583) 30 at java.lang.Class.getDeclaredFields(Class.java:1916) 31 at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:755) 32 ... 21 common frames omitted 33 Caused by: java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedPropertyResolver 34 at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 35 at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 36 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) 37 at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 38 ... 25 common frames omitted
看这个错误信息好像是和AppClassLoader有关的,类加载器加载不到所需要的RelaxedPropertyResolver类,具体内部是怎么解决这个问题的,也不知道,通过网上求救是换jar的版本换成1.2.10的版本就OK了
2、application.properties文件中的配置中的问题
这里的问题主要是通用mapper的问题:先看一下正确的配置
1 # 通用mapper配置 2 mapper.mappers=com.example.demo.dao.BaseMapper 3 mapper.not-empty=false 4 mapper.identity=MYSQL
这里面有一个配置需要注意:mapper.mappers 这个配置,这个配置是需要配置你写的那个基础的mapper类的全路径的BaseMapper的代码:
1 /** 2 * @program: demo 3 * @description: 基础的mapper 4 * @author: ssc 5 * @create: 2019/8/20 10:21 6 **/ 7 public interface BaseMapper<T> extends Mapper<T>,MySqlMapper<T>{ 8 9 }
这个如果没有配置正确的话,启动的时候也会报错的,具体的报错信息:
1 Description: 2 Failed to bind properties under ‘mapper.mappers‘ to java.util.List<java.lang.Class<?>>: 3 Reason: No converter found capable of converting from type [java.lang.String] to type [java.util.List<java.lang.Class<?>>]
补充一下:这里还有一个问题,就是BaseMapper能和业务中的mapper类放到一个包中的问题,这个还没有验证,反正现在是不放到一个包中是没有问题的
TODO:这个明天验证一下
2019年8月21日09:46:30 今天来验证一下这个,这个好像是不行的,因为在启动类中加入了@MapperScan("com.example.demo.dao.mapper")注解,不能让启动类扫描到这个BaseMapper不能放到和@MapperScan注解的同一个包下面,不然会报错,创建失败
1 org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘com.github.pagehelper.autoconfigure.MapperAutoConfiguration‘: Invocation of init method failed; nested exception is java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class 2 at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:139) 3 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:414) 4 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1770) 5 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) 6 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) 7 at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) 8 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 9 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) 10 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) 11 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845) 12 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) 13 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) 14 at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) 15 at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:743) 16 at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:390) 17 at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) 18 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1214) 19 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1203) 20 at com.example.demo.web.DemoWebApplication.main(DemoWebApplication.java:18) 21 Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class 22 at tk.mybatis.mapper.mapperhelper.MapperHelper.setSqlSource(MapperHelper.java:247) 23 at tk.mybatis.mapper.mapperhelper.MapperHelper.processConfiguration(MapperHelper.java:310) 24 at tk.mybatis.mapper.mapperhelper.MapperHelper.processConfiguration(MapperHelper.java:289) 25 at com.github.pagehelper.autoconfigure.MapperAutoConfiguration.addPageInterceptor(MapperAutoConfiguration.java:69) 26 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 27 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 28 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 29 at java.lang.reflect.Method.invoke(Method.java:498) 30 at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363) 31 at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307) 32 at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136) 33 ... 18 common frames omitted 34 Caused by: java.lang.RuntimeException: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class 35 at tk.mybatis.mapper.mapperhelper.MapperTemplate.setSqlSource(MapperTemplate.java:246) 36 at tk.mybatis.mapper.mapperhelper.MapperHelper.setSqlSource(MapperHelper.java:244) 37 ... 28 common frames omitted 38 Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class 39 at tk.mybatis.mapper.mapperhelper.MapperTemplate.getEntityClass(MapperTemplate.java:278) 40 at tk.mybatis.mapper.provider.base.BaseSelectProvider.selectCount(BaseSelectProvider.java:111) 41 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 42 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 43 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 44 at java.lang.reflect.Method.invoke(Method.java:498) 45 at tk.mybatis.mapper.mapperhelper.MapperTemplate.setSqlSource(MapperTemplate.java:234) 46 ... 29 common frames omitted
3、实体类与数据库表对应的问题
这个就是一些字段与实体类的属性,以及表名称与类名称的对应的问题了,这个也是很恶心的,还是不是很熟悉,所以总是报错,在创建实体类的时候,最好在类名上加上@Table(name="表名称")以及在属性上加上@Column(name="字段名称")这样的注解,以防范出现对应错误
4、BaseService封装的问题
先看一下错误信息:
1 org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘bookController‘: Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘bookService‘: Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘tk.mybatis.mapper.common.Mapper<?>‘ available: expected single matching bean but found 2: bookInfoMapper,bookMapper 2 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:324) 3 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) 4 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) 5 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) 6 at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) 7 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 8 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) 9 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) 10 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845) 11 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) 12 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) 13 at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) 14 at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:743) 15 at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:390) 16 at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) 17 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1214) 18 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1203) 19 at com.example.demo.web.DemoWebApplication.main(DemoWebApplication.java:18) 20 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘bookService‘: Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘tk.mybatis.mapper.common.Mapper<?>‘ available: expected single matching bean but found 2: bookInfoMapper,bookMapper 21 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:324) 22 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) 23 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) 24 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) 25 at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) 26 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 27 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) 28 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) 29 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeanByName(AbstractAutowireCapableBeanFactory.java:452) 30 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:526) 31 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496) 32 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:636) 33 at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:180) 34 at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) 35 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:321) 36 ... 17 common frames omitted 37 Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘tk.mybatis.mapper.common.Mapper<?>‘ available: expected single matching bean but found 2: bookInfoMapper,bookMapper 38 at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:221) 39 at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1229) 40 at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1171) 41 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:520) 42 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496) 43 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:636) 44 at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:180) 45 at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) 46 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:321) 47 ... 31 common frames omitted
这个错误的根本原因是在封装的通用的service中,因为也就是BaseService这个类,开始写的是使用的
@Autowired
private Mapper<T> mapper;
为啥这样写就会出现那个错误呢 ?分析一下可以知道,当一个新创建的service层的类继承BaseService的时候,BaseService需要自动注入Mapper类,但是这时候Mapper发现spring容器中有多个类实现了Mapper,到底是用哪一个实现类呢,他自己搞不清楚,于是就抛出异常了,找到了多个实现类,现在记不清之前如何解决这个问题的,但是可以退一步,不要在BaseService中自动注入Mapper类我就明确告诉你,你需要实现那个Mapper类型的class。
具体的解决方法是:
我创建一个抽象的方法,子类继承我的时候需要给我一个具体的实现类
public abstract Mapper<T> getMapper();
例如:子类BookService 直接把你实现的BookMapper给了父类就行了,这样就不会有那个,不知道实现哪个子类的情况了:
1 @Service 2 public class BookService extends BaseService<BookInfo>{ 3 4 private Logger logger = LoggerFactory.getLogger(BookService.class); 5 6 @Autowired 7 private BookMapper bookMapper; 8 9 @Override 10 public Mapper<BookInfo> getMapper() { 11 return bookMapper; 12 } 13 }
原文地址:https://www.cnblogs.com/ssh-html/p/11407034.html