文档章节

mybatis必知必会

haoran_10
 haoran_10
发布于 2016/07/15 16:39
字数 2914
阅读 15
收藏 2
点赞 0
评论 1

1、SqlSessionFactory

2、SqlSession

3、Mapper XML 文件

4、动态SQL

5、常用API

6、集成spring

6.1、SqlSessionFactoryBean

6.2、SqlSessionTemplate

 

前沿:什么是mybatis,为什么需要她?

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。

MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

优点:比原生jdbc简单,少写很多通用的代码。比类似hibernate简单,直观,可操作性强。

 -------------------------------------------------------------------------------------------------------------------------

1、SqlSessionFactory

要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于 classpath 中即可。

ps:如果使用 Maven 来构建项目,则需将下面的 dependency 代码置于 pom.xml 文件中,相应version可以在http://www.mvnrepository.com/ maven中央库去查找,或者自己的私服。

 

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>

 

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。其实就是session管理的一个工厂。

SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得,而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。

 

public SqlSessionFactory SqlSessionFactory(){
		DataSource dataSource ;//数据库连接池,使用第三方即可
		TransactionFactory transactionFactory = new JdbcTransactionFactory();//事物,使用默认。也可以配合spring,使用spring自带的
		Environment environment = new Environment("development", transactionFactory, dataSource);//环境配置即 开发或者生产
		
		Configuration configuration = new Configuration(environment);//配置中心
		//configuration.addMappers("conge.wang.sqlmappers");//加载mappers xml package,及扫描conge.wang.sqlmappers下面的xml配置
		//configuration.addMapper(TestSqlMapper.class);//或者加载mappers class。不过不推荐使用
		
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);//从SqlSessionFactoryBuilder构建
		
		return sqlSessionFactory;
	}
 注意点:

 

(1)、SqlSessionFactoryBuilder 这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳范围是方法范围(也就是局部方法变量)。你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在以保证所有的 XML 解析资源开放给更重要的事情。

 

(2)、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳范围是应用范围。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

 

 

2、SqlSession

SqlSession  可以理解为一个jdbc Connection。

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的范围是请求或方法范围。

绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。

也绝不能将 SqlSession 实例的引用放在任何类型的管理范围中,比如 Serlvet 架构中的 HttpSession。

那么也就是说,每次操作时,获取新的SqlSession,并且确保完成数据库操作之后,确保关闭,例如:

 

SqlSession session = sqlSessionFactory.openSession();
try {
  // 业务处理
} finally {
  session.close();
}

 

注意点:

(1)、一定确保SqlSession是线程安全使用

(2)、一定确保使用完成,或者异常时,关闭SqlSession

 

 

3、Mapper XML 文件

MyBatis的核心就在Mapper XML文件的配置,大显身手的地方。

SQL 映射文件有很少的几个顶级元素,

 

resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。

sql – 可被其他语句引用的可重用语句块。

insert – 映射插入语句

update – 映射更新语句

delete – 映射删除语句

 

select – 映射查询语句

 

(0)、先建张表,以备使用,mysql数据库

