`
haoran_10
  • 浏览: 444443 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

mybatis必知必会

阅读更多

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。

 

分享到:
评论

相关推荐

    500道Java后端面试必知必会-V1版.pdf

    《500道Java后端面试必知必会-V1版.pdf》这份文档的内容主要聚焦于Java后端开发领域的面试题目和知识点,其涵盖了面试者在求职过程中可能会遇到的Java相关问题。该文档适合准备Java后端开发面试的读者,帮助他们更好...

    mybatis-generator-gui.zip

    MyBatis Generator (MBG) 是一个强大的工具,它能够自动生成 MyBatis 框架所需的 SQL 映射文件、Java 模型类以及 DAO 接口。这个工具极大地提高了开发效率,尤其是在处理大量的数据库表时。"mybatis-generator-gui....

    java 必会108题,大数据面试文档,Java面试文档,Java公司面试真题

    一、Java必知必会108题 这部分内容可能涵盖了Java基础语法、面向对象编程、集合框架、多线程、异常处理、I/O流、网络编程、反射机制、JVM内存模型等多个方面。例如: 1. Java的基础语法:变量声明、数据类型、运算符...

    通过这篇总结实现找工作自由! 《Java面试必知必系列-V1.0》靠谱

    本文将基于《Java面试必知必系列-V1.0》的指导,提炼出一些关键知识点。 1. **Java基础** - **三大特性**:封装、继承和多态。封装是限制对对象属性的直接访问,通过方法来操作;继承允许创建新的类(子类)继承已...

    技术面试分享资源.ZIP

    4. **Java基础 - 必知必会(中/下)**: 这些章节可能包括了异常处理、多线程、IO流、反射等Java基础知识。面试中,你应能解释何时抛出异常,如何正确使用synchronized关键字,理解文件读写的基本操作,以及如何...

    java笔试面试题企业版2021-07-11最新

    04-Java必知必会108题 全部答案,更新日期:2024年7月11日,直接下载吧! 新增:高清172份,累计 7701 页大厂面试题 PDF 新增:高清172份,累计 7701 页大厂面试题 PDF 所有干货免费奉送,,如果整理数据材料不易...

    javaee笔试题-JavaExercise:Java学习的代码,包括设计模式、se、ee以及相关测试代码

    java ee笔试题 JavaExercise 方便同步 Arch 与 Windows 主要是一些练习代码... 秋招 ...必知必会 书籍 Java 程序员面试宝典 Netty 实战 Java8 实战 并发 Java 并发编程实战 Java 并发编程的艺术 JVM

    java自学路线图(超全超详细)

    * SQL:推荐《SQL 必知必会》,视频可以观看 B 站上的老外视频课。 * MySQL:推荐《高性能MySQL》,视频可以观看 B 站上的女老师视频。 * Redis:推荐《Redis 深度历险:核心原理与应用实战》,视频可以观看 B 站上...

    learning-note:web学习笔记

    webNote java 基础 容器化&持续集成 框架 java8 数据库访问 Hibernate Hibernate连接查询 JPA Mybatis ...Mysq必知必会 前端 Vue Vue&Angular 微信小程序 python Python Python+Appium自动化测试

    互联网公司测试工程师测试开发工程师(已拿到头条、小米、shopee、微众银行)面经整理.docx

    - 学习《MySQL 必知必会》以应对基础面试问题。 - 主从复制、分表分库等进阶概念。 - 深入理解 MySQL 索引机制。 5. **JVM**: - JVM 内存分区、垃圾收集机制和类加载。 6. **框架**: - SSM(Spring、...

    基于ssm学校运动会信息管理系统.zip

    同时,良好的异常处理机制和日志记录也是必不可少的,有助于系统故障排查和优化。 总体而言,基于SSM的学校运动会信息管理系统是一个集成了前端展示、后端业务逻辑和数据访问的综合性项目,体现了Java Web开发的...

    基于ssm小说阅读器微信小程序源码数据库文档.zip

    10. **测试与调试**:项目开发过程中,单元测试、集成测试以及性能测试都是必不可少的,以确保代码质量。微信小程序提供了调试工具,帮助开发者定位并修复问题。 综上所述,这个项目涵盖了从后端开发到前端展示的全...

    基于ssm学生就业管理系统.zip

    10. **版本控制**:项目开发过程中,版本控制工具如Git的使用必不可少,它能有效管理代码版本,便于团队协作。 总的来说,基于SSM的学生就业管理系统是一个综合性的IT项目,涵盖了后端开发、前端开发、数据库设计、...

    基于ssm焦作旅游协会管理系统.zip

    日志管理和监控工具如Log4j和Prometheus也是运维过程中必不可少的工具,它们可以帮助开发者追踪系统运行状态,及时发现并解决问题。 总之,《基于SSM的焦作旅游协会管理系统》是一个典型的Java Web项目,它融合了...

    基于ssm+vue的智能训练管理平台源码数据库文档.zip

    JUnit、Mockito、MyBatis Test等工具可能会被使用到。 这个项目涉及到的技术广泛且深入,涵盖了Java后端开发、前端开发、数据库设计以及移动应用开发等多个方面,对于学习和实践全栈开发是一个很好的案例。通过这个...

    宿舍管理课程设计java

    5. 《MySQL必知必会》:熟悉数据库操作。 通过以上步骤,我们可以完成一个完整的宿舍管理系统,满足学校对宿舍管理的需求。在实际开发过程中,要注重代码的可读性、可维护性和安全性,同时不断学习新的技术和工具,...

    基于ssm高校食堂订餐系统.zip

    - **订单处理**:用户可以浏览菜品,选择并下单,系统会处理订单状态,如待支付、已支付、准备中、已完成等。 - **支付功能**:可能集成第三方支付接口,如支付宝、微信支付,使用户能方便快捷地完成支付。 - **微信...

    基于ssm的扶贫网站设计与开发源码数据库.zip

    8. **安卓应用开发**:如果项目包含安卓客户端,那么Android SDK、布局设计、Activity管理、网络请求等是必不可少的技能。 9. **RESTful API设计**:后端通常会提供RESTful接口供前端调用,这涉及HTTP协议、状态码和...

    基于ssm+vue电子设备销售网站.zip

    12. **测试**:项目开发过程中,单元测试和集成测试必不可少,可以使用JUnit测试Java代码,Jest或Mocha测试Vue组件。 13. **部署与运维**:项目上线后,需要考虑服务器部署、负载均衡、日志监控、性能优化等问题。 ...

Global site tag (gtag.js) - Google Analytics