mybatis教程(二):概念总结

一、注意规范

注意:(1).XXXmapper.xml 文件中的 namespace 等于mapper 接口地址

           (2).XXXmapper.java 接口中的方法输入参数和 mapper.xml 中statement的parameterType指定的  类型一致。

           (3) .mapper.java 接口中的方法的返回值类型和mapper.xml中statement的resultType指定的类型一致

 

二、配置文件及标签介绍

1. properties 介绍

可以将数据连接单独配置在 db.properties 中改善硬编码,其他配置文件引用该文件。内容示例:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root

 

2.核心配置 SqlMapConfig.xml 标签介绍

标签种类:

        1. properties(属性)

<!-- 加载数据库文件db.properties -->
<properties resource="db.properties">
    <!-- 
            properties中还可以配置一些属性名和属性值,此处的优先加载 
            读取完此标签内再读取其他文件。如果有同名属性,则会被读取文件中的覆盖
    -->
    <!-- <property name="driver" value=""/> -->
</properties>

      2. settings(全局配置参数): 可以调整一些运行参数:开启二级缓存、开启延迟加载等。会影响mybatis的运动行为

      3. typeAiases(类型别名):指定输入输出类型较不方便,可以针对 parameterType、resourceType 指定的类型定义一些别名

      3.1 默认支持的别名

别名 _byte _long _short _int _integer _double _float _boolean string byte
类型 byte long short int int doouble float boolean String Byte
别名 long short int integer double float boolean data decimal bigdecimal
类型 Long Short Integer Integer Double Float Boolean Data BigDecimal BigDecimal

      3.2 自定义别名

<!-- 针对单个别名定义 type:类型的路径; alias:别名 -->
<typeAliases>
        <typeAlias type="com.mybatis.entity.User" alias="user"/>
</typeAliases>

<select id="findUserById" parameterType="int" resultType="user" >
      select * from t_user where id=#{id}
</select>


<!-- 批量别名的定义:
        package:指定包名,mybatis会自动扫描包中的pojo类,自动定义别名,别名就是类名(首字母大写或小写都可以)
 -->
<typeAliases>
         <package name="com.mybatis.entity"/>
         <package name="其它包"/>
 </typeAliases>

        4. typeHandlers(类型处理器):完成 jdbc 类型和 java 类型的转换

        5. objectFactory(对象工厂)

        6. plugins(插件)

        7. environments(环境集合属性对象)mappers(映射器)

                 7.1 environment (环境子属性对象)

                 7.2 transactionManager(事务管理)

                7.3 datasource(数据源)

<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
    <environment id="development">
        <!-- 使用jdbc事务管理,事务控制由mybatis管理-->
        <transactionManager type="JDBC" />
        <!-- 数据库连接池,由mybatis管理-->
        <dataSource type="POOLED">
                 <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
         </dataSource>
    </environment>
</environments>

        8.mapper(映射器)

<!-- 加载映射文件 -->
<mappers>

    <!--  通过resource方法一次加载一个映射文件  -->
        <mapper resource="sqlmap/User.xml"/>
        <mapper resource="mapper/UserMapper.xml"/>


    <!--   通过mapper接口加载单个映射配置文件
           需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中
      -->
         <mapper class="com.mybatis.mapper.UserMapper"/> 


    <!-- 批量加载映射配置文件,mybatis自动扫描包下面的mapper接口进行加载
           需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中;
            上边规范的前提是:使用的是mapper代理方法;
      -->
         <package name="com.mybatis.mapper"/> 

</mappers>

 

三、输入、输出 映射

1.输入映射:通过 parameterType 指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型

        如需要查询的条件较复杂,可以使用自定义的包装类型 pojo ,将复杂的查询条件包含进去

1.1 复杂的包装类 UserQueryVo 示例

public class UserQueryVo {

     //这里包装其它的查询条件
     //用户查询条件
     private UserCustom userCustom;
 

     public UserCustom getUserCustom() {
         return userCustom;
     }
 
     public void setUserCustom(UserCustom userCustom) {
         this.userCustom = userCustom;
     }
 
 }

 