CREATE TABLE `t_test` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(50) NOT NULL DEFAULT '0',
	`num` INT(11) NOT NULL DEFAULT '0',
	`create_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;

 
定义下面的这些的SQL语句之前,别忘了命名空间

 

<?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="t_test">

...//SQL语句配置
</mapper >
 

 

 

(1)、即预定义一些SQL语句,其他SQL配置可以直接引用,省去很多重复编码

<sql id="baseResult">
     id,name,num,create_ts
</sql>

上面定义了t_test 表的所有字段 ,也可以定义一些复杂的通用的SQL代码,但最好一目了然,太复杂不利于维护,二次开发。这也正是魅力所在。

 

(2)、resultMap ,定义SQL表字段对java pojo的映射,可以理解为ORM,对象--表对应

<resultMap id="baseMap" type="pojo.TTest">
	<id column="id"              property="id" />
	<result column="name" 	     property="name" />
	<result column="balance"     property="num" />
	<result column="create_ts"   property="createTs" />
</resultMap>

虽然映射了表和POJO的对象,但是不一定全部字段映射,也不一定非要每个表都要映射,也可以多个表的join之后的字段映射为一个POJO,总之一句话,灵活使用。 

 

(3)、select ,查询语句。

 

<select id="query" parameterType="map" resultMap="baseMap">
	SELECT <include refid="baseResult"/>
		FROM t_test
        WHERE id = #{id}
</select>
 注意点:

 

a)、id 在命名空间中唯一的标识符,可以被用来引用这条语句。

b)、parameterType 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。

         其实做为parameterType 无非三类参数,1.直接一个基本类型的数据 2.一个java bean的参数,包含多个基本类型 3、map类型

c)、resultMap  外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用。

d)、resultType  java类,包含多个基本类型 ,和resultMap作用一样,用来映射结果集 

 其他的还有一些属性,用的时候在查即可。

 

#{id} 即接收一个id的参数,就像PreparedStatement 预处理SQL语句,占位符。

 

(4)insert, update 和 delete 基本类似

insert语句,selectKey使用Mysql自带的主键自增长特性 

 

<insert id="insert" parameterType="pojo.TTest">
  insert into t_test(id,name,num)
  values (#{id},#{name},#{num})

        <selectKey keyProperty="id" resultType="java.lang.Long">
		  SELECT LAST_INSERT_ID() AS ID
	</selectKey>
</insert>
 update语句
<update id="update" parameterType="map">
	UPDATE t_test
		SET num = #{num}
	WHERE id = #{id}
</update>
 删除语句
<delete id="delById" parameterType="long">
	DELETE FROM t_test
		WHERE id = #{id}
</delete>
 

 

 平时使用MyBatis开发时,和这些配置则是打交道最频繁的,所以写SQL的时候,一定要规范好。

 

 

4、动态SQL

MyBatis强大的另外一个地方则是动态SQL。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

(1)、if

动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。例如:

<select id="query" parameterType="map" resultMap="baseMap">
	SELECT <include refid="baseResult"/>
		FROM t_test
	WHERE 1=1
	  <if test="id!=0">
               AND id = #{id}
          </if>   
</select>

 还是基于上个SELECT语句,只不过加了一句动态的条件附加语句。这个时候,如果id!=0,会执行AND id = #{id},如果id==0,则不会执行这一句。

动态体现的淋漓尽致。

 

(2)、choose, when, otherwise

有些时候,我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

 

<select id="query" resultType="Blog">
	SELECT <include refid="baseResult"/>
		FROM t_test
	WHERE 1=1
	  <choose>
		<when test="flag == 1">
		  AND id> #{id}
		</when>
		<when test="flag == 2">
		  AND id= #{id}
		</when>
		<otherwise>
		  AND #{id} > id 
		</otherwise>
	  </choose>
</select>
 这个时候使用flag字段不同值,对应的SQL语句不同

 

 

(3)、foreach  非常有用的一个语法

动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候。比如:

 

 

<select id="query" parameterType="map" resultMap="baseMap">
	SELECT <include refid="baseResult"/>
		FROM t_test
	WHERE ID in
	  <foreach collection="idList" item="item" index="index"  open="(" separator="," close=")">
			#{item}
	  </foreach>
</select>
 如果查询一组id,可以使用foreach

 

ps:关于exist于in 的使用,如果id数组范围小,使用in,如果id数组范围大于查询的表的本身,使用exist。一句话,从少的结果集中扫描。

 

(4)、like,不是MyBatis的特性,只是偶尔用下。不要乱用,性能不行。

 

 

select * from my_tab  
where keywords like CONCAT('%',#{keywords},'%' )

 

 

5、常用API

SqlSessionFactory 很少操作,不必刻意记住一下api,需要时查询即可。但是SqlSession有一些使用频率非常高的api,在使用的过程,不刻意记,也记住了。

这些方法被用来执行定义在 SQL 映射的 XML 文件中的 SELECT,INSERT,UPDA E T 和 DELETE 语句。它们都会自行解释,每一句都使用语句的 ID 属性和参数对象,参数可以 是原生类型(自动装箱或包装类) ,JavaBean,POJO 或 Map。

 

<T> T selectOne(String statement, Object parameter)//只返回一条数据,如果有多条结果时,会报错,建议此类的select 语句最后加一句limit 1
<E> List<E> selectList(String statement, Object parameter)//返回多条数据
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey)
int insert(String statement, Object parameter)//插入
int update(String statement, Object parameter)//更新
int delete(String statement, Object parameter)//删除
至于使用映射器,就罢了,不用也没啥。 

 

 

6、集成spring

6.1、SqlSessionFactoryBean

6.2、SqlSessionTemplate

要使用 MyBatis-Spring 模块,你只需要包含 mybatis-spring-x.x.x.jar 文 件就可以了,并在类路径中加入相关的依赖。相应version可以在http://www.mvnrepository.com/ maven中央库去查找,或者自己的私服。

如果你使用 Maven,那么在 pom.xml 中加入下面的代码即可:

 

dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>x.x.x</version>
</dependency>
 这个时候,SqlSessionFactory,SqlSession就交给了spring管理。spring使用SqlSessionFactoryBean去代理SqlSessionFactory,使用SqlSessionTemplate去代理SqlSession。
import java.beans.PropertyVetoException;
import java.io.IOException;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.support.TransactionTemplate;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration
public class DbConfig {
	
	@Bean 
	public DataSource DataSource() throws PropertyVetoException{
		DruidDataSource ds = new DruidDataSource();
		
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl(XX);
		ds.setUsername(XX);
		ds.setPassword(XX);
		
                //配置数据库连接池
		return ds;
	}
	
	@Bean
	public SqlSessionFactoryBean SqlSessionFactoryBean() throws IOException, PropertyVetoException {
		SqlSessionFactoryBean fc = new SqlSessionFactoryBean();
		fc.setDataSource(DataSource());
		
		ResourcePatternResolver resoler = ResourcePatternUtils.getResourcePatternResolver(new DefaultResourceLoader());
		
		fc.setMapperLocations(resoler.getResources("sql/*/*.xml"));//扫描sql包下面的子包下面的mapper xml文件
		
		return fc;
	}
	
	@Bean
	public SqlSessionTemplate SqlSessionTemplate() throws Exception {
		SqlSessionTemplate sqlSession = new SqlSessionTemplate(SqlSessionFactoryBean().getObject());
		
                //SqlSessionTemplate 是线程安全的,放心使用
		return sqlSession;
	}
	
	@Bean
	public DataSourceTransactionManager transactionManager() throws PropertyVetoException{
		DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
		transactionManager.setDataSource(DataSource());
		
		return transactionManager;
	}
	
	@Bean
	public TransactionTemplate TransactionTemplate() throws PropertyVetoException{
		TransactionTemplate tsTemplate = new TransactionTemplate();
		tsTemplate.setTransactionManager(transactionManager());
		tsTemplate.setIsolationLevel(Isolation.DEFAULT.value());//事物级别采用数据库默认
		tsTemplate.setPropagationBehavior(Propagation.REQUIRED.value());//事物传播行为采用默认
		
		return tsTemplate;
	}
	
}
   注意点:

 (1)、在基本的 MyBatis 中,session 工厂可以使用 SqlSessionFactoryBuilder 来创建。而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来替代。

也可以使用xml配置,例如:

 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
</bean>
  mapperLocations配置就是扫描该包下的mapper xml配置文件

 

(2)、事物,就用spring的。关于事物,一两句说不完整,要单独篇幅了。

(3)、 SqlSessionTemplate 是线程安全的, 可以被多个 DAO 所共享使用。业界良心啊!所有一切有陷阱的代码都不是好代码。

 

怎么使用SqlSessionTemplate?

@Repository
public class TestRepository {
	@Autowired SqlSession session;
	
	public TTest queryById(long id){
		return session.selectOne("t_test.query", id);
	}
}

 

简洁而不简单。简于形而繁于心,这种设计真的超赞。

 

 

 

 --------------------------------------------------------------------------------------------------------------------------------

总结:MyBatis其实是一个半ORM的持久化框架,但正是这种特性,开发人员更能更加灵活的运用,订制SQL语句,直接提升性能。

如果说hibernate是一把M16,那么MyBatis就是一把AK47。

我喜欢MyBatis。

 

© 著作权归作者所有

共有 人打赏支持
haoran_10
粉丝 25
博文 88
码字总数 80846
作品 0
杭州
程序员
加载中

评论(1)

i
itxx2016
推荐国内最流行的ibatis、mybatis代码生成网站: fwjava.com
无需任何安装配置,直接在线生成,且十分规范好用.
现在,很多知名的互联网公司都在用它.
双11Java程序员书单推荐

Java 《Java核心技术卷I》 《Java核心技术卷II》 《Java编程思想》 《Java并发编程实战》 《Effective Java》 《Java8实战》 《Java8函数式编程思维》 《深入理解Java虚拟机》 《Java性能权威...

黄步欢
2017/11/04
0
0
PHPer 必知必会的 Linux 命令

PHPer 必知必会的 Linux 命令https://github.com/Nick233333/gitbook

-Nick-
06/08
0
0
新手必看,Spring Boot CLI 必会必知

新手必看,Spring Boot CLI 必会必知 泥瓦匠BYSocket2017-10-249 阅读 Spring技术 Spring Boot CLI 是什么 Spring Boot CLI 是 Spring Boot Commad Line 的缩写,是 Spring Boot 命令行工具。...

泥瓦匠BYSocket
2017/10/24
0
0
程序猿成长计划--growing-up

程序猿成长计划 程序员成长计划包含了作为一名程序猿成长过程中的所学,我把这些以教程的形式开源出来,供大家一起学习、补充,共同成长。 三十分钟学会AWK Docker学习笔记-基础命令 一小时学...

mylxsw
2016/11/30
704
0
推荐《高性能MYSQL(第3版)》及 { MySQL性能管理及架构设计 }

最近项目所在服务器经常当机,我怀疑是不是数据库的问题,却不知从哪下手优化。 MySQL的性能优化一直是非常有必要学习的! 考虑 购买:《高性能MYSQL(第3版)》 同学福利:电子版终于找到:放...

phpervip
2017/09/30
0
0
关于sql子查询优化的一个问题

来自《mysql必知必会》里面的例子 表结构如下:Create Table: CREATE TABLE ( int(11) NOT NULL autoincrement, `orderdatecustidordernumfkorderscustomerscustidfkorderscustomerscustidcu......

