一、下载相关依赖JAR包mysql-connector-java-5.1.20.jar(数据库驱动)、mybatis-3.2.6.jar(Mybatis),最好把相关源码也下载下来:
二、 新建JAVA工程,添加依赖JAR包。
三、 创建Mybatis配置文件(myBatis-config.xml)完成和数据库的链接设置操作、DTD是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"/>
<environments default="dev"><!--可以定义多个环境,根据实际环境选取配置 -->
<environment id="dev">
<transactionManager type="JDBC"/>
<!-- 事务管理器类型,两种事务管理类型(type=”[JDBC|MANAGED]”) -->
<!-- JDBC:直接简单使用了 JDBC 的提交和回滚设置。 它依赖于从数据源得到的连接来管理事务范围 -->
<!-- MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如 Spring 或 J2EE 应用服务器的上下文) 默认情况下它会关闭连接-->
<!-- 数据源 -->
<dataSource type="POOLED">
<!-- 三种内建的数据源类型 -->
<!-- 1、UNPOOLED:每次被请求时简单打开和关闭连接 -->
<!-- UNPOOLED 类型的数据源仅仅用来配置以下 4 种属性: -->
<!-- driver – 这是 JDBC 驱动的 Java 类的完全限定名-->
<!-- url – 这是数据库的 JDBC URL 地址。-->
<!-- username – 登录数据库的用户名。 -->
<!-- password – 登录数据库的密码。 -->
<!-- defaultTransactionIsolationLevel – 默认的连接事务隔离级别。 -->
<!-- driver.encoding=UTF8 -->
<!-- 2、POOLED – 这是 JDBC 连接对象的数据源连接池的实现,用来避免创建新的连接实例时必要的初始连接和认证时间。这是一种当前 Web 应用程序用来快速响应请求很流行的方法。-->
<!--3、JNDI 这个数据源的实现是为了使用如 Spring 或应用服务器(tomcat)这类的容器, 容器可以集
中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。这个数据源配置只需要两个属
性:initial_context(从 初 始 上 下 文 中 寻 找 环 境)、data_source(引用数据源实例位置的上下文的路径)、env.encoding=UTF8 -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
</configuration>
jdbc.properties
jdbc.driverclass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mysql_learn
jdbc.username=root
jdbc.password=123qwe
四、 创建实体类(User.java)
package com.qding.mybatis.learn.model;
/**
*
* @author zhangyonghong
*
*/
public class User {
private Long id;
private String name;
private Integer sex ;
private Integer isDel;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Integer getIsDel() {
return isDel;
}
public void setIsDel(Integer isDel) {
this.isDel = isDel;
}
}
五、 创建map文件完成实体类的映射(User.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="com.qding.mybatis.learn.model.User">
<insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="com.qding.mybatis.learn.model.User">
INSERT INTO `t_user` (name,sex,is_del)
VALUES (
#{name,jdbcType=VARCHAR},
#{sex,jdbcType=TINYINT},
#{isDel,jdbcType=TINYINT}
)
</insert>
</mapper>
六、编写测试类
package com.qding.mybatis.learn.test;
import java.io.IOException;
import java.io.Reader;
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 com.qding.mybatis.learn.model.User;
public class TestAdduser {
public static void main(String[] args) {
myBatisTest();
}
public static void myBatisTest(){
try {
//1、创建读取配置文件myBatis-config.xml的输入流
String resource = "myBatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
//2、创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
//3、创建SQLSession
SqlSession session = factory.openSession();
//4、调用mapper文件插入数据,需要将mapper文件加载到配置文件(myBatis-config.xml)中
User user =new User();
user.setName("王靖坤");
user.setSex(1);
user.setIsDel(0);
session.insert("com.qding.mybatis.learn.model.User.insert", user);
session.commit();
session.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void JDBCTest(){
}
}
七、简单的运行原理:
1、读取mybatis配置解析问文件流
String resource = "myBatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
2、创建SqlSessionFactory,myBatis的默认实现类是DefaultSqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactoryBuilder类的build方法:
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
XMLConfigBuilder类部分代码:
属性:
protected final Configuration configuration;
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。
方法:
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
最终会myBatis配置文件解析为Configuration类、其中Configuration类中的mappedStatements(Map)属性将存储每个mapper配置信息(Map<key,MappedStatement>)key=namespace+id ===>"com.qding.mybatis.learn.model.User.insert"
3、获取session链接 获取默认DefaultSqlSession实例。
4、新增 session.insert("com.qding.mybatis.learn.model.User.insert", user); DefaultSqlSession.insert
public int update(String statement, Object parameter) {
try {
dirty = true;
MappedStatement ms = configuration.getMappedStatement(statement);
return executor.update(ms, wrapCollection(parameter));
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
myBatis 会根据你传入的“com.qding.mybatis.learn.model.User.insert”在初始化的configuration里查找到对应的MappedStatement并通过默认的Executor执行sql
BoundSql是myBatis 封装的原子性操作封装:
public class BoundSql {
private String sql;
private List<ParameterMapping> parameterMappings;
private Object parameterObject;
private Map<String, Object> additionalParameters;
private MetaObject metaParameters;
。。。。。
}
处理返回主键:
PreparedStatementHandler
public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
int rows = ps.getUpdateCount();
Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
return rows;
}
processAfter这个方法会根据mapper中的配置useGeneratedKeys="true" keyProperty="id" 去取值并赋值在对象实例上。