MyBatis学习记录

 《Java EE框架整合开发入门到实战》

   mybatis – MyBatis 3 | 简介

   如有不当,请批评指正!

目录

1,MyBatis

1.1,MyBatis简介

1.2,MyBatis工作原理

1.3, MyBatis创建流程

1.4,MyBatis与Spring的整合 

2,映射器

2.1,MyBatis配置文件概述

2.2,映射器概述

.......


1,MyBatis

1.1,MyBatis简介

     MyBatis 是一个基于Java持久层框架MyBatis提供的持久层框架包括SQL MapsData Access Objects(DAO),它消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和Java POJOsPlain Old Java Objects,普通的Java对象)映射成数据库中的记录。 

目前,Java的持久层框架产品有许多,常见的有Hibernate和MyBatis。

  MyBatis是一个半自动映射的框架,因为MyBatis需要手动匹配POJO、SQL和映射关系;

  Hibernate是一个全表映射的框架,只需提供POJO和映射关系即可。

  MyBatis是一个小巧、方便、高效、简单、直接、半自动化的持久层框架;

  Hibernate是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。

两个持久层框架各有优缺点,开发者应根据实际应用选择它们。

1.2,MyBatis工作原理


     

(1)读取MyBatis配置文件:mybatis-config.xml为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,例如数据库连接信息。

(2)加载映射文件。映射文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在MyBatis配置文件mybatis-config.xml中加载。mybatis-config.xml文件可以加载多个映射文件,每个文件对应数据库中的一张表。

(3)构造会话工厂:通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory。

(4)创建会话对象:由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法。

(5)Executor执行器:MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。

(6)MappedStatement对象:在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。

(7)输入参数映射:输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于JDBC对preparedStatement对象设置参数的过程。

(8)输出结果映射:输出结果类型可以是Map、 List等集合类型,也可以是基本数据类型和POJO类型。输出结果映射过程类似于JDBC对结果集的解析过程。

1.3, MyBatis创建流程

1.创建Web应用,并添加相关JAR包

2.创建日志文件 log4j.properties

3.创建持久化类 

     注意在类中声明的属性与数据表的字段一致

4.创建映射文件 XXXMapper.xml

     上述映射文件中,<mapper>元素是配置文件的根元素,它包含了一个namespace属性,该属性值通常设置为“包名+SQL映射文件名”,指定了唯一的命名空间。子元素<select><insert><update>以及<delete>中的信息是用于执行查询、添加、修改以及删除操作的配置。在定义的SQL语句中,“#{}”表示一个占位符,相当于“?”,而“#{uid}”表示该占位符待接收参数的名称为uid

5.创建MyBatis的配置文件

     创建核心配置文件mybatis-config.xml,在该文件中配置了数据库环境和映射文件的位置。

6.创建测试类

      在测试类中首先使用输入流读取配置文件,然后根据配置信息构建SqlSessionFactory对象。接下来通过SqlSessionFactory对象创建SqlSession对象,并使用SqlSession对象的方法执行数据库操作。

1.4,MyBatisSpring的整合 

 1.导入相关JAR

(1)MyBatis框架所需的JAR

    MyBatis框架所需的JAR包,包括它的核心包和依赖包,包的详情见6.2节。

(2)Spring框架所需的JAR

    Spring框架所需的JAR包,包括它的核心模块JARAOP开发使用的JARJDBC和事务的JAR包(其中依赖包不需要再导入,因为MyBatis已提供),具体如下:

  aopalliance-1.0.jar

  aspectjweaver-1.8.13.jar

  spring-aop-5.0.2.RELEASE.jar

  spring-aspects-5.0.2.RELEASE.jar

  spring-beans-5.0.2.RELEASE.jar

  spring-context-5.0.2.RELEASE.jar

  spring-core-5.0.2.RELEASE.jar

  spring-expression-5.0.2.RELEASE.jar

  spring-jdbc-5.0.2.RELEASE.jar

  spring-tx-5.0.2.RELEASE.jar

3MyBatisSpring整合的中间JAR

    编写本书时,该中间JAR包的最新版本为mybatis-spring-1.3.1.jar。此版本可从地址“http://mvnrepository.com/artifact/org.mybatis/mybatis-spring/1.3.1”下载。