超级呆子
2013/02/24
298
3
泥瓦匠 5 年 Java 的成长感悟(下)

泥瓦匠 5 年 Java 的成长感悟(下) 泥瓦匠BYSocket2017-10-236 阅读 继续《泥瓦匠 5 年 Java 的成长感悟(上)》,大致包括下面几点: 学技术的心态 学技术的学法 工作的心态 工作的硬技能 ...

泥瓦匠BYSocket
2017/10/23
0
0
简单对比几条查询语句的执行时间

平时都是用第三种查询,今天看了SQL必知必会 第4版,作了几次查询实验。原来在一般情况下,还是用嵌套查询时间快些: set statistics time on; select * from ICBOMChild where FInterID in...

笔下生辉
2017/08/25
0
0
Python 免费资源集合--Awesome Python

Awesome Python 是一个资源整理集合,由 vinta 发起和维护。内容包括:Web框架、网络爬虫、网络内容提取、模板引擎、数据库、数据可视化、图片处理、文本处理、自然语言处理、机器学习、日志...

匿名
2017/01/22
2.1K
0
OSChina 开源周刊 44 期

每周技术抢先看,总有你想要的! 移动开发 【开发】使用 Countly 来分析 Apple Watch 统计数据 【翻译】Xcode 7 中的 UI 测试功能 前端开发 【开源访谈】大漠穷秋:AngularJS 发展与开源精神...