1.2 再复杂一下 UserCustom.java 示例

public class UserCustom extends User{
    //可以扩展用户的信息
}

 

1.3 配置文件 UserMapper.xml 定义综合查询示例

<!-- 模拟包装类型组合查询 
    #{userCustom.sex}:取出pojo包装对象中性别值
    ${userCustom.username}:取出pojo对象中姓名值
-->
    <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" 
         resultType="com.mybatis.entity.UserCustom">
        where sex=#{userCustom.sex} and username LIKE '%${userCustom.username}%'
    </select>

 

1.4 UserMapper.java 示例

public interface UserMapper {
    // 用户信息综合查询
    public List<UserCustom> findUserList(UserQueryVo userQueryVo);
}

 

1.5  Junit 测试代码

 1 ackage com.mybatis.dao.test;
 2 
 3 import java.io.InputStream;
 4 import java.util.Date;
 5 import java.util.List;
 6 
 7 import org.apache.ibatis.io.Resources;
 8 import org.apache.ibatis.session.SqlSession;
 9 import org.apache.ibatis.session.SqlSessionFactory;
10 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
11 import org.junit.Before;
12 import org.junit.Test;
13 
14 import com.mybatis.entity.User;
15 import com.mybatis.entity.UserCustom;
16 import com.mybatis.entity.UserQueryVo;
17 import com.mybatis.mapper.UserMapper;
18 
19 public class UserMapperTest {
20 
21     private SqlSessionFactory sqlSessionFactory;
22 
23     // 此方法是在执行findUserByIdTest之前执行
24     @Before
25     public void setUp() throws Exception {
26         String resource = "SqlMapConfig.xml";
27         InputStream inputStream = Resources.getResourceAsStream(resource);
28         // 创建SqlSessionFcatory
29         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
30     }
31     
32     @Test
33     public void testFindUserList() {
34         SqlSession sqlSession = sqlSessionFactory.openSession();
35         //创造查询条件
36         UserQueryVo userQueryVo = new UserQueryVo();
37         UserCustom userCustom = new UserCustom();
38         userCustom.setSex("2");
39         userCustom.setUsername("小");
40         userQueryVo.setUserCustom(userCustom);
41         // 创建Usermapper对象,mybatis自动生成mapper代理对象
42         UserMapper mapper = sqlSession.getMapper(UserMapper.class);
43         List<UserCustom>list=mapper.findUserList(userQueryVo);
44         System.out.println(list);
45         sqlSession.commit();
46         sqlSession.close();
47     }
48 }
UserMapperTest

 

 

2.输出映射:只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功

    (如果查询出来的列名和 pojo 中属性名只要有一个一致,就会创建 pojo 对象,只有全部不一样才会不创建对象)

2.1 输出简单类型:只有输出的结果只有一行一列才可以使用

2.1.1 UserMapper.xml 

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

<!-- 用户信息综合查询总数
     parameterType:指定输入类型,和findUserList一致。
     resultType:输出结果类型.    
  -->
<mapper namespace="com.mybatis.mapper.UserMapper">
    <select id="findUserCount" parameterType="com.mybatis.entity.UserQueryVo" resultType="int">
        select count(*) from t_user where  sex=#{userCustom.sex} and username like '%${userCustom.username}%'
    </select>
</mapper>

 

2.1.2 UserMapper.java

 public interface UserMapper {
     //用户信息综合查询总数
     public int findUserCount(UserQueryVo userQueryVo);
 }

 

2.1.3 junit 测试

 1 package com.mybatis.dao.test;
 2 
 3 import java.io.InputStream;
 4 import java.util.Date;
 5 import java.util.List;
 6 
 7 import org.apache.ibatis.io.Resources;
 8 import org.apache.ibatis.session.SqlSession;
 9 import org.apache.ibatis.session.SqlSessionFactory;
