用Maven项目配置Mybatis依赖
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>x.x.xversion>
dependency>
<configuration>
configuration>
在配置文件中通过在properties配置一些property,这些property可以在配置文件的其他位置通过${propertyname}的方式来进行引用。
<properties resource="org/mybatis/example/config.properties">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/User"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
properties>
在整个配置文件中用来替换需要动态配置的属性值,比如:
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
属性配置的优先级:
在MyBatis的XML配置文件中可以通过settings字段元素配置MyBatis 的运行时行为
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
settings>
我们可以通过typeAliases元素来配置java类中类路径名的别名,以后要写类的全路径名时,就可以用简短的别名来代替。
<typeAliases>
<typeAlias alias="User" type="com.book.User"/>
<typeAlias alias="ShopList" type="com.book.ShopList"/>
typeAliases>
也可以这样配置,通过扫描包下的所有类并以类名为全路径名:
<typeAliases>
<package name="com.book"/>
typeAliases>
或者在写代码的通过注解的方式设置
@Alias("User")
public class User {
...
}
objectFactory元素可以配置设置自己的对象工厂。MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。
自定义工厂类
这里工厂类有四个方法。
前两个方法分别对应处理默认无参构造方法和处理有参构造,可以在这两个方法添加一些类创建前的处理。
后两个方法setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。
// ExampleObjectFactory.java
public class ExampleObjectFactory extends DefaultObjectFactory {
public Object create(Class type) {
return super.create(type);
}
public Object create(Class type, List constructorArgTypes, List constructorArgs) {
return super.create(type, constructorArgTypes, constructorArgs);
}
public void setProperties(Properties properties) {
super.setProperties(properties);
}
public boolean isCollection(Class type) {
return Collection.class.isAssignableFrom(type);
}}
在xml中指定自己的工厂类
<objectFactory type="org.mybatis.example.ExampleObjectFactory">
<property name="someProperty" value="100"/>
objectFactory>
MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。MyBatis 允许使用插件来拦截的方法调用包括:
创建自己的插件类
/**
* @Intercepts 拦截器注解,包括一个或多个 @Signature
* @Signature 拦截的目标类信息,包括 type、method、args
* * type 要拦截的接口类型(对应Executor,ParameterHandler,ResultSetHandler,StatementHandler)
* * method 接口中的方法名(接口中的方法)
* * args 方法的所有入参类型
*/
@Intercepts({
@Signature(
type = StatementHandler.class,
method = "prepare",
args = {
Connection.class, Integer.class}
)
})
public class ExamplePlugin implements Interceptor {
//自定义的拦截逻辑
@Override
public Object intercept(Invocation invocation) throws Throwable {
//invocation为调用对象
// MetaObject 是 Mybatis 提供的一个用于访问对象属性的对象
MetaObject metaObject = SystemMetaObject.forObject(invocation);
//通过getValue获取信息
//拦截的对象
metaObject.getValue("target");
//拦截的sql语句
metaObject.getValue("target.delegate.boundSql.sql");
//setValue设置信息
//更改sql语句
//metaObject.setValue("target.delegate.boundSql.sql", newSQL);
// 返回执行结果(调用执行并传递给下一步)
return invocation.proceed();
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
}
}
配置插件
<plugins>
<plugin interceptor="org.mybatis.example.ExamplePlugin">
<property name="someProperty" value="100"/>
plugin>
plugins>
MyBatis 可以配置成适应多种环境,例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。许多类似的用例。
<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>
映射器(mappers),用于配置SQL语句的映射,但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。通过mappers字段配置XML映射文件的位置。
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
mappers>
或者这样
<mappers>
<package name="org.mybatis.builder"/>
mappers>
namespace="org.mybatis.example.BlogMapper"标明映射的mapper接口命名空间。每个mapper映射文件都对应一个映射器。每个mapper映射器都要注册到Mybatis的配置文件。(上面的mappers元素中配置)
映射器:
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
select>
mapper>
对应的映射接口:
package org.mybatis.example;
public interface BlogMapper {
Blog selectBlog(int id);
}
使用java注解映射SQL语句
除了通过xml设置sql语句还可以在代码里面通过java注解的方式来实现SQL语句的映射。
package org.mybatis.example;
public interface BlogMapper {
@Select("SELECT * FROM blog WHERE id = #{id}")
Blog selectBlog(int id);
@Delete("delete from blog where id = #{id}")
void deleteBlog(int id);
}
MyBatis 的真正强大在于它的映射语句,mybatis通过SQL 映射语句,将实体类中属性与数据库中字段映射。比较常用的映射如下:
insert
– 映射插入语句update
– 映射更新语句delete
– 映射删除语句select
– 映射查询语句MyBatis 通过Mapper XML 文件来配置映射语句。
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
select>
<select id="selectPerson" parameterType="int" resultType="com.book.pojo.author">
SELECT * FROM author WHERE ID = #{id}
select>
跟select一样,SQL语句写在字段之间,并且通过唯一的ID号来标识该SQL语句。
<insert id="insertAuthor">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
insert>
<update id="updateAuthor">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
update>
<delete id="deleteAuthor">
delete from Author where id = #{id}
delete>
更多的配置应该参考官方文档,而本文章跟注重如何快速使用mybatis,使用下面直接讲如何使用java调用这些配置好的SQL语句。
MyBatis 的主要 Java 接口就是 SqlSession。你可以通过该接口来执行SQL命令。SqlSession通过:
上面的流程可以知道,创建SqlSession要先创建SqlSessionFactory,要创建 SqlSessionFactory 要通过SqlSessionFactoryBuilder来创建。
首先先new一个SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactoryBuilder通过build 方法来创建SqlSessionFactory,SqlSessionFactoryBuilder 有五个 build() 方法,每一种都允许你从不同的资源中创建一个 SqlSessionFactory 实例。
SqlSessionFactory build(InputStream inputStream)
SqlSessionFactory build(InputStream inputStream, String environment)
SqlSessionFactory build(InputStream inputStream, Properties properties)
SqlSessionFactory build(InputStream inputStream, String env, Properties props)
SqlSessionFactory build(Configuration config)
创建SqlSessionFactory官方示例:
String resource = "org/mybatis/builder/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
SqlSessionFactory是用来创建SqlSession,SqlSessionFactory可以认为是在数据源中获得数据库连接然后封装在SqlSession中供程序员使用。
SqlSessionFactory 有多个方法创建 SqlSession 实例。
SqlSession openSession()
SqlSession openSession(boolean autoCommit)
SqlSession openSession(Connection connection)
SqlSession openSession(TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType)
SqlSession openSession(ExecutorType execType, boolean autoCommit)
SqlSession openSession(ExecutorType execType, Connection connection)
默认的 openSession() 方法没有参数,它会创建具备如下特性的 SqlSession:
参数:
autoCommit
事务自动提交
connection
自己的数据库连接
TransactionIsolationLevel
事务隔离级别
NONE
、READ_UNCOMMITTED
、READ_COMMITTED
、REPEATABLE_READ
和 SERIALIZABLE
)execType
执行类型
ExecutorType.SIMPLE
:该类型的执行器没有特别的行为。它为每个语句的执行创建一个新的预处理语句。
ExecutorType.REUSE
:该类型的执行器会复用预处理语句。
ExecutorType.BATCH
:该类型的执行器会批量执行所有更新语句,如果 SELECT 在多个更新中间执行,将在必要时将多条更新语句分隔开来,以方便理解
SqlSession包含了所有执行语句、提交或回滚事务以及获取映射器实例的方法。SqlSession用于执行SQL。
执行sql语句
<T> T selectOne(String statement, Object parameter)
<E> List<E> selectList(String statement, Object parameter)
<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<T> Cursor<T> selectCursor(String statement, Object parameter)
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
int insert(String statement, Object parameter)
int update(String statement, Object parameter)
int delete(String statement, Object parameter)
旧版本 MyBatis
这里的org.mybatis.example.BlogMapper.selectBlog对应mapper映射器+执行语句的ID。如:
try (SqlSession session = sqlSessionFactory.openSession()) {
Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
}
新版本MyBatis
较新的版本官方建议通过getMapper来获取映射的接口先,再执行接口的方法。
try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
}
快速使用mybatis的过程:
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.6version>
dependency>
spring整合mybatis后,mybatis中的SqlSessionFactory和SqlSession都交由spring来进行托管。
首先要在spring的配置文件中配置数据源,数据源可以是多种,c3p0,DBCP,spring自带的等都行。
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/User?useSSL=true" />
<property name="username" value="root" />
<property name="password" value="root">
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
bean>
官方解析:
SqlSessionTemplate
是 MyBatis-Spring 的核心。作为 SqlSession
的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的 SqlSession
。 SqlSessionTemplate
是线程安全的,可以被多个 DAO 或映射器所共享使用。注意这里标的“无缝代替”。
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
bean>
先编写UserDao接口的实现类
public class UserDaoImpl implements UserDao {
private SqlSession sqlSession;
public void setSqlSession(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
public User getUser(String userId) {
return sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
}
}
注入SqlSessionTemplate,并将实现类给spring托管。
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
<property name="sqlSession" ref="sqlSession" />
bean>
官方提供了一个SqlSessionDaoSupport,SqlSessionDaoSupport
是一个抽象的支持类,用来为你提供 SqlSession
。调用 getSqlSession()
方法你会得到一个 SqlSessionTemplate
。
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
public User getUser(String userId) {
return getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
}
}
使用SqlSessionDaoSupport就可以跳过配置SqlSessionTemplate的这一步,在进行注入的时候,不在是SqlSessionTemplate,而是直接引用sqlSessionFactory。
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
bean>