MyBatis入门之各种坑(MAVEN,IDEA)
1.首先配置pom.xml
。在pom
添加mybatis
的jar
包以及相关依赖。这也没啥。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.7</version>
<scope>compile</scope>
</dependency>
2.然后创建数据库,创建表,插入一些数据。
-- 创建数据库
CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 创建表
USE mybatis;
CREATE TABLE country (
id int NOT NULL AUTO_INCREMENT,
countryname VARCHAR(255) NULL,
countrycode VARCHAR(255) NULL,
PRIMARY KEY(id)
);
-- 插入数据
INSERT INTO country(countryname, countrycode) VALUES ('中国', 'CN'),('美国', 'US'),('俄罗斯','RU'),('英国', 'GB'),('法国','FR');
3.Country
实体类
package com.chromer.pojo;
/**
* @program: MyBatis
* @Date: 2019.4.1 20:48 下午
* @Author: chromeRo
* @Description:
*/
public class Country {
private Long id;
private String countryname;
private String countrycode;
...
省略getter(),setter(),toString()
}
4.然后配置实体类Country
的映射文件CountryMapper.xml
,这个配置文件要在mybatis-config.xml
配一下。如果是在类路径下,就不用写包名
,其他位置都要写(全路径)。namespace
:是唯一的。但是可以随意起名。使用的时候要加上namespace
。这里resultType
就不再写包名
。
<?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="com.chromer.mapper.CountryMapper">
<select id="selectCountry" resultType="Country">
SELECT * FROM Country WHERE id = #{id}
</select>
<select id="selectAll" resultType="Country">
SELECT * FROM country
</select>
</mapper>
5.然后配置mybatis
的主配置文件mybatis-config.xml
,这个名字随便起。一般放在resources
目录下。通过这个配置文件完成与数据库的连接。
参数说明:settings
:配置mybatis
的log
实现为log4j
,这样在控制台可以清晰的看到你想看到的运行结果。当然亦可以不配置。typeAliases
:配置类的别名,根据包取别名,把包下面的类按类名来取别名。比如resultType
可以设置为Country
。transactionManager
:配置事务管理,使用JDBC
事务管理。dataSource
:POOLED
是mybatis
数据源,JNDI
是基于tomcat
数据源。mapper
:配置实体类
的映射文件,resource
要写成/
的形式,如果是在类路径(resources)
下,可以直接写文件名,其他位置要写全路径名,我这里是在(java)
目录下配置的,所以写成全路径名。
<?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>
<!--默认使用LOG4J输出日志-->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!--配置包的别名,在使用类的时候不需要写包名的部分,只是用Country即可-->
<typeAliases>
<package name="com.chromer.pojo" />
</typeAliases>
<!--配置数据库连接-->
<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:///mybatis" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!--配置映射文件-->
<mappers>
<mapper resource="com/chromer/mapper/CountryMapper.xml" />
</mappers>
</configuration>
6.然后配置log4j.properties
#全局配置
log4j.rootLogger=ERROR, console
#MyBatis日志配置
log4j.logger.com.chromer.mapper=TRACE
#控制台输出配置
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%5p [%t] - %m%n
7.然后写测试类CountryMapperTest.java
package com.chromer.test;
import com.chromer.pojo.Country;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @program: MyBatis
* @Date: 2019.4.2 10:41 上午
* @Author: chromeRo
* @Description:
*/
public class CountryMapperTest {
private static SqlSessionFactory sessionFactory;
@Test
public void testSelectOne() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
sessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = sessionFactory.openSession();
Country country = session.selectOne("com.chromer.mapper.CountryMapper.selectCountry", 1);
System.out.println(country);
session.close();
in.close();
}
@Test
public void testSelectAll(){
try {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
sessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = sessionFactory.openSession();
List<Country> countryList = session.selectList("com.chromer.mapper.CountryMapper.selectAll");
for (Country c : countryList) {
System.out.printf("%-4d%4s%6s\n", c.getId(), c.getCountryname(), c.getCountrycode());
}
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
8.运行结果
哎呦卧槽。它告诉我它找不到com/chromer/mapper/CountryMapper.xml
,后来我度了一通,发现IDEA不会加载java
目录下的xml
文件(因为这个文件我是在java
目录下写的),然后需要在pom
的build
里添加下面这一段:
然后测试一下testSelectOne()
,结果如下图所示:
卧槽,我的日志呢?然后找了半天(几个小时),发现log4j.logger
下的包名要和CountryMapper.xml
的namespace
的包名一致。也就是说namespace
怎么写log4j.logger
下的包名就怎么写。虽然说namespace
是随便起的,但是也要有一定的规范,因为它是唯一的,所以一般用CountryMapper
的全路径名作为它的namespace
(反正我是这么起的)。
然后再运行一下:
然后接着测试testSelectAll
,结果如下:
卧槽,打印Empty test suite.
,然后我又弄了半天,把方法名改一下试试:
@Test
public void testSelectCountry(){
try {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
sessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = sessionFactory.openSession();
List<Country> countryList = session.selectList("com.chromer.pojo.CountryMapper.selectAll");
for (Country c : countryList) {
System.out.printf("%-4d%4s%6s\n", c.getId(), c.getCountryname(), c.getCountrycode());
}
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
结果:
可以了。