10 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
11 import org.junit.Before;
12 import org.junit.Test;
13 
14 import com.mybatis.entity.User;
15 import com.mybatis.entity.UserCustom;
16 import com.mybatis.entity.UserQueryVo;
17 import com.mybatis.mapper.UserMapper;
18 
19 public class UserMapperTest {
20 
21     private SqlSessionFactory sqlSessionFactory;
22 
23     // 此方法是在执行findUserByIdTest之前执行
24     @Before
25     public void setUp() throws Exception {
26         String resource = "SqlMapConfig.xml";
27         InputStream inputStream = Resources.getResourceAsStream(resource);
28         // 创建SqlSessionFcatory
29         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
30     }
31     
32     @Test
33     public void findUserCountTest() {
34         SqlSession sqlSession = sqlSessionFactory.openSession();
35         //创造查询条件
36         UserQueryVo userQueryVo = new UserQueryVo();
37         UserCustom userCustom = new UserCustom();
38         userCustom.setSex("2");
39         userCustom.setUsername("小");
40         userQueryVo.setUserCustom(userCustom);
41         // 创建Usermapper对象,mybatis自动生成mapper代理对象
42         UserMapper mapper = sqlSession.getMapper(UserMapper.class);
43         int count=mapper.findUserCount(userQueryVo);
44         System.out.println(count);
45         sqlSession.commit();
46         sqlSession.close();
47     }
48 }
UserMapperTest

 

2.2 输出 pojo 对象和 pojo 列表:单个或列表,在 mapperType 类型是一样的,在 mapper.java 中返回值不一样

2.2.1 方法返回值区别示例

 public interface UserMapper {
    
     /** 根据ID查询用户信息 */
    // 返回单个
     public User findUserById(int id);

     /** 根据用户名称模糊查询用户信息 */
    // 返回列表
     public List<User> findUserByName(String username);

 }

 

2.2.2 使用 resoultMap 作为输出映射类型

        定义 resoultMap

<?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">
  <!-- namespace命名空间,作用就是对sql进行分类化的管理,理解为sql隔离
    注意:使用mapper代理开发时,namespace有特殊作用,namespace等于mapper接口地址
  -->
   <!-- 用户信息综合查询总数
     parameterType:指定输入类型,和findUserList一致。
      resultType:输出结果类型.    
   -->
 <mapper namespace="com.mybatis.mapper.UserMapper">
 <!-- 定义resultMap 
     select id id_,username username_ from t_user和User类中的属性作为一个映射关系
    type:resultMap最终映射的java对象类型,可以使用别名;
     id:对resultMap的唯一标识
 -->
 <resultMap type="user" id="userResultMap">
     <!--id表示查询结果中的唯一标识,
         column:查询出来的列名
         property:type指定的pojo类型中的属性名
        最终resultMap对column和property作一个映射关系(对应关系)
      -->
     <id column="id_" property="id"/>
     <!--result:表示对普通列名的映射,
        column:查询出来的列名
       property:type指定的pojo类型中的属性名
         最终resultMap对column和property作一个映射关系(对应关系)
       -->
     <result column="username_" property="username"/>
 </resultMap>
 </mapper>

 

        使用 resoultMap 

<!-- 使用resultMap作为输出映射
    resultMap:指定定义的resultMap的id,如果这个resultMap在其它的mapper.xml文件中,前边需要添加namespace命名空间
 -->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap" >
    select id id_,username username_ from t_user where id=#{id}
</select>

 

        UserMapper.java示例

public interface UserMapper {

    /** 根据ID查询用户信息,使用resultMap进行输出 */
    public User findUserByIdResultMap(int id);
}

 

        Junit 测试示例

 1 package com.mybatis.dao.test;
 2 
 3 import java.io.InputStream;
 4 import java.util.Date;
 5 import java.util.List;
 6 
 7 import org.apache.ibatis.io.Resources;
 8 import org.apache.ibatis.session.SqlSession;
 9 import org.apache.ibatis.session.SqlSessionFactory;