4.数据库驱动JAR

    本书所使用的MySQL数据库驱动包为mysql-connector-java-5.1.45-bin.jar

5.数据源所需的JAR

    整合时使用的是DBCP数据源,需要准备DBCP和连接池的JAR包。编写本书时,最新版本的DBCPJAR包为commons-dbcp2-2.2.0.jar,可从地址“http://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi”下载;最新版本的连接池的JAR包为commons-pool2-2.5.0.jar,可从地址“http://commons.apache.org/proper/commons-pool/download_pool.cgi”下载。 

2.Spring中配置MyBatis工厂

    通过与Spring的整合,MyBatisSessionFactory交由Spring来构建。构建时需要在Spring的配置文件中添加如下代码: 

<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
	<property name="driverClassName" value="com.mysql.jdbc.Driver" />
	<property name="url" value="jdbc:mysql://localhost:3306/springtest?characterEncoding=utf8" />
	<property name="username" value="root" />
	<property name="password" value="root" />
	…….
</bean>
<!-- 配置MyBatis工厂,同时指定数据源,并与MyBatis完美整合 -->  
 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
      <property name="dataSource" ref="dataSource" />  
	 <!-- configLocation的属性值为MyBatis的核心配置文件 -->
	 <property name="configLocation" value="classpath:com/mybatis/mybatis-config.xml"/>
 </bean>

3.使用Spring管理MyBatis的数据操作接口

    使用Spring管理MyBatis的数据操作接口的方式有多种。其中,最常用最简洁的一种是基于MapperScannerConfigurer的整合。该方式需要在Spring的配置文件中加入以下内容:

<!--Mapper代理开发,使用Spring自动扫描MyBatis的接口并装配
 	(Spring将指定包中所有被@Mapper注解标注的接口自动装配为MyBatis的映射接口)  --> 
 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
     <!-- mybatis-spring组件的扫描器。com.dao只需要接口(接口方法与SQL映射文件中相同)-->
     <property name="basePackage" value="com.dao"/>
     <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
 </bean>

2,映射器

2.1,MyBatis配置文件概述

MyBatis的核心配置文件中的元素配置顺序不能颠倒,一旦颠倒在MyBatis启动阶段将发生异常。

2.2,映射器概述

 映射器是MyBatis最复杂且最重要的组件,由一个接口加上XML文件(SQL映射文件)组成。MyBatis的映射器也可以使用注解完成,但在实际应用中使用不广泛,原因主要来自以下几个方面:

其一,面对复杂的SQL会显得无力;

其二,注解的可读性较差;

其三,注解丢失了XML上下文相互引用的功能。因此,推荐使用XML文件开发映射器。

2.3,<select>元素

属性名称

  

id

它和Mapper的命名空间组合起来使用,是唯一标识符,供MyBatis调用

parameterType

表示传入SQL语句的参数类型的全限定名或别名。是个可选属性,MyBatis能推断出

具体传入语句的参数。

resultType

SQL语句执行后返回的类型(全限定名或者别名)。如果是集合类型,返回的是集

元素的类型。返回时可以使用resultTyperesultMap之一

resultMap

它是映射集的引用,与< resultMap>元素一起使用。返回时可以使用resultType

resultMap之一

flushCache

它的作用是在调用SQL语句后,是否要求MyBatis清空之前查询本地缓存和二级缓存。默认值为false。如果设置为true,则任何时候只要SQL语句被调用,都将清空本地缓存和二级缓存

useCache

启动二级缓存的开关。默认值为true,表示将查询结果存入二级缓存中

timeout

用于设置超时参数,单位是秒。超时将抛出异常。

fetchSize

获取记录的总条数设定

statementType

告诉MyBatis使用哪个JDBCStatement工作,取值为STATEMENTStatemen

t)、PREPAREDPreparedStatement)、CALLABLECallableStatement

resultSetType

这是针对JDBCResultSet接口而言,其值可设置为FORWARD_ONLY(只允

许向前访问)、SCROLL_SENSITIVE(双向滚动,但不及时更新)、

SCROLL_INSENSITIVE(双向滚动,及时更新)

