一个好的架构,其实要做的事情是非常简单的,除了深入理解一些架构的原理和组成要素之外,此外就是选择一个合适的技术来解决特定的问题。
下面我们将使用Maven项目配置MyBatis连接mySQL。
项目源码下载地址:https://github.com/JFAlex/MyBatis/tree/master/MyBatis_No.2/alex
MyBatis参考文档:
中文版:http://www.mybatis.org/mybatis-3/zh/index.html
英文版:http://www.mybatis.org/mybatis-3/
工具
JDK 1.6及以上版本
MyBatis 3.30版本
MySQL 6.3版本
Eclipse4 及以上版本
Apache Maven 构建工具
项目源码下载地址:https://github.com/JFAlex/MyBatis/tree/master/MyBatis_No.2/alex
创建Maven项目
首先在Eclipse中创建一个基本的Maven项目,按照如下步骤进行操作即可
1、在Eclipse中打开【File】-->【New】选择【other】(或者使用快捷键 Ctrl + N)打开新建项目向导
2、选择【Maven】下的【Maven Project】,点击【Next】
3、选中【Create a simple project (skip archetype selection)】的复选框,点击【Next】
4、输入Group Id,Artifact Id,其他按照默认填写,然后点击【Finish】
完成以上操作之后,等待片刻,就可以得到一个基于Maven的基本结构了,得到的Maven项目的目录结构如下所示:
5、打开Maven项目的配置文件pom.xml,添加mybatis和mysql的依赖
<!-- mybatis依赖包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<!-- mysql数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
我们可以通过以下链接查找我们需要的Mavne依赖包
https://mvnrepository.com/
http://maven.outofmemory.cn/search/?q=
http://search.maven.org/
我们还需要添加Log4j、JUnit的驱动依赖。最后我们得到的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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>mybatis</groupId>
<artifactId>alex</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 设置源代码编码格式为UTF-8 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<!-- 单元测试 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- 表示开发的时候引入,发布的时候不会加载此包 -->
<scope>test</scope>
</dependency>
<!-- mybatis依赖包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<!-- mysql数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<!-- 日志依赖包 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<!-- 设置编译源代码JDK的版本 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
当对Maven的配置进行修改后,我们还需要在项目上单击鼠标右键,在【Maven】中选择【Update Project ...】(或者直接在项目中,使用Alt + F 快捷键)来更新外部依赖包。
让MyBatis跑起来
1、准备数据库
首先创建一个数据库,编码方式设置为UTF-8,通过执行下面的SQL语句创建一个名为mybatis的数据库。
CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
然后再创建一个名为country的表,并插入一些数据。
use mybatis;
CREATE TABLE Country(
id int(15) NOT NULL AUTO_INCREMENT,
countryname varchar(255) NOT NULL,
countrycode varchar(255) NOT NULL,
PRIMARY KEY(id)
);
insert INTO country(countryname,countrycode)values('中国','CN'),('美国','US'),('英国','GB'),('法国','FR');
2、配置MyBatis
配置MyBatis有多种方式,在此我们首先使用的最基础的XML形式进行配置。使用XML形式进行配置,首先在src/main/resources下面创建mybatis-config.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>
<!-- 配置指定使用LOG4J输出日志 -->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 配置包的别名,这样我们在mapper中定义时,就不需要使用类的全限定名称,只需要使用类名即可 -->
<typeAliases>
<package name="mybatis.simple.model"/>
</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://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- mybatis的SQL语句和映射配置文件 -->
<mappers>
<mapper resource="mybatis/simple/mapper/CountryMapper.xml"/>
</mappers>
</configuration>
配置说明:
<settings>中的logImpl属性配置指定使用LOG4J输出日志。
<typeAliases>元素下面配置了一个包的别名。通常确定一个类的时候需要使用类的全限定名称,例如mybatis.simple.model.Country,在MyBatis中需要频繁的使用类的权限定名称,为了方便使用,我们配置了mybatis.simple.model包,这样配置以后,我们再使用该包下的类的时候就不用再写上包名了,直接使用类名接口,如 Country 。
<environments>环境配置中主要配置了数据库连接。
dataSource的类型可以配置成其内置类型之一,如UNPOOLED、POOLED、JNDI.
- 如果将类型设置为UNPOOLED,MyBatis会为每一个数据库操作创建一个新的连接,并关闭它。该方式适用于只有小规模数据并发用户的简单应用程序上。
- 如果将属性设置为POOLED,MyBatis会创建一个数据库连接池,连接池中的一个连接将会被用作数据库操作。一旦数据库操作完成,MyBatis会将此连接返回给连接池。在开发测试环境中,经常使用该种方式。
- 如果将类型设置为JNDI,MyBatis从在应用服务器向配置好的JNDI数据源dataSource获取连接。在生产环境中优先考虑这种方式。
<mapper>中配置了一个包含完整路径的mapper.xml(CountryMapper.xml)文件,这是一个MyBatis的SQL语句和映射配置文件。
3、创建实体类和Mapper.xml文件
MyBatis是一个结果映射框架,这里创建的实体类实际上是一个数据值对象(Data Value Object),在实际应用中一般会对应一个实体,用于INSERT、UPDATE、DELETE、SELECT操作。
关于Mapper的命名方式:在MyBatis中,根据MyBatis官方的习惯,一般用Mapper作为XML和接口类名的后缀。(CountryMapper.xml)
在src/main/java下面创建一个基础的包mybatis.simple.model,根据数据库表country表,创建实体类Country
package mybatis.simple.model;
public class Country {
private Long id;
private String countryname;
private String countrycode;
public Country() {
super();
}
public Country(Long id, String countryname, String countrycode) {
super();
this.id = id;
this.countryname = countryname;
this.countrycode = countrycode;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCountryname() {
return countryname;
}
public void setCountryname(String countryname) {
this.countryname = countryname;
}
public String getCountrycode() {
return countrycode;
}
public void setCountrycode(String countrycode) {
this.countrycode = countrycode;
}
@Override
public String toString() {
return "Country [id=" + id + ", countryname=" + countryname + ", countrycode=" + countrycode + "]";
}
}
然后在src/main/resource(也可以是src/main/java)下创建mybatis/simple/mapper目录,再在该目录下创建CountryMapper.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="mybatis.simple.mapper.CountryMapper">
<select id="selectAll" resultType="Country">
select * from country
</select>
</mapper>
SQL定义在CountryMapper.xml文件中,里面的配置如下:
<mapper>:XML的根元素,属性namespace定义了当前XML的命名空间
<select>:我们所定义的select查询。还有<update>、<insert>、<delete>等标签
id属性:定义当前语句的唯一id,调用SQL语句时,通过id区别
resultType:定义当前SQL语句的返回值类型。此处就是指实体类Country,前面配置中提到的别名主要用于这里,如果没有配置,此处就需要写成 resultType="mybatis.simple.model.Country"
4、配置Log4j
配置Log4j,以便查看MyBatis操作数据库的过程
在src/main/resources中添加log4j.properties配置文件
#全局配置
log4j.rootLogger=DEBUG, stdout
#mybatis日志配置
log4j.logger.mybatis.simple.mapper=TRACE
#控制台输出配置
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
如果用过Log4j日志组件的人应该知道,配置中log4j.logger.mybatis.simple.mapper对应的是mybatis.simple.mapper包,但是在此实例中,Java目录下并没有这个包名,只在资源目录下有mapper目录。
MyBatis的日志实现中,所谓的包名实际上就是XML配置中的namespace属性值的一部分。(后面介绍接口相关部分时,由于namespace属性值必须和接口的权限定类名相同,因此才会真正对应到java包。当使用纯注解方式时,使用的就是纯粹的包名。)
MyBatis日志的最低级别是TRACE,在这个日志级别下,MyBatis会输出执行SQL过程中的详细信息。
5、编写测试代码
首先在src/test/java中创建mybatis/simple/test包,然后创建CountryMapperTest测试类
package mybatis.simple.test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
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.BeforeClass;
import org.junit.Test;
import mybatis.simple.model.Country;
public class CountryMapperTest {
private static SqlSessionFactory sessionFactory;
@BeforeClass
public static void init(){
try{
//通过配置文件获取连接数据库连接信息
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//通过配置信息来构建一个SqlSessionFactory
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
}catch(IOException e){
e.printStackTrace();
}
}
@Test
public void test(){
//通过SqlSessionFactory打开一个会话
SqlSession openSession = sessionFactory.openSession();
try{
List<Country> countryList = openSession.selectList("selectAll");
printCountryList(countryList);
}finally{
//关闭session会话
openSession.close();
}
}
private void printCountryList(List<Country> countryList){
for(Country country : countryList){
System.out.println(country.getId()+"--"+country.getCountryname()+"--"+country.getCountrycode());
}
}
}
说明:
通过Resources工具类将mybatis-config.xml配置文件读入Reader。
再通过SqlSessionFactoryBuilder建造类使用Reader创建SqlSessionFactory工厂对象。在创建SqlSessionFactory对象的过程中,首先解析mybatis-config.xml配置文件,读取配置文件中mappers配置后会读取全部的Mapper.xml进行具体方法的解析,在这些解析完成后,SqlSessionFactory就会包含了所有的属性配置和执行SQL的信息
使用时通过SqlSessionFactory工厂对象获取一个SqlSession。
通过SqlSession的selectList方法查询到CountryMapper.xml中id="selectAll"的方法,执行SQL查询。
MyBatis底层使用JDBC执行SQL,获取查询结果集ResultSet后,根据resultType的配置将结果集映射为Country类型的集合,返回查询结果,这样就得到了最后的countryList,并将结果输出到控制台
最后一定不要忘记关闭SqlSession,否则会因为连接没有关闭导致数据库连接数过多,而造成系统崩溃。
6、进入CountryMapperTest测试类,右键选择【Run as】--> 【1 JUnit Test】
我们将会在控制台看到如下输出结果
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 399931359.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@17d677df]
DEBUG [main] - ==> Preparing: select * from country
DEBUG [main] - ==> Parameters:
TRACE [main] - <== Columns: id, countryname, countrycode
TRACE [main] - <== Row: 1, 中国, CN
TRACE [main] - <== Row: 2, 美国, US
TRACE [main] - <== Row: 3, 英国, GB
TRACE [main] - <== Row: 4, 法国, FR
DEBUG [main] - <== Total: 4
1--中国--CN
2--美国--US
3--英国--GB
4--法国--FR
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@17d677df]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@17d677df]
DEBUG [main] - Returned connection 399931359 to pool.
从日志中我们可以看到完整的SQL输出和结果输出,从日志对应的级别可以发现SQL、参数、结果数都是DEBUG级别,具体的查询结果列和数据都是TRACE级别。
项目源码下载地址:https://github.com/JFAlex/MyBatis/tree/master/MyBatis_No.2/alex
最终目录结构:
网友评论