When using XML configuration to build the core class sqlsessionfactory of mybatis, we encountered the problem that the configuration file path is always written incorrectly. After the event, I didn’t look at the documents well, and I was always feeling the elephant for the blind.
The code to read the XML configuration file is as follows:
var inputSteam = Resources.getResourceAsStream("config/mybatis.xml");
var sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputSteam);
At first, I put the configuration file in thesrc/main/java/com/imxfly/config/mybatis.xml
Then the read path is written as:com/imxfly/config/mybatis.xml
But the hintjava.io.IOException: Could not find resource com/imxfly/config/mybatis.xml
。
So the key is how to fill in the configuration file path here. We know that the read path is not according to the directory structure at the time of current development, but is read after compilation in the target directory of the project with the classes directory as the classpath (that is, the root directory of the class).
Suppose we put the configuration file in thesrc/main/java/com/imxfly/config
Directory, then usemaven compile
After compiling, go to the target directory and you will find that you can’t find this configuration file. This is because Maven only reads it by default when compilingsrc/main/java
Under the directory.java
The file is then compiled into.class
File, so you can’t find our configuration file in the target directory. How can we solve this problem?
The recommended approach is to put these XML configuration files in thesrc/main/resources
Under the directory.
This behavior is clearly described in the official document (click to view)
Within artifact producing source directories (ie.
main
andtest
), there is one directory for the languagejava
(under which the normal package hierarchy exists), and one forresources
(the structure which is copied to the target classpath given the default resource definition).
For the resources directory, its directory structure will be completely copied directly to the target classpath. Suppose we have the following SRC directory structure:
.
├── main
│ ├── java
│ │ └── com
│ │ └── imxfly
│ │ └── App.java
│ └── resources
│ └── config
│ └── mybatis.xml
└── test
└── java
└── com
└── imxfly
└── AppTest.java
Then the target directory structure after compilation is as follows:
.
├── classes
├── com
│ └── imxfly
│ └── App.class
└── config
└── mybatis.xml
So the path to read the configuration file in the code is as follows:
var inputSteam = Resources.getResourceAsStream("config/mybatis.xml");
Because by default, Maven willsrc/main/resources
Find the resource file for the project.
But if our project structure is not easy to modify, the configuration file is in thesrc/main/java/com/imxfly/config/mybatis.xml
What to do?
At this point, we need to configure the file in Maven pom.xml To tell Maven where our resource files are:
<project>
...
<build>
...
<resources>
<resource>
<directory>src/main/java/com/imxfly/config</directory>
</resource>
<resource>
<directory>src/main/java/com/imxfly/config2</directory>
</resource>
<resource>
<directory>src/main/java/com/imxfly/config3</directory>
</resource>
</resources>
...
</build>
...
</project>
At compile time, Maven will completely copy the file structures in these directories to the target directory (just like copying the resources directory above), so our reading path is:
var inputSteam = Resources.getResourceAsStream("mybatis.xml");
reference material:
- https://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html
- https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html