豆角茄子子

导航

搭建一个简单的Mybatis框架

直接进入正题,如何搭建一个纯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&amp;characterEncoding=utf-8&amp;serverTimezone=GMT" />

3、查询到的某些属性为null,如下:

1
马二
null

去数据库直接查看id为1的person,地址不为null才对。这种情况有可能是mapper接口文件里select标签的resultType属性直接写了实体类的路径,而此实体类的address属性名与表person的列名不对应。例如,列名为addr,而属性名为address。其实熟悉Mybatis,可以使用resultMap来手动映射列与属性名之间的关系,以及级联等等,这里不多赘述。

posted on 2019-01-21 23:13  豆角茄子子  阅读(1066)  评论(0编辑  收藏  举报