直接進入正題,如何搭建一個純Mybatis框架?過程中間可能會遇到各種各樣的問題,簡單整理在此。
准備工作
搭建Mybatis,需要的兩個核心jar包,一個是任意Mybatis版本的包,另一個是數據庫驅動包。這里的環境如下:
- mybatis-3.4.6.jar
- mysql-connector-java-8.0.13.jar
二者的pom依賴可去https://mvnrepository.com/查找,然后創建一個簡單的java項目,這里以Maven項目為例。
相關配置
1、pom.xml文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.szh.Mybatis_test</groupId>
<artifactId>Mybatis_test</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.basedir>com.szh</project.basedir>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
</dependencies>
<build>
<finalName>Mybatis_test</finalName>
</build>
</project>
2、 Mybatis核心配置文件conf.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<!-- 配置數據庫連接信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydata" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- 注冊personMapper.xml文件,注意使用正斜杠分隔 -->
<mapper resource="com/szh/mapper/personMapper.xml"/>
<!-- 類引入方式 -->
<!-- <mapper class="com.szh.mapper.IPersonMapper"/> -->
</mappers>
</configuration>
當然,dataSource的四個屬性也可以寫在一個單獨的配置文件里,然后在conf.xml中使用<properties resource="local_pro.properties"></properties>引用即可。
conf.xml是Mybatis的核心配置文件,放在下面一級目錄:
3、Mybatis接口映射文件personMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 為這個mapper指定一個唯一的namespace,namespace的值習慣上設置成包名+sql映射文件名,這樣就能夠保證namespace的值是唯一的
例如namespace="com.szh.mapper.personMapper"就是com.szh.mapper(包名)+personMapper(personMapper.xml文件去除后綴) -->
<mapper namespace="com.szh.mapper.personMapper">
<!-- 在select標簽中編寫查詢的SQL語句, 設置select標簽的id屬性為getPerson,id屬性值必須是唯一的,不能夠重復 使用parameterType屬性指明查詢時使用的參數類型,resultType屬性指明查詢返回的結果集類型
resultType="com.szh.po.PersonPo"就表示將查詢結果封裝成一個PersonPo類的對象返回 PersonPo類就是person表所對應的實體類 -->
<!-- 根據id查詢得到一個person對象 -->
<select id="getPerson" parameterType="int" resultType="com.szh.po.PersonPo">
select * from person where id=#{id}
</select>
</mapper>
personMapper.xml文件是Mybatis每個實體類對應的接口映射文件,一般統一放在如下目錄:
4、測試主類Test.java
package com.szh;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.szh.po.PersonPo;
public class Test {
public static void main(String[] args) {
//mybatis的配置文件
String resource = "conf.xml";
//使用類加載器加載mybatis的配置文件(它也加載關聯的映射文件)
InputStream is = Test.class.getClassLoader().getResourceAsStream(resource);
System.out.println(Test.class.getClassLoader().getResource(resource).getFile());
//構建sqlSession的工廠
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
//使用MyBatis提供的Resources類加載mybatis的配置文件(它也加載關聯的映射文件)
//Reader reader = Resources.getResourceAsReader(resource);
//構建sqlSession的工廠
//SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//創建能執行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession();
/**
* 映射sql的標識字符串,
* me.gacl.mapping.userMapper是userMapper.xml文件中mapper標簽的namespace屬性的值,
* getUser是select標簽的id屬性值,通過select標簽的id屬性值就可以找到要執行的SQL
*/
//在命名空間“com.szh.mapper.personMapper”中定義了一個名為“getPerson”的映射語句,
//這樣它就允許你使用指定的完全限定名“com.szh.mapper.personMapper.getPerson”來調用映射語句,
//格式:命名空間名(namespace)+映射語句名(id)
String statement = "com.szh.mapper.personMapper.getPerson";//映射sql的標識字符串
//執行查詢返回一個唯一user對象的sql
PersonPo p = session.selectOne(statement, 1);
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAddress());
}
}
以上就是主要配置步驟,接下來run一下工程,看看結果,看看可能出現什么樣的問題。
疑難雜症
1、personMapper.xml文件找不到,具體日志如下:
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:
### Error building SqlSession.
### The error may exist in com.szh.mapper.personMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com.szh.mapper.personMapper.xml
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64)
at com.szh.Test.main(Test.java:20)
com.szh.mapper.personMapper.xml文件明明存在,目錄也正確,卻報這個異常,這時我們需要確認conf.xml中是否正確定義了每一個mapper,注意mapper接口文件路徑要以正斜杠分隔開,正確的寫法如下:
<mappers>
<!-- 注冊personMapper.xml文件,注意使用正斜杠分隔 -->
<mapper resource="com/szh/mapper/personMapper.xml"/>
</mappers>
2、數據庫時區問題,具體日志如下:
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
### The error may exist in com/szh/mapper/personMapper.xml
### The error may involve com.szh.mapper.personMapper.getPerson
### The error occurred while executing a query
### Cause: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77)
at com.szh.Test.main(Test.java:38)
那么,我們需要給數據庫連接url添加以下參數:
<property name="url" value="jdbc:mysql://localhost:3306/mydata?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT" />
3、查詢到的某些屬性為null,如下:
1
馬二
null
去數據庫直接查看id為1的person,地址不為null才對。這種情況有可能是mapper接口文件里select標簽的resultType屬性直接寫了實體類的路徑,而此實體類的address屬性名與表person的列名不對應。例如,列名為addr,而屬性名為address。其實熟悉Mybatis,可以使用resultMap來手動映射列與屬性名之間的關系,以及級聯等等,這里不多贅述。