<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<?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="db.properties"></properties>
<settings>
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!-- 控制全局缓存(二级缓存)-->
<setting name="cacheEnabled" value="true"/>
<!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过select标签的 fetchType来覆盖-->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认JAVASSIST -->
<!--<setting name="proxyFactory" value="CGLIB" />-->
<!-- STATEMENT级别的缓存,使一级缓存,只针对当前执行的这一statement有效 -->
<!--
<setting name="localCacheScope" value="STATEMENT"/>
-->
<setting name="localCacheScope" value="SESSION"/>
</settings>
<typeAliases>
<typeAlias alias="blog" type="com.ggaoxinfu.domain.Blog" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/><!-- 单独使用时配置成MANAGED没有事务 -->
<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>
<mappers>
<mapper resource="BlogMapper.xml"/>
<mapper resource="BlogMapperExt.xml"/>
</mappers>
</configuration>
SQL的xml文件
主要是每一张表的Mapper接口
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
Blog blog = (Blog) session.selectOne("com.gaoxinfu.mapper.BlogMapper.selectBlogById", 1);
System.out.println(blog);
} finally {
session.close();
}
Mapper(实际上是一个代理对象)是从 SqlSession 中获取的。
BlogMapper mapper = session.getMapper(BlogMapper.class)
参考官网
http://www.mybatis.org/mybatis-3/zh/getting-started.html
源码代码:处理Xml文件中的一级标签如properties setttings等等标签
org.apache.ibatis.session.Configuration
http://www.mybatis.org/mybatis-3/zh/configuration.html#properties
org.apache.ibatis.type.TypeAliasRegistry
<typeAliases>
<typeAlias alias="blog" type="com.gapxinfu.domain.Blog" />
</typeAliases>
1.解决的问题主要是Java 类型和数据库的 JDBC 类型的对应
2.对应的默认类处理 org.apache.ibatis.type.TypeHandlerRegistry
如上MyBatis 已经内置了很多 TypeHandler(在 type 包下)[如:StringTypeHandler,ClobTypeHandler等你等],
它们全部注册在 TypeHandlerRegistry中,他们都继承了抽象类 BaseTypeHandler,
泛型就是要处理的Java数据类型呢
StringTypeHandler源码举例
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.apache.ibatis.type;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class StringTypeHandler extends BaseTypeHandler<String> {
public StringTypeHandler() {
}
//setNonNullParameter: 设置非空参数
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter);
}
//获取空结果集(根据列名), 一般都是调用这个
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return rs.getString(columnName);
}
//获取空结果集(根据下标值)
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getString(columnIndex);
}
//获取空结果集 存储过程用的
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getString(columnIndex);
}
}
比如我们想要在获取或者设置 String 类型的时候做一些特殊处理,
我们可以写一个String 类型的 TypeHandler
package com.gaoxinfu.type;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MyTypeHandler extends BaseTypeHandler<String> {
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
throws SQLException {
// 设置 String 类型的参数的时候调用,Java类型到JDBC类型
// 注意只有在字段上添加typeHandler属性才会生效
// insertBlog name字段
System.out.println("---------------setNonNullParameter1:"+parameter);
ps.setString(i, parameter);
}
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 根据列名获取 String 类型的参数的时候调用,JDBC类型到java类型
// 注意只有在字段上添加typeHandler属性才会生效
System.out.println("---------------getNullableResult1:"+columnName);
return rs.getString(columnName);
}
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// 根据下标获取 String 类型的参数的时候调用
System.out.println("---------------getNullableResult2:"+columnIndex);
return rs.getString(columnIndex);
}
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
System.out.println("---------------getNullableResult3:");
return cs.getString(columnIndex);
}
}
配置如下
<typeHandlers>
<typeHandler handler="com.gupaoedu.type.MyTypeHandler"></typeHandler>
</typeHandlers>
1.主要是对数据库查询结果每个对象的处理
1.默认的对象工厂:org.apache.ibatis.reflection.factory.DefaultObjectFactory
package org.apache.ibatis.reflection.factory;
import java.util.List;
import java.util.Properties;
/**
* MyBatis uses an ObjectFactory to create all needed new Objects.
*
* @author Clinton Begin
*/
public interface ObjectFactory {
/**
* Sets configuration properties.
* @param properties configuration properties
*/
//设置参数时调用
void setProperties(Properties properties);
/**
* Creates a new object with default constructor.
* @param type Object type
* @return
*/
//创建对象(调用无参构造函数)
<T> T create(Class<T> type);
/**
* Creates a new object with the specified constructor and params.
* @param type Object type
* @param constructorArgTypes Constructor argument types
* @param constructorArgs Constructor argument values
* @return
*/
//创建对象(调用带参数构造函数)
<T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
/**
* Returns true if this object can have a set of other objects.
* It's main purpose is to support non-java.util.Collection objects like Scala collections.
*
* @param type Object type
* @return whether it is a collection or not
* @since 3.1.0
*/
//判断是否集合
<T> boolean isCollection(Class<T> type);
}
应用举例
public class MyObjectFactory extends DefaultObjectFactory {
@Override
public Object create(Class type) {
System.out.println("创建对象方法:" + type);
if (type.equals(Blog.class)) {
Blog blog = (Blog) super.create(type);
blog.setName("object factory");
blog.setBid(1111*100);
blog.setAuthorId(2222);
return blog;
}
Object result = super.create(type);
return result;
}
}
<!-- mybatis-config.xml -->
<objectFactory type="org.mybatis.gaoxinfu.MyObjectFactory ">
<property name="someProperty" value="100"/>
</objectFactory>
http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html
<if>
<choose> (<when>,<otherwise>)
<trim> (<where>,<set>)
<foreach>
mybatis操作数据库,默认最大4M数据包
1.把所有的循环的,弄成一次插入或者删除,可以减少数据库的交互次数;
2.但是数据量太大,不太好,因为数据库操作,数据包最大4M,ping接的太大,可能会报错;
样例
insert into tbl_emp (emp_id, emp_name, gender,email, d_id) values ( ?,?,?,?,? ) , ( ?,?,?,?,? ) , ( ?,?,?,?,? ) , ( ?,?,?,?,? ) ,
( ?,?,?,?,? ) , ( ?,?,?,?,? ) , ( ?,?,?,?,? ) , ( ?,?,?,?,? ) , ( ?,?,?,?,? ) , ( ?,?,?,?,? );
delete from tbl_emp where emp_id in (?,?,?,?);
@Test
public void testJdbcBatch() throws IOException {
Connection conn = null;
//支持预编译和缓存 PreparedStatement.addBatch()添加批次,批量执行 PreparedStatement.executeBatch();
PreparedStatement ps = null;
try {
// 注册 JDBC 驱动
Class.forName("com.mysql.jdbc.Driver");
// 打开连接
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true",
"root",
"root");
ps = conn.prepareStatement(
"INSERT into blog values (?, ?, ?)");
for (int i = 1000; i < 101000; i++) {
Blog blog = new Blog();
ps.setInt(1, i);
ps.setString(2, String.valueOf(i));
ps.setInt(3, 1001);
ps.addBatch();
}
ps.executeBatch();
// conn.commit();
ps.close();
conn.close();
} catch (SQLException se) {
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (ps != null) ps.close();
} catch (SQLException se2) {
}
try {
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
}
Batch Executor
底层和上面的PreparedStatement批量执行原理一样