mybatis分享

Mybatis入门

一、Mybatis环境搭建及简单实例

pom.xml

mybatis-config.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4   "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6 
 7   <!-- 指定properties配置文件, 我这里面配置的是数据库相关 -->
 8   <properties resource="dbConfig.properties"></properties>
 9       
10   <environments default="development">
11     <environment id="development">
12       <transactionManager type="JDBC"/>
13       <dataSource type="POOLED">
14           <!--
15           如果上面没有指定数据库配置的properties文件,那么此处可以这样直接配置 
16         <property name="driver" value="com.mysql.jdbc.Driver"/>
17         <property name="url" value="jdbc:mysql://localhost:3306/test1"/>
18         <property name="username" value="root"/>
19         <property name="password" value="root"/>
20          -->
21          
22          <!-- 上面指定了数据库配置文件, 配置文件里面也是对应的这四个属性 -->
23          <property name="driver" value="${driver}"/>
24          <property name="url" value="${url}"/>
25          <property name="username" value="${username}"/>
26          <property name="password" value="${password}"/>
27          
28       </dataSource>
29     </environment>
30   </environments>
31   
32   <!-- 映射文件,mybatis精髓, 后面才会细讲 -->
33   <mappers>
34     <mapper resource="com/dy/dao/userDao-mapping.xml"/>
35   </mappers>
36   
37 </configuration>

1. configuration节点为根节点。

2. 在configuration节点之下,我们可以配置10个子节点, 分别为:properties、typeAliases、plugins、objectFactory、objectWrapperFactory、settings、environments、databaseIdProvider、typeHandlers、mappers。

实体类——User

properties的使用方法

envirements元素节点的使用方法

environments元素节点可以配置多个environment子节点, 怎么理解呢? 

  假如我们系统的开发环境和正式环境所用的数据库不一样(这是肯定的), 那么可以设置两个environment, 两个id分别对应开发环境(dev)和正式环境(final),那么通过配置environments的default属性就能选择对应的environment了, 例如,我将environments的deault属性的值配置为dev, 那么就会选择dev的environment。

typeAliases

typeHandler

Mybatis中的TypeHandler是什么?

  无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成 Java 类型。Mybatis默认为我们实现了许多TypeHandler, 当我们没有配置指定TypeHandler时,Mybatis会根据参数或者返回结果的不同,默认为我们选择合适的TypeHandler处理。

配置typeHandler

 1 <configuration>
 2     <typeHandlers>
 3       <!-- 
 4           当配置package的时候,mybatis会去配置的package扫描TypeHandler
 5           <package name="com.dy.demo"/>
 6        -->
 7       
 8       <!-- handler属性直接配置我们要指定的TypeHandler -->
 9       <typeHandler handler=""/>
10       
11       <!-- javaType 配置java类型,例如String, 如果配上javaType, 那么指定的typeHandler就只作用于指定的类型 -->
12       <typeHandler javaType="" handler=""/>
13       
14       <!-- jdbcType 配置数据库基本数据类型,例如varchar, 如果配上jdbcType, 那么指定的typeHandler就只作用于指定的类型  -->
15       <typeHandler jdbcType="" handler=""/>
16       
17       <!-- 也可两者都配置 -->
18       <typeHandler javaType="" jdbcType="" handler=""/>
19       
20   </typeHandlers>
21   
22   ......
23   
24 </configuration>

objectFactory是干什么的? 需要配置吗?

  MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。默认情况下,我们不需要配置,mybatis会调用默认实现的objectFactory。 除非我们要自定义ObjectFactory的实现, 那么我们才需要去手动配置。

plugin有何作用? 需要配置吗?

  plugins 是一个可选配置。mybatis中的plugin其实就是个interceptor, 它可以拦截Executor 、ParameterHandler 、ResultSetHandler 、StatementHandler 的部分方法,处理我们自己的逻辑。Executor就是真正执行sql语句的东西, ParameterHandler 是处理我们传入参数的,还记得前面讲TypeHandler的时候提到过,mybatis默认帮我们实现了不少的typeHandler, 当我们不显示配置typeHandler的时候,mybatis会根据参数类型自动选择合适的typeHandler执行,其实就是ParameterHandler 在选择。ResultSetHandler 就是处理返回结果的。

mappers作用 ? 需要配置吗?

  mappers 节点下,配置我们的mapper映射文件, 所谓的mapper映射文件,就是让mybatis 用来建立数据表和javabean映射的一个桥梁。在我们实际开发中,通常一个mapper文件对应一个dao接口, 这个mapper可以看做是dao的实现。所以,mappers必须配置。

mapper映射文件配置之insert、update、delete

 1 <?xml version="1.0" encoding="UTF-8" ?>   
 2 <!DOCTYPE mapper   
 3 PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"  
 4 "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"> 
 5 
 6 <!-- mapper 为根元素节点, 一个namespace对应一个dao -->
 7 <mapper namespace="com.dy.dao.UserDao">
 8 
 9     <insert
