java

Springboot +Mybatis整合常见错误 报错:Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required

记录一下在使用Spring Boot 时,由于对框架不熟悉,在项目启动的过程中遇到的问题


问题描述:

问题一:dao层注入问题

Field xxMapper in xx.service.impl.xxServiceImpl required a bean of type 'xx.mapper.xxMapper

以前是通过xml文件配置的,但spring boot不用配置xml文件。
解决方法:
1:可以在每个dao加上@Mapper或者@Repository注解
2:统一在启动类配置@MapperScan

复制代码
1 @SpringBootApplication
2 @MapperScan("com.example.demo.base.mapper")
3 @ComponentScan(basePackages = {"com.example.demo"})
4 public class DemoApplication {
5     public static void main(String[] args) {
6         SpringApplication.run(DemoApplication.class, args);
7     }
8 }
复制代码

问题二:配置好之后,启动项目又出现数据源配置问题

Failed to configure a DataSource: ‘url’ attribute is not specified and no embedded datasource could be configured

项目中加了Mybatis依赖jar包,SpringBoot数据源自动配置需要我们配置主类中加入@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})自动注入

复制代码
1 @SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
2 @MapperScan("com.example.demo.base.mapper")
3 @ComponentScan(basePackages = {"com.example.demo"})
4 public class DemoApplication {
5     public static void main(String[] args) {
6         SpringApplication.run(DemoApplication.class, args);
7     }
8 }
复制代码

接下来又报错。。。

Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

原因是mybatis-spring-1.3.2中取消了自动注入SqlSessionFactory 和 SqlSessionTemplate,也就是mybatis依赖版本的问题。

方案一:
mybatis版本太高(1.3.2),于是降级到1.1.1解决问题。
(换这个太麻烦,没有实践,但听说还是有用。。)

方案二:
创建一个Dao的基类CommonDao,让这个基类继承SqlSessionDaoSupport,并通过set方法注入SqlSessionFactory属性即可:

复制代码
1 public class CommonDao extends SqlSessionDaoSupport {
2     @Resource
3     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory){
4         super.setSqlSessionFactory(sqlSessionFactory);
5     }
6 }
复制代码

然后让Dao实现类再继承这个CommonDao基类即可。(但我dao用的是接口,不适用)

方案三:
后面将(exclude={DataSourceAutoConfiguration.class})去掉,将application.properties中配置放到新建的application.yml中

application.yml

复制代码
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/demo_db?serverTimezone=GMT%2B8
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
复制代码

项目启动成功

方案四:
上面说SqlSessionFactory 和 SqlSessionTemplate没有自动注入,那我们可以自己手动注入

复制代码
 1 @Value("${mybatis-plus.mapper-locations}")
 2     private String mapperLocations;
 3     //配置FactoryBean
 4     @Bean(name = "sqlSessionFactoryBean")
 5     public SqlSessionFactoryBean sqlSessionFactoryBean() {
 6         SqlSessionFactoryBean sqlSessionFactoryBean = null;
 7         try {
 8             // 加载JNDI配置
 9             Context context = new InitialContext();
10             // 实例SessionFactory
11             sqlSessionFactoryBean = new SqlSessionFactoryBean();
12             // 配置数据源
13             sqlSessionFactoryBean.setDataSource(dataSource());
14             // 加载MyBatis配置文件
15             PathMatchingResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
16             // 能加载多个,所以可以配置通配符(如:classpath*:mapper/**/*.xml)
17             sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources(mapperLocations));
18         } catch (Exception e) {
19             System.out.println("创建SqlSession连接工厂错误:{}");
20         }
21         return sqlSessionFactoryBean;
22     }
23     @Bean
24     public SqlSessionTemplate sqlSessionTemplate() throws Exception {
25         SqlSessionTemplate sqlSessionTemplate=new SqlSessionTemplate(sqlSessionFactoryBean().getObject(),ExecutorType.BATCH);
26         return sqlSessionTemplate;
27     }

java8报错”Could not create the Java Virtual Machine”解决方案

 

本次实验环境:winjava@8。本篇内容主要讲这个大乌龙,而不是ide安装。

报错截图

主要的报错信息就是:

Could not create the Java Virtual Machine
Plain text

 

苏南大叔:java8报错"Could not create the Java Virtual Machine"解决方案 - java000

