MyBatis核心文件
1.MyBatis核心配置文件层级关系
注意在MyBatis核心配置的.xml文件中配置的顺序是按照上述的顺序配置
The content of element type “configuration” must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?);
1》environments标签
数据库环境的配置支持多环境配置
<environments default="development"> --指定默认的环境名称
<environment id="development"> --指定当前环境的名称
<transactionManager type="JDBC" /> --指定事务管理类型是JDBC
<dataSource type="POOLED"> --指定当前数据源类型是连接池
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/> --数据源的基本参数配置
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
environment标签
其中:事务管理器(transactionManager)类型有两种:
- jdbc:这个配置就是直接使用JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
- MANAGED:这个配置几乎没做什么,它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如:JEE应用服务器的上下文)。默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将closeConnection属性设置为false来阻止它默认的关闭行为。
其实,数据源(dataSource)类型有三种:
- UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接
- POOLED:这个数据源的实现利用 ”池“ 的概念将JDBC连接对象组织起来
- JNDI:这个数据源的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用
环境配置(environments)(官方api)
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。还有许多类似的使用场景。
不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推,记起来很简单:
- 每个数据库对应一个 SqlSessionFactory 实例
为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。可以接受环境配置的两个方法签名是:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
如果忽略了环境参数,那么将会加载默认环境,如下所示:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
environments 元素定义了如何配置环境。
<environments default="development"> --默认使用的环境
<environment id="development"> --当前使用的环境
<transactionManager type="JDBC"> --当前使用的事务管理器
<property name="..." value="..."/>
</transactionManager>
<dataSource type="POOLED"> --当前使用的数据源是连接池的方式
<property name="driver" value="${driver}"/> --基本数据源的相关配置
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
注意一些关键点:
- 默认使用的环境 ID(比如:default=“development”)。
- 每个 environment 元素定义的环境 ID(比如:id=“development”)。
- 事务管理器的配置(比如:type=“JDBC”)。
- 数据源的配置(比如:type=“POOLED”)。
默认环境和环境 ID 顾名思义。 环境可以随意命名,但务必保证默认的环境 ID 要匹配其中一个环境 ID。
事务管理器(transactionManager)
在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"):
-
JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
-
MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。例如:
<transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager>
提示 如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器,因为 Spring 模块会使用自带的管理器来覆盖前面的配置。
这两种事务管理器类型都不需要设置任何属性。它们其实是类型别名,换句话说,你可以用 TransactionFactory 接口实现类的全限定名或类型别名代替它们。
public interface TransactionFactory {
default void setProperties(Properties props) { // 从 3.5.2 开始,该方法为默认方法
// 空实现
}
Transaction newTransaction(Connection conn);
Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}
在事务管理器实例化后,所有在 XML 中配置的属性将会被传递给 setProperties() 方法。你的实现还需要创建一个 Transaction 接口的实现类,这个接口也很简单:
public interface Transaction {
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
Integer getTimeout() throws SQLException;
}
使用这两个接口,你可以完全自定义 MyBatis 对事务的处理。
2》Mappers标签:(是用于引入Mapper配置文件的)
既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:///
形式的 URL),或类名和包名等。例如:
该标签的作用是加载映射文件,加载方式如下几种:
1.使用相对于类路径的资源引用:例如:
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
2.使用完全限定资源定位符(URL):例如:
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
3.使用映射器接口实现类的完全限定类名:例如:
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
4.将包内的映射器接口实现全部注册为映射:例如:
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
3》Properties标签
实际开发中,习惯将数据源的配置信息单独抽取成一个Properties文件,该标签可以加载额外配置的properties文件
4》typeAliases标签
类型别名是为java类型一个短的名字。如:
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
MyBatis相应的API
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。
SqlSession工厂构建器SqlSessionFactorBuilder
常用API:SqlSessionFactory build(InputStream inputStream);
通过加载MyBatis核心文件的输入流的形式构建一个SqlSessionFactor对象
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
下面的API最重要:
MyBatis两个重要的API
提交事务
openSession() 没有传入任何参数,必须手动的提交事务
openSession(boolean autoCommit) 当传入true时,将不需要手动提交事务,否则需要
public SqlSession getSqlSession() throws IOException {
InputStream sqlMapConfig = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(sqlMapConfig);
SqlSession sqlSession = build.openSession(true);
return sqlSession;
}
查询单个实体(对象)
<T> T selectOne(String statement,Object parameter)
@Test
public void test3() throws IOException {
Person person = new Person();
person.setId(1);
SqlSession sqlSession = getSqlSession();
Person one = sqlSession.selectOne("userMapper.select", person);
System.out.println(one);
}
MyBatis入门代码区:
1.导入相关的坐标
<!-- 添加MyBatis依赖-->
mybatis
<!-- 添加mysql依赖-->
mysql-connector-java
<!-- 添加日记依赖-->
log4j
<!-- 添加测试依赖-->
junit
2.编写实体数据库
3.编写实体类(与数据库字段对应)
4.编写UserMapper.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="userMapper">
<select id="findAll" resultType="person">
select * from person
</select>
<!-- 添加数据-->
<insert id="insert" parameterType="person">
insert into person values(#{id},#{username},#{password});
</insert>
<!-- 修改数据-->
<update id="update" parameterType="person">
update person set username=#{username} where id=#{id}
</update>
<!-- 删除数据-->
<delete id="delete" parameterType="person">
delete from person where id=#{id}
</delete>
<!-- 删除数据-->
<delete id="delete2" parameterType="java.lang.Integer">
delete from person where id=#{id}
</delete>
<!-- 查询单个对象(实体)-->
<select id="select" resultType="person">
select * from person where id=#{id}
</select>
</mapper>
5.编写SqlMapConfig.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>
<properties resource="jdbc.properties"/>
<typeAliases>
<typeAlias type="com.haikang.pojo.Person" alias="person"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 引入properties文件-->
<!-- <properties resource="jdbc.properties"/>-->
<!-- <properties resource="jdbc2.properties"/>-->
<!-- 环境配置-->
<!-- <environments default="development">-->
<!-- <environment id="development">-->
<!-- <transactionManager type="JDBC"></transactionManager>-->
<!-- <dataSource type="POOLED">-->
<!-- <property name="driver" value="${jdbc2.driver}"/>-->
<!-- <property name="url" value="${jdbc2.url}"/>-->
<!-- <property name="username" value="${jdbc2.username}"/>-->
<!-- <property name="password" value="${jdbc2.password}"/>-->
<!-- </dataSource>-->
<!-- </environment>-->
<!-- </environments>-->
<mappers>
<mapper resource="com/haikang/mapper/UserMapper.xml"/>
</mappers>
</configuration>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
package com.haikang.test;
import com.haikang.pojo.Person;
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;
public class UserMapperTest {
public SqlSession getSqlSession() throws IOException {
//加载配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//获得SqlSession工厂对象
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得SqlSession对象
SqlSession sqlSession = build.openSession();
return sqlSession;
}
@Test
public void test1() throws IOException {
SqlSession sqlSession = getSqlSession();
List<Person> personList = sqlSession.selectList("userMapper.findAll");
System.out.println(personList);
sqlSession.close();
}
@Test
public void test2() throws IOException {
SqlSession sqlSession = getSqlSession();
int insert = sqlSession.insert("userMapper.insert", new Person(4, "湛江", "123"));
System.out.println(insert);
//提交事务
sqlSession.commit();
sqlSession.close();
}
//修改数据
@Test
public void test3() throws IOException {
Person person = new Person();
person.setId(2);
person.setUsername("明天");
SqlSession sqlSession = getSqlSession();
int update = sqlSession.update("userMapper.update", person);
System.out.println(update);
//提交事务
sqlSession.commit();
sqlSession.close();
}
@Test
public void test4() throws IOException {
Person person = new Person();
person.setId(3);
SqlSession sqlSession = getSqlSession();
int delete = sqlSession.delete("userMapper.delete",person);
System.out.println(delete);
//提交事务
sqlSession.commit();
sqlSession.close();
}
//删除数据方式二
@Test
public void test5() throws IOException {
SqlSession sqlSession = getSqlSession();
int delete = sqlSession.delete("userMapper.delete2", 4);
System.out.println(delete);
//提交事务
sqlSession.commit();
sqlSession.close();
}
}