10 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
11 import org.junit.Before;
12 import org.junit.Test;
13 
14 import com.mybatis.entity.User;
15 import com.mybatis.entity.UserCustom;
16 import com.mybatis.entity.UserQueryVo;
17 import com.mybatis.mapper.UserMapper;
18 
19 public class UserMapperTest {
20 
21     private SqlSessionFactory sqlSessionFactory;
22 
23     // 此方法是在执行findUserByIdTest之前执行
24     @Before
25     public void setUp() throws Exception {
26         String resource = "SqlMapConfig.xml";
27         InputStream inputStream = Resources.getResourceAsStream(resource);
28         // 创建SqlSessionFcatory
29         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
30     }
31     
32     @Test
33     public void testFindUserByIdResultMap() {
34         SqlSession sqlSession = sqlSessionFactory.openSession();
35         // 创建Usermapper对象,mybatis自动生成mapper代理对象
36         UserMapper mapper = sqlSession.getMapper(UserMapper.class);
37         User user = mapper.findUserByIdResultMap(1);
38         System.out.println(user);
39         sqlSession.close();
40     }
41 }
UserMapperTest

 

2.3 用 resultType 进行输出映射时,只有查询出来的列名和 pojo 中的属性名一致,该列才可以映射成功。如果不一致,可以通过定义一个 resultType 对列名和 pojo 属性名之间作为一个映射关系

 

四、

1.动态SQL:mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对SQL进行拼接、组装

        UserMapper.xml、Junit测试代码示例:

 1 <!-- 用户信息综合查询 
 2     #{userCustom.sex}:取出pojo包装对象中性别值
 3     ${userCustom.username}:取出pojo对象中用户名称
 4 -->
 5     <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" 
 6     resultType="com.mybatis.entity.UserCustom">
 7         select * from t_user 
 8         <!-- 动态sql查询:where可以自动去掉第一个and -->
 9         <where>
10             <if test="userCustom!=null">
11                 <if test="userCustom.sex!=null and userCustom.sex!='' ">
12                     and sex=#{userCustom.sex}
13                 </if>
14                 <if test="userCustom.username!=null and userCustom.username!='' ">
15                     and username=#{userCustom.username}
16                 </if>
17             </if>
18         </where>
19 <!--          where sex=#{userCustom.sex} and username LIKE '%${userCustom.username}%' -->
20     </select>
UserMapper.xml

 

 1 @Test
 2     public void testFindUserList() {
 3         SqlSession sqlSession = sqlSessionFactory.openSession();
 4         //创造查询条件
 5         UserQueryVo userQueryVo = new UserQueryVo();
 6         UserCustom userCustom = new UserCustom();
 7 //        userCustom.setSex("2");
 8         //这里使用动态sql,如果不设置某个值,条件不会拼接sql中
 9         userCustom.setUsername("小");
10         userQueryVo.setUserCustom(userCustom);
11         // 创建Usermapper对象,mybatis自动生成mapper代理对象
12         UserMapper mapper = sqlSession.getMapper(UserMapper.class);
13         List<UserCustom>list=mapper.findUserList(userQueryVo);
14         //测试动态sql,属性的非空判断测试
15 //        List<UserCustom>list=mapper.findUserList(null);
16         System.out.println(list);
17         sqlSession.commit();
18         sqlSession.close();
19     }
testFindUserList

 

 

2. SQL片段:抽取动态sql,组成一个sql片段,方便重复调用

2.1 定义sql片段

<!-- 定义sql片段,Id是唯一标识
         建议:是基于单表来定义sql片段,这样的话sql片段的可重用性才高,在sql片段中不要包含where
     -->
    <sql id="query_user_where" >
        <if test="userCustom!=null">
                <if test="userCustom.sex!=null and userCustom.sex!='' ">
                    and sex=#{userCustom.sex}
                </if>
               <if test="userCustom.username!=null and userCustom.username!='' ">
                    and username=#{userCustom.username}
                </if>
            </if>
    </sql>

 

2.2 在 mapper.xml 中定义的 statement 中引用sql片段

<!-- 用户信息综合查询 
    #{userCustom.sex}:取出pojo包装对象中性别值
    ${userCustom.username}:取出pojo对象中用户名称