10       <!-- 1. id (必须配置)
11         id是命名空间中的唯一标识符,可被用来代表这条语句。 
12         一个命名空间(namespace) 对应一个dao接口, 
13         这个id也应该对应dao里面的某个方法(相当于方法的实现),因此id 应该与方法名一致 -->
14       
15       id="insertUser"
16       
17       <!-- 2. parameterType (可选配置, 默认为mybatis自动选择处理)
18         将要传入语句的参数的完全限定类名或别名, 如果不配置,mybatis会通过ParameterHandler 根据参数类型默认选择合适的typeHandler进行处理
19         parameterType 主要指定参数类型,可以是int, short, long, string等类型,也可以是复杂类型(如对象) -->
20       
21       parameterType="com.demo.User"
22       
23       <!-- 3. flushCache (可选配置,默认配置为true)
24         将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句) -->
25       
26       flushCache="true"
27       
28       <!-- 4. statementType (可选配置,默认配置为PREPARED)
29         STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 -->
30       
31       statementType="PREPARED"
32       
33       <!-- 5. keyProperty (可选配置, 默认为unset)
34         (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 -->
35       
36       keyProperty=""
37       
38       <!-- 6. keyColumn     (可选配置)
39         (仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 -->
40       
41       keyColumn=""
42       
43       <!-- 7. useGeneratedKeys (可选配置, 默认为false)
44         (仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。  -->
45       
46       useGeneratedKeys="false"
47       
48       <!-- 8. timeout  (可选配置, 默认为unset, 依赖驱动)
49         这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。 -->
50       timeout="20">
51 
52     <update
53       id="updateUser"
54       parameterType="com.demo.User"
55       flushCache="true"
56       statementType="PREPARED"
57       timeout="20">
58 
59     <delete
60       id="deleteUser"
61       parameterType="com.demo.User"
62       flushCache="true"
63       statementType="PREPARED"
64       timeout="20">
65 </mapper>

如果我们在使用mysql的时候,想在数据插入后返回插入的id, 我们也可以使用 selectKey 这个元素:

 1 <!-- 对应userDao中的insertUser方法,  -->
 2    <insert id="insertUser" parameterType="com.dy.entity.User">
 3            <!-- oracle等不支持id自增长的,可根据其id生成策略,先获取id 
 4            
 5         <selectKey resultType="int" order="BEFORE" keyProperty="id">
 6               select seq_user_id.nextval as id from dual
 7         </selectKey>
 8         
 9         --> 
10         
11         <!-- mysql插入数据后,获取id -->
12         <selectKey keyProperty="id" resultType="int" order="AFTER" >
13                SELECT LAST_INSERT_ID() as id
14            </selectKey>
15           
16            insert into user(id, name, password, age, deleteFlag) 
17                values(#{id}, #{name}, #{password}, #{age}, #{deleteFlag})
18    </insert>

mapper映射文件配置之select、resultMap

select配置

 1 <select
 2         <!--  1. id (必须配置)
 3         id是命名空间中的唯一标识符,可被用来代表这条语句。 
 4         一个命名空间(namespace) 对应一个dao接口, 
 5         这个id也应该对应dao里面的某个方法(相当于方法的实现),因此id 应该与方法名一致  -->
 6      
 7      id="selectPerson"
 8      
 9      <!-- 2. parameterType (可选配置, 默认为mybatis自动选择处理)
10         将要传入语句的参数的完全限定类名或别名, 如果不配置,mybatis会通过ParameterHandler 根据参数类型默认选择合适的typeHandler进行处理
11         parameterType 主要指定参数类型,可以是int, short, long, string等类型,也可以是复杂类型(如对象) -->
12      parameterType="int"
13      
14      <!-- 3. resultType (resultType 与 resultMap 二选一配置)
15          resultType用以指定返回类型,指定的类型可以是基本类型,可以是java容器,也可以是javabean -->
16      resultType="hashmap"
17      
18      <!-- 4. resultMap (resultType 与 resultMap 二选一配置)
19          resultMap用于引用我们通过 resultMap标签定义的映射类型,这也是mybatis组件高级复杂映射的关键 -->
20      resultMap="personResultMap"
21      
22      <!-- 5. flushCache (可选配置)
23          将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false -->
24      flushCache="false"
25      
26      <!-- 6. useCache (可选配置)
27          将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true -->
28      useCache="true"
29      
30      <!-- 7. timeout (可选配置) 
31          这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)-->
32      timeout="10000"
33      
34      <!-- 8. fetchSize (可选配置) 
35          这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)-->
36      fetchSize="256"
37      
38      <!-- 9. statementType (可选配置) 
39          STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED-->
40      statementType="PREPARED"
41      
42      <!-- 10. resultSetType (可选配置) 
43          FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)-->
44      resultSetType="FORWARD_ONLY">

resultMap配置

 1 <!-- 
 2         1.type 对应类型,可以是javabean, 也可以是其它
 3         2.id 必须唯一, 用于标示这个resultMap的唯一性,在使用resultMap的时候,就是通过id指定
 4      -->
 5     <resultMap type="" id="">
 6     
 7         <!-- id, 唯一性,注意啦,这个id用于标示这个javabean对象的唯一性, 不一定会是数据库的主键(不要把它理解为数据库对应表的主键) 
 8             property属性对应javabean的属性名,column对应数据库表的列名
 9             (这样,当javabean的属性与数据库对应表的列名不一致的时候,就能通过指定这个保持正常映射了)
10         -->
11         <id property="" column=""/>
12         
13         <!-- result与id相比, 对应普通属性 -->    
14         <result property="" column=""/>
15         
16         <!-- 
17             constructor对应javabean中的构造方法
18          -->
19         <constructor>
20             <!-- idArg 对应构造方法中的id参数 -->
21             <idArg column=""/>
22             <!-- arg 对应构造方法中的普通参数 -->
23             <arg column=""/>
24         </constructor>
25         
26         <!-- 
27             collection,对应javabean中容器类型, 是实现一对多的关键 
28             property 为javabean中容器对应字段名
29             column 为体现在数据库中列名
30             ofType 就是指定javabean中容器指定的类型
31         -->
32         <collection property="" column="" ofType=""></collection>
33         
34         <!-- 
35             association 为关联关系,是实现N对一的关键。
36             property 为javabean中容器对应字段名
37             column 为体现在数据库中列名
38             javaType 指定关联的类型
39          -->
40         <association property="" column="" javaType=""></association>
41     </resultMap>

强大的动态SQL

那么,问题来了: 什么是动态SQL? 动态SQL有什么作用?

  传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。

if

1 <select id="findUserById" resultType="user">
2            select * from user where 
3            <if test="id != null">
4                id=#{id}
5            </if>
6             and deleteFlag=0;
7 </select>

有问题?

where

1 <select id="findUserById" resultType="user">
2            select * from user 
3            <where>
4                <if test="id != null">
5                    id=#{id}
6                </if>
7                and deleteFlag=0;
8            </where>
9  </select>

从表面上来看,就是多了个where标签而已, 不过实质上, mybatis是对它做了处理,当它遇到AND或者OR这些,它知道怎么处理。其实我们可以通过 trim 标签去自定义这种处理规则。

trim

上面的where标签,其实可以用trim表示:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
</trim>

set

 1 <update id="updateUser" parameterType="com.dy.entity.User">
 2            update user set 
 3            <if test="name != null">
 4                name = #{name},
 5            </if> 
 6            <if test="password != null">
 7                password = #{password},
 8            </if> 
 9            <if test="age != null">
10                age = #{age}
11            </if> 
12            <where>
13                <if test="id != null">
14                    id = #{id}
15                </if>
16                and deleteFlag = 0;
17            </where>
18 </update>
 1 <update id="updateUser" parameterType="com.dy.entity.User">
 2            update user
 3         <set>
 4           <if test="name != null">name = #{name},</if> 
 5              <if test="password != null">password = #{password},</if> 
 6              <if test="age != null">age = #{age},</if> 
 7         </set>
 8            <where>
 9                <if test="id != null">
10                    id = #{id}
11                </if>
12                and deleteFlag = 0;
13            </where>
14 </update>

这个用trim 可表示为:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

foreach

1 <select id="selectPostIn" resultType="domain.blog.Post">
2   SELECT *
3   FROM POST P
4   WHERE ID in
5   <foreach item="item" index="index" collection="list"
6       open="(" separator="," close=")">
7         #{item}
8   </foreach>
9 </select>

choose

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

SqlSessionFactory与sqlsession

从表面上来看,咱们都是通过SqlSession去执行sql语句。那么咱们就先看看是怎么获取SqlSession的吧:

 1 SqlSessionFactory sessionFactory = null;  
 2 String resource = "mybatis-conf.xml";  
 3 try {
 4      //SqlSessionFactoryBuilder读取配置文件
 5     sessionFactory = new SqlSessionFactoryBuilder().build(Resources  
 6               .getResourceAsReader(resource));
 7 } catch (IOException e) {  
 8     e.printStackTrace();  
 9 }    
10 //通过SqlSessionFactory获取SqlSession
11 SqlSession sqlSession = sessionFactory.openSession();

SqlSession咱们也拿到了,咱们可以调用SqlSession中一系列的select...,  insert..., update..., delete...方法轻松自如的进行CRUD操作了。 就这样? 那咱配置的映射文件去哪儿了?  别急, 咱们接着往下看:

2. 利器之MapperProxy:

在mybatis中,通过MapperProxy动态代理咱们的dao, 也就是说, 当咱们执行自己写的dao里面的方法的时候,其实是对应的mapperProxy在代理。

原文地址:https://www.cnblogs.com/lijia0511/p/5774080.html