OSC编辑部
2015/07/25
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

全新内存布局Android5 for one x

众所周知Android5.0默认ART模式,运行速度加倍,软件占用内存也加倍,我们one x这种元老机采用旧的内存布局,data空间2g ART模式下安装几个软件也就不够用了。最近逛国外的xda论坛,发现有大...

CrazyManDF
6分钟前
0
0
web3j转账

 web3 转账功能   为了完成以太坊交易,必须有几个先决条件   1、对方的以太坊地址   2、确定要转账的金额   3、自己地址的转账权限   4、大于转账金额的以太币,以太币转账其实就...

智能合约
7分钟前
0
0
10.28 rsync工具介绍 , rsync常用选项, rsync通过ssh同步

rsync远程同步 重点!重点!!重点!!! 例子 • rsync -av /etc/passwd /tmp/1.txt • rsync -av /tmp/1.txt 192.168.188.128:/tmp/2.txt rsync格式 • rsync [OPTION] … SRC DEST • rs......

Linux_老吴
21分钟前
0
0
iis php 环境搭建,非常详细的教程

准备篇 一、环境说明: 操作系统:Windows Server 2016 PHP版本:php 7.1.0 MySQL版本:MySQL 5.7.17.0 二、相关软件下载: 1、PHP下载地址: http://windows.php.net/downloads/releases/ph...

T_star
23分钟前
0
0
Day35 rsync通过服务同步

rsync通过服务同步 rsyncd.conf配置文件详解 port:指定在哪个端口启动rsyncd服务,默认是873端口。 log file:指定日志文件。 pid file:指定pid文件,这个文件的作用涉及服务的启动、停止等...

杉下
28分钟前
1
0
【最新最全】为 iOS 和 Android 的真机和模拟器编译 Luajit 库

编译 Luajit 库,的确是一个挑战。因为官网的教程,在当前版本的 Xcode 和 NDK 环境中,已经不适用了。以前只是编译了适用于真机的 Luajit 库。最近在尝试编译模拟器 Luajit 库,就顺便梳理了...

ios122
28分钟前
0
0
rsync至ssh同步

rsync: 文件同步工具,可实现“增量拷贝”;使用yum安装rsync包 常用选项:-a=-rtplgoD (-r同步目录,-t保持文件的时间属性,-p保持文件的权限属性,-l保持软连接,-g保持文件的属组,-o保持...

ZHENG-JY
34分钟前
0
0
TradingView 学习笔记

#前言 公司最后需要使用TradingView展示K线图走势。由于之前没接触过,拿到文档时一脸蒙逼。还好找到二篇文章+Demo代码,直接改改就行了。 #被批 由于上面的懵懂,有个问题困扰4个小时没解决...

hihubs
34分钟前
0
0
10.28 rsync工具介绍~10.31 rsync通过ssh同步

rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而...

洗香香
36分钟前
1
0
卷积为什么要旋转180度

参考《最容易理解的对卷积(convolution)的解释》 https://blog.csdn.net/bitcarmanlee/article/details/54729807 这篇博客详细讲解了“卷积”,提及了为什么要反转180度,我简述下。 1.卷积的...

datadev_sh
45分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部