<!-- 根据uid查询一个用户信息 -->

  <select id="selectUserById" parameterType="Integer"

  resultType="com.po.MyUser">

  select * from user where uid = #{uid}

  </select>

    上述示例代码中,id的值是唯一标识符,它接收一个Integer类型的参数,返回一个MyUser类型的对象,结果集自动映射到MyUser属性。

2.3.1,使用Map接口传递多个参数

假设数据操作接口中有个实现查询陈姓男性用户信息功能的方法:

    public List<MyUser> selectAllUser(Map<String, Object> param);

    此时,传递给映射器的是一个Map对象,使用它在SQL中设置对应的参数,对应SQL文件代码如下:

    <!-- 查询陈姓男性用户信息 -->

  <select id="selectAllUser"  resultType="com.po.MyUser" parameterType="map">

  select * from user

  where uname like concat('%',#{u_name},'%')

  and usex = #{u_sex}

  </select>

  上述SQL文件中参数名u_nameu_sexMapkey

2.3.2,使用Java Bean传递多个参数

    首先创建一个名为com.pojo的包,在包中创建一个POJOSeletUserParam

    其次,将Dao接口中的selectAllUser方法修改为:

public List<MyUser> selectAllUser(SeletUserParam param);

    再次,将SQL映射文件UserMapper.xml中的“查询陈姓男性用户信息”代码修改为:

    <select id="selectAllUser"  resultType="com.po.MyUser" parameterType="com.pojo.SeletUserParam">

  select * from user

  where uname like concat('%',#{u_name},'%')

  and usex = #{u_sex}

    </select>

    最后,将UserController的“查询多个用户”代码片段修改

在实际应用中是选择Map还是选择Java Bean传递多个参数应根据实际情况而定,如果参数较少,建议选择Map;如果参数较多,建议选择Java Bean。

2.4,<insert>元素

属性与<select>元素的属性大部分相同,几个特有属性。具体如下:

    keyProperty:该属性的作用是将插入或更新操作时的返回值赋值给PO类的某个属性,通常会设置为主键对应的属性。如果是联合主键,可以在多个值之间用逗号隔开。

    keyColumn:该属性用于设置第几列是主键,当主键列不是表中的第一列时需要设置。如果是联合主键时,可以在多个值之间用逗号隔开。

    useGeneratedKeys:该属性将使MyBatis使用JDBCgetGeneratedKeys()方法获取由数据库内部生产的主键,如MySQLSQL Server等自动递增的字段,其默认值为false

2.4.1,主键(自动递增)回填

MySQLSQL Server等数据库的表格可以采用自动递增的字段作为主键。有时可能需要使用这个刚刚产生的主键,用以关联其他业务。

<!-- 添加一个用户,成功后将主键值回填给uid(po类的属性)-->
	<insert id="addUser" parameterType="com.po.MyUser" 
	keyProperty="uid" useGeneratedKeys="true">
		insert into user (uname,usex) values(#{uname},#{usex})
	</insert>

2.4.2,自定义主键

如果实际工程中使用的数据库不支持主键自动递增(如Oracle),或者取消了主键自动递增的规则时,可以使用MyBatis<selectKey>元素来自定义生成主键。

    <insert id="insertUser" parameterType="com.po.MyUser">
	<!-- 先使用selectKey元素定义主键,然后再定义SQL语句 -->
	<selectKey keyProperty="uid" resultType="Integer" order="BEFORE">
	   select if(max(uid) is null, 1 , max(uid)+1) as newUid from user
	</selectKey>
	insert into user (uid,uname,usex) values(#{uid},#{uname},#{usex})
    </insert>

   

 

  在执行上述示例代码时,<selectKey>元素首先被执行,该元素通过自定义的语句设置数据表的主键,然后执行插入语句。<selectKey>元素的keyProperty属性指定了新生主键值返回给PO类的哪个属性。order属性可以设置为BEFORE或AFTER,BEFORE表示先执行<selectKey>元素然后执行插入语句;AFTER表示先执行插入语句再执行<selectKey>元素。 

2.5,<update><delete>元素

    <!-- 修改一个用户 -->
    <update id="updateUser" parameterType="com.po.MyUser">
	update user set uname = #{uname},usex = #{usex} where uid = #{uid}
    </update>
    <!-- 删除一个用户 -->
    <delete id="deleteUser" parameterType="Integer"> 
	delete from user where uid = #{uid}
    </delete>

2.6,<sql>元素

<sql>元素的作用在于可以定义SQL语句的一部分(代码片段),方便后面的SQL语句引用它,比如反复使用的列名。

<sql id="comColumns">uid,uname,usex</sql>
    <select id="selectUser" resultType="com.po.MyUser">
	select <include refid="comColumns"/> from user
    </select>

在上述代码中使用<include>元素的refid属性引用了自定义的代码片段。 

2.7,<resultMap>元素

<resultMap>元素表示结果映射集,是MyBatis中最重要也是最强大的元素。主要用来定义映射规则、级联的更新以及定义类型转化器等。

2.7.1,<resultMap>元素结构

<resultMap type="" id="">
    <constructor><!-- 类在实例化时,用来注入结果到构造方法 -->
	<idArg/><!-- ID参数,结果为ID -->
	<arg/><!-- 注入到构造方法的一个普通结果 -->
    </constructor>
    <id/><!-- 用于表示哪个列是主键 -->
    <result/><!-- 注入到字段或JavaBean属性的普通结果 -->
    <association property=""/><!-- 用于一对一关联 -->
    <collection property=""/><!-- 用于一对多、多对多关联 -->
    <discriminator javaType=""><!-- 使用结果值来决定使用哪个结果映射 -->
        <case value=""/>	<!-- 基于某些值的结果映射 -->
    </discriminator>
</resultMap>

 <resultMap>元素的type属性表示需要的POJOid属性是resultMap的唯一标识。

子元素<constructor>用于配置构造方法(当POJO未定义无参数的构造方法时使用)。

子元素<id>用于表示哪个列是主键。

子元素<result>用于表示POJO和数据表普通列的映射关系。子元素<association> <collection> <discriminator>是用在级联的情况下。

2.7.2,使用Map存储结果集

任何select语句可以使用Map存储结果,示例代码如下:

	<!-- 查询所有用户信息存到Map中 -->
	<select id="selectAllUserMap"  resultType="map">
		select * from user 
	</select>

测试上述SQL配置文件的过程如下:

首先在Dao接口中添加以下接口方法

然后在Controller类中调用接口方法

 上述Map的key是select语句查询的字段名(必须完全一样),而Map的value是查询返回结果中字段对应的值,一条记录映射到一个Map对象中。Map用起来很方便,但可读性稍差,有的开发者不太喜欢使用Map,更多时候喜欢使用POJO的方式。 

2.7.3,使用POJO存储结果集

POJO的方式存储结果集,一方面可以使用自动映射,例如使用resultType属性,但有时候需要更为复杂的映射或级联,这时候就需要使用<select>元素的resultMap属性配置映射集合。

	<!-- 使用自定义结果集类型 -->
	<resultMap type="com.pojo.MapUser" id="myResult">
		<!-- property是com.pojo.MapUser类中的属性-->
		<!-- column是查询结果的列名,可以来自不同的表 -->
		<id property="m_uid" column="uid"/>
		<result property="m_uname" column="uname"/>
		<result property="m_usex" column="usex"/>
	</resultMap>
	<!-- 使用自定义结果集类型查询所有用户 -->
	<select id="selectResultMap" resultMap="myResult">
		select * from user
	</select>

2.8,级联关系

      级联的优点是获取关联数据十分方便,但是级联过多会增加数据库系统的复杂度,同时降低系统的性能。在实际开发中要根据实际情况判断是否需要使用级联。更新和删除的级联关系很简单,由数据库内在机制即可完成。

2.8.1,一对一级联查询

        通过<resultMap>元素的子元素<association>处理这种一对一级联关系。在<association>元素中,通常使用以下属性。

property:指定映射到实体类的对象属性。

column:指定表中对应的字段(即查询返回的列名)。

javaType:指定映射到实体对象属性的类型。

           select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询。

            

2.8.2,一对多级联查询

2.8.3,多对多级联查询

其实,MyBatis没有实现多对多级联,这是因为多对多级联可以通过两个一对多级联进行替换。

3,动态SQL 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值