-->
    <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" 
    resultType="com.mybatis.entity.UserCustom">
        select * from t_user 
        <!-- 动态sql查询:where可以自动去掉第一个and -->
        <where>
        <!-- 引用sql片段的id,如果refid指定的不在本mapper.xml中,需要前边加namespace -->
            <include refid="query_user_where"></include>
            <!-- 这里可以引用其它的sql片段 -->
        </where>
    </select>

 

 

3. foreach:向 sql 传递数组或 list 时,mybatis 使用 foreach 解析

3.1 传入多个id的

 1 package com.mybatis.entity;
 2 
 3 import java.util.List;
 4 
 5 /**
 6  * 
 7  * @ClassName: UserQueryVo
 8  * @Description: TODO(包装类型)
 9  * @author warcaft
10  * 
11  */
12 public class UserQueryVo {
13 
14     public List<Integer> ids;
15 
16     public List<Integer> getIds() {
17         return ids;
18     }
19 
20     public void setIds(List<Integer> ids) {
21         this.ids = ids;
22     }
23 }
UserQueryVo .java

 

3.2 mapper.xml :实现两条不同sql示例

 1 <!-- 实现下边的sql拼接
 2             select * from t_user where id=1 OR id=2 OR id=3
 3     -->
 4     <select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo" 
 5     resultType="com.mybatis.entity.User">
 6             select * from t_user
 7         <where>
 8                 <if test="ids!=null">
 9                 <!-- 使用foreach遍历ids
10                     collection:指定输入对象的集合属性
11                     item:每个遍历生成对象中
12                     open:开始遍历时拼接的串
13                     close:技术遍历时拼接的串
14                     separator:遍历的两个对象中需要拼接的串
15                  -->
16                 <foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
17                     id=#{user_id}
18                 </foreach>
19             </if>
20         </where>
21     </select>
mapper.xml
 1 <!-- 实现下边的sql拼接
 2             select * from t_user whereid in(1,2,3)
 3  -->
 4 
 5 <select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo" 
 6     resultType="com.mybatis.entity.User">
 7             select * from t_user
 8         <where>
 9                 <if test="ids!=null">
10                 <!-- 
11                     使用foreach遍历ids
12                     collection:指定输入对象的集合属性
13                     item:每个遍历生成对象中
14                     open:开始遍历时拼接的串
15                     close:技术遍历时拼接的串
16                     separator:遍历的两个对象中需要拼接的串
17                  -->
18                 <!-- 实现“ select * from t_user where  id in(1,2,3)”拼接 -->
19                 <foreach collection="ids" item="user_id" open="AND id in ("  close=")" separator=",">
20                     id=#{user_id}
21                 </foreach>
22             </if>
23         </where>
24     </select>
mapper.xml

 

3.3 UserMapper.java 示例

1  public interface UserMapper {
2      //ids查询用户数据
3      public List<User> findUserByIds(UserQueryVo userQueryVo);
4  }

3.4 Junit 测试代码示例

 1 @Test
 2     public void findUserByIdsTest() {
 3         SqlSession sqlSession = sqlSessionFactory.openSession();
 4         // 创建Usermapper对象,mybatis自动生成mapper代理对象
 5         UserMapper mapper = sqlSession.getMapper(UserMapper.class);
 6         //创造查询条件
 7         UserQueryVo userQueryVo = new UserQueryVo();
 8         //传入多个id
 9         List<Integer> ids=new ArrayList<Integer>();
10         ids.add(1);
11         ids.add(2);
12         ids.add(3);
13         //将ids通过userQueryVo传入statement中
14         userQueryVo.setIds(ids);
15         //调用userMapper的代码
16         List<UserCustom> userList= mapper.findUserList(userQueryVo);
17         System.out.println(userList);
18         sqlSession.close();
19     }
findUserByIdTest.java

 

最后:这两篇随笔参考和引用了传智播客的资料和代码,尤其是(二),写的时候比较匆忙。写这两篇仅仅是为了便于自己以后查阅而已。

posted @ 2018-01-31 21:59  大概是个小学生  阅读(771)  评论(0编辑  收藏  举报