java8报错”Could not create the Java Virtual Machine”解决方案(图5-2)

 

乌龙的起源

这个乌龙,按理说还要归责于java身上。因为java版本升级到现在,用了一个和别人不一样的参数调用方式,而且居然不提示命令错误。而是提示如图这个错误消息。 “Could not create the Java Virtual Machine”。

其他可以在命令行里面运行的软件,包括java的早期版本。都是使用 --version 来查看软件版本的,而不是 -version。 而目前的最流行的java8系列,版本号查看方式却是 -version 。注意查看中划线的数量。这就是大乌龙的根本原因所在。

java -version
Plain text
java --version
Plain text

无论是win环境还是mac环境,都存在着这个问题。问题会导致,大家认为java根本没有安装好。

win:

 

苏南大叔:java8报错"Could not create the Java Virtual Machine"解决方案 - java001

java8报错”Could not create the Java Virtual Machine”解决方案(图5-3)

 

mac:

 

苏南大叔:java8报错"Could not create the Java Virtual Machine"解决方案 - java002

java8报错”Could not create the Java Virtual Machine”解决方案(图5-4)

 

然而转折

但是最新java9系列,又再次支持了--version命令。真心是没谁了。

 

苏南大叔:java8报错"Could not create the Java Virtual Machine"解决方案 - 030_java_version

java8报错”Could not create the Java Virtual Machine”解决方案(图5-5)

 

结论

学艺不精,主观臆断。也是苏南大叔的这次大乌龙的原因之一了。大家可千万别再犯苏南大叔这样的错误哦。java8系列是不支持--version的,但是java9却支持--version。所以,在未来的日子里面,大家还是可以以相同的习惯,继续使用--version的。

 

Java双端队列Deque使用详解

Deque是一个双端队列接口,继承自Queue接口,Deque的实现类是LinkedList、ArrayDeque、LinkedBlockingDeque,其中LinkedList是最常用的。

关于Queue的介绍可以看上一篇文章:Java队列Queue使用详解

Deque有三种用途:

普通队列(一端进另一端出):
Queue queue = new LinkedList()或Deque deque = new LinkedList()
双端队列(两端都可进出)
Deque deque = new LinkedList()
堆栈
Deque deque = new LinkedList()

注意:Java堆栈Stack类已经过时,Java官方推荐使用Deque替代Stack使用。Deque堆栈操作方法:push()、pop()、peek()。

Deque是一个线性collection,支持在两端插入和移除元素。名称 deque 是“double ended queue(双端队列)”的缩写,通常读为“deck”。大多数 Deque 实现对于它们能够包含的元素数没有固定限制,但此接口既支持有容量限制的双端队列,也支持没有固定大小限制的双端队列。

此接口定义在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。插入操作的后一种形式是专为使用有容量限制的 Deque 实现设计的;在大多数实现中,插入操作不能失败。

下表总结了上述 12 种方法:
第一个元素 (头部) 最后一个元素 (尾部)
抛出异常 特殊值 抛出异常 特殊值
插入 addFirst(e) offerFirst(e) addLast(e) offerLast(e)
删除 removeFirst() pollFirst() removeLast() pollLast()
检查 getFirst() peekFirst() getLast() peekLast()

Deque接口扩展(继承)了 Queue 接口。在将双端队列用作队列时,将得到 FIFO(先进先出)行为。将元素添加到双端队列的末尾,从双端队列的开头移除元素。从 Queue 接口继承的方法完全等效于 Deque 方法,如下表所示:
Queue方法 等效Deque方法
add add(e) addLast(e)
offer(e) offerLast(e)
remove() removeFirst()
poll() pollFirst()
element() getFirst()
peek() peekFirst()

双端队列也可用作 LIFO(后进先出)堆栈。应优先使用此接口而不是遗留 Stack 类。在将双端队列用作堆栈时,元素被推入双端队列的开头并从双端队列开头弹出。堆栈方法完全等效于 Deque 方法,如下表所示:
堆栈方法 等效Deque方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst()

类似-Xms、-Xmn这些参数的含义:

类似-Xms、-Xmn这些参数的含义:

答:
堆内存分配:
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64
JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。
因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。
非堆内存分配:
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
-Xmn2G:设置年轻代大小为2G。
-XX:SurvivorRatio,设置年轻代中Eden区与Survivor区的比值。