【MyBatis】的入门程序和配置文件详解

1.Mybatis的介绍
mybatis就是一个封装jdbc的持久层框架,它和hibernate都属于ORM框架,但是具体的说,hibernate是一个完全的orm框架,而mybatis是一个不完全的orm框架。mybatis让程序员只关注sql本身,而不需要去关注如连接的创建、statement的创建等操作。mybatis会将输入参数、输出结果进行映射。

2.Mybatis的框架原理
这里写图片描述

3.下载Mybatis
mybaits的代码由github.com管理,下载地址:https://github.com/mybatis/mybatis-3/releases
这里写图片描述

4.入门程序

  • 4.1工程搭建
    Mybatis的核心包和依赖包
    MySQl的驱动包
    Junit(非必须)
    这里写图片描述
  • 4.2代码实现
1)创建pojo类
public class User { 
    private Integer id;
    private String userName;    //用户名
    private String sex;         //性别
    private String birthday;    //生日
    private String address;     //地址
    省略getXxx()和setXxx()
    ...
}   

2)创建全局配置文件
在config目录下,创建SqlMapConfig.xml文件,该名称不是固定不变的。
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 对类进行别名的定义 -->
<typeAliases>
    <!-- 单个别名定义 -->
    <!-- <typeAlias type="com.mybatis.assess.pojo.User" alias="user" /> -->
    <!-- 批量别名定义 -->
    <!-- package:指定包名称来为该包下的pojo类声明别名,默认的别名就是类名(首字母大小写都行)-->
    <package name="com.mybatis.assess.pojo"/>
</typeAliases>
<configuration>
    <!--配置mybatis的环境信息,与spring整合,该信息由spring管理 -->
    <environments default="development">
        <environment id="development">
            <!-- 配置jdbc事物控制,由mybatis管理 -->
            <transactionManager type="JDBC" />
            <!-- 配置数据源,采用mybatis连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8" />
                <property name="username" value="root" />
                <property name="password" value="123456" /> 
            </dataSource>
        </environment>
    </environments>
<configuration> 
<!-- 加载映射文件 -->
<mappers>
    <!-- 使用相对于类路径的资源 -->
    <mapper resource="com/mybatis/assess/config/UserMapper.xml"/>
</mappers>

3)映射文件
在config目录下,创建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">
<!-- 注意:在mapper代理时,它具有特殊及重要的作用 -->
<mapper namespace="IUserMapper"> 
<!-- select:表示一个MappedStatement对象
     id:statement的唯一标识
     #{}:表示一个占位符?
     #{id}:里面的id表示输入参数的参数名称,如果该参数是简单类型,那么#{}参数名称可以任意
     parameterType:输入参数的JAVA类型
     resultType:输出结果所映射的java类型(单条结果所对应的java类型)
 -->
<select id="queryUserById" parameterType="int" resultType="User">
    select * from user where id = #{id}
</select>

<!-- ${}:表示一个sql的连接符 
     ${value}:里面的value表示输入参数的名称,如果该参数是简单类型,那么${}里面的参数名称必须是value
     ${}:这种写法存在sql注入的风险,但是在一定的场景下,必须使用${},比如排序时,动态传入排序的名称
-->
<select id="queryUserByName" parameterType="String" resultType="User">
    select * from User where username like '%${value}%' 
</select>

<!-- 主键自增长 并且配置 useGeneratedKeys="true" keyProperty="fid" -->
<insert id="insertUser" parameterType="user" useGeneratedKeys="true"
    keyProperty="id">
    insert into
    user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
</insert>

<!-- 主键返回之自增主键
     selectkey:查询主键,在标签内需要输入查询主键的sql
     order:指定查询主键的sql和insert语句的执行顺序,相当于insert语句来说
     LAST_INSERT_ID:该函数是mysql的函数,获取自增主键的id,它必须配合insert语句一起使用
 -->
<insert id="saveUser" parameterType="user">
    <selectKey keyProperty="id" resultType="int" order="AFTER">
        select LAST_INSERT_ID()
    </selectKey>
    insert into
    user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
</insert>

<!-- 自增主键之UUID -->
<insert id="saveUser2" parameterType="user">
    <selectKey keyProperty="id" resultType="String" order="BEFORE"><!-- 只要不是自增主键,那么order都设置为before -->
        select UUID()
    </selectKey>
    insert into
    user(id,username,birthday,sex,address) values (#{id},#{username},#{birthday},#{sex},#{address})
<!-- 需要显示的给id赋值,因为该id的值不是通过自增主键来创建的 -->
</insert>
注意:最后需要在全局配置文件中加载映射文件

4)测试代码
##根据用户ID查询用户信息
@Test
public void test() throws Exception{
    //读取配置文件
    String resource = "com/mybatis/assess/config/SqlMapConfig.xml";
    Reader reader = Resources.getResourceAsReader(resource);
    //创建sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); 
    //创建sqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession();        
    //第一个参数,表示statement的唯一标识
    User user = sqlSession.selectOne("IUserMapper.queryUserById", 1);
    System.out.println(user.getUserName());
    //关闭资源
    sqlSession.close();
}

##根据用户名称模糊查询用户列表
@Test
public void test() throws Exception{
    .....
    //第一个参数,表示statement的唯一标识
    Object object = sqlSession.selectList("IUserMapper.queryUserByName", "张");
    System.out.println(object);
    //关闭资源
    .....
}

##添加用户  
@Test
public void test() throws Exception{
    .....
    //第一个参数,表示statement的唯一标识
    User user = new User();
    user.setUsername("Jello");
    user.setSex("1");
    user.setBirthday("2016-08-08");
    user.setAddress("上海市"); 
    sqlSession.insert("IUserMapper.insertUser", user);
    //提交事务
    sqlSession.commit();
    //关闭资源  
    .....
}       

5.Mapper代理的开发方式
开发mapper接口(相当于dao接口),Mapper代理使用的是jdk的代理策略。

  • 5.1Mapper代理的开发规范
    mapper接口的全限定名要和mapper映射文件的namespace值一致。
    mapper接口的方法名称要和mapper映射文件的statement的id一致。
    mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致,而且它的参数是一个。
    mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致。

  • 5.2mapper接口

public interface UserMapper {
    int saveUser(User user) throws Exception; 
    User queryUserById(Integer id) throws Exception;
}
  • 5.3mapper映射文件
    在com.mybatis.assess.mybatis下创建UserMapper.xml(这是mybatis的命名规范,当然,也不是必须是这个名称)
    sqlSession内部的数据区域本身就是一级缓存,是通过map来存储的。
<?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="com.mybatis.assess.dao.UserMapper">
    <!-- 根据用户ID查询 -->
    <select id="queryUserById" parameterType="int" resultType="User">
        select * from user where id = #{id}
    </select>

    <!-- 添加用户 -->
    <insert id="saveUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        insert into user(username,sex,birthday,address) 
            values (#{username},#{sex},#{birthday},#{address})
    </insert>
</mapper>
  • 5.4加载映射文件
    这里写图片描述

  • 5.5测试代码

public static SqlSessionFactory getSqlSessionFactory(){
    //读取配置文件
    String resource = "SqlMapConfig.xml";
    Reader reader = null;;
    SqlSessionFactory sqlSessionFactory = null;
    try {
        reader = Resources.getResourceAsReader(resource);
        //创建sqlSessionFactory
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return sqlSessionFactory;
}
/**
 * 根据ID查询用户
 * @throws Exception
 */
@Test
public void queryUserById() throws Exception{
    SqlSession sqlSession = getSqlSessionFactory().openSession();
    User user = sqlSession.selectOne("com.mybatis.assess.dao.UserMapper.queryUserById", 1);
    System.out.println(user.toString());
    //关闭资源
    sqlSession.close();
}

6.全局配置文件

  • 6.1概览
    SqlMapConfig.xml的配置内容和顺序如下(顺序不能乱):
    Properties(属性)
    Settings(全局参数设置)
    typeAliases(类型别名)
    typeHandlers(类型处理器)
    objectFactory(对象工厂)
    plugins(插件)
    environments(环境信息集合)
    environment(单个环境信息)
    transactionManager(事物)
    dataSource(数据源)
    mappers(映射器)

  • 6.2常用配置

1.properties

这里写图片描述

这里写图片描述

加载的顺序
1)先加载properties中property标签声明的属性
2)再加载properties标签引入的java配置文件中的属性
3)parameterType的值会和properties的属性值发生冲突。

2.settings
mybatis全局配置参数,全局参数将会影响mybatis的运行行为

这里写图片描述
这里写图片描述

3.typeAliases
对pojo类进行别名的定义

4.mybatis支持的别名

这里写图片描述
这里写图片描述
自定义别名:
这里写图片描述

5.Mappers
<mappers>
    <!-- 使用相对于类路径的资源 -->
    <mapper resource="com/mybatis/assess/config/UserMapper.xml"/>

    <mapper url=’’/> 使用完全限定路径
    <mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\UserMapper.xml" />

    <mapper class=’’/> 使用mapper接口的全限定名
    <mapper class="com.mybatis.mapper.UserMapper"/>
    此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下;

    <package name=’’/>(推荐)
    注册指定包下的所有映射文件
    <package name="cn.mybatis.mapper"/>
    此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下; 
</mappers>

7.映射文件

  • 7.1输入映射parameterType
    简单类型
    Pojo类型
    包装pojo类型

    Map
    同传递POJO对象一样,map的key相当于pojo的属性
    映射文件:
    这里写图片描述
    上边红色标注的是hashmap的key。
    测试代码:
    这里写图片描述
    异常测试:
    传递的map中的key和sql中解析的key不一致。测试结果没有报错,只是通过key获取值为空。

  • 7.2输出映射resultType
    1)使用要求
    使用resultType进行结果映射时,需要查询出的列名和映射的对象的属性名一致,才能映射成功。
    如果查询的列名和对象的属性名全部不一致,那么映射的对象为空。
    如果查询的列名和对象的属性名有一个一致,那么映射的对象不为空,但是只有映射正确那一个属性才有值。
    如果查询的sql的列名有别名,那么这个别名就是和属性映射的列名。
    2) 简单类型
    注意:对简单类型的结果映射也是有要求的,查询的列必须是一列,才能映射为简单类型。
    这里写图片描述
    mapper接口:
    这里写图片描述
    测试代码:

@Test
public void queryCount() throws Exception{
    SqlSession sqlSession = getSqlSessionFactory().openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    int count = mapper.queryCount();
    System.out.println(count);
    //关闭资源
    sqlSession.close();
}
  • 3)Pojo对象和pojo列表

  • 4)resultMap
    使用要求:使用resultMap进行结果映射时,不需要查询的列名和映射的属性名必须一致。但是需要声明一个resultMap,来对列名和属性名进行映射。

映射文件:
<resultMap type="User" id="userRstMap">
    <!-- id:专门为查询结果中唯一列映射 result:映射查询结果中的普通列 -->
    <id column="id" property="id"/>
    <result column="username" property="username" />
    <result column="sex" property="sex" />
    <result column="birthday" property="birthday" />
    <result column="address" property="address" />
</resultMap>

<select id="queryAllUser" resultMap="userRstMap">
    select * from user
</select>

测试代码:
@Test
public void queryAllUser() throws Exception{
    SqlSession sqlSession = getSqlSessionFactory().openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> user = mapper.queryAllUser();
    System.out.println(user.toString());
    //关闭资源
    sqlSession.close();
}
  • 7.3动态sql
    在mybatis中,它提供了一些动态sql标签,可以让程序员更快的进行mybatis的开发,这些动态sql可以通过sql的可重用性。
    常用的动态sql标签:if标签、where标签、sql片段、foreach标签

1)If标签/where标签和sql片段(Sql片段可以让代码有更高的可重用性、Sql片段需要先定义后使用)

映射文件:
<!-- 定义sql片段 
        sql片段内,可以定义sql语句中任何部分
        sql片段内,最好不要将where和select关键字声明在内-->
<sql id="whereClause">
    <!-- if:可以对输入的参数进行判断  test:指定判断表达式 -->
    <if test="userName!=null and userName!=''">
        and userName like '%${userName}%'
    </if>
    <if test="birthday!=null and birthday!=''">
        and birthday = #{birthday};
    </if>
</sql>

<select id="queryUserByNameOrBirthday" parameterType="User" resultType="User">
    select * from user
    <!-- where:默认去掉后面第一个and 如果没有参数,则把自己干掉 -->
    <where>
        <!-- 引入sql片段  -->
        <include refid="whereClause"></include>
    </where>
</select>

测试代码:
@Test
public void queryUserByNameOrBirthday() throws Exception{
    SqlSession sqlSession = getSqlSessionFactory().openSession();
    User uu =new User();
    uu.setBirthday("");
    uu.setUserName("王五");
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> user  = mapper.queryUserByNameOrBirthday(uu);
    System.out.println(user.size());
    //关闭资源
    sqlSession.close();
}

2)Foreach标签
可以循环传入参数值

映射文件:
<sql id="foreachCaluse">
    and id in
    <!-- 
        collection:表示pojo中集合属性的名称
        item:为遍历出的结果声明一个变量名称
        open:遍历开始时,需要拼接的字符串
        close:遍历结束时,需要拼接的字符串
        separator:遍历中间需要拼接的字符串
     -->
    <foreach collection="idList" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>
</sql>

<!-- 根据多个ID查询用户 -->
<select id="queryUserByIds" parameterType="User" resultType="User">
    select * from user
    <where>
        <include refid="foreachCaluse"></include>
    </where>
</select>

测试代码:
@Test
public void queryUserByIds() throws Exception{
    SqlSession sqlSession = getSqlSessionFactory().openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(10);
    User uu =new User();
    uu.setIdList(list);
    List<User> user = mapper.queryUserByIds(uu);
    System.out.println(user.size());
    //关闭资源
    sqlSession.close();
}

8.mybatis与hibernate的区别及各自应用场景
Mybatis技术特点:
1.通过直接编写SQL语句,可以直接对SQL进行性能的优化;
2.学习门槛低,学习成本低。只要有SQL基础,就可以学习mybatis,而且很容易上手;
3.由于直接编写SQL语句,所以灵活多变,代码维护性更好。
4.不能支持数据库无关性,即数据库发生变更,要写多套代码进行支持,移植性不好。
Hibernate技术特点:
1.标准的orm框架,程序员不需要编写SQL语句。
2.具有良好的数据库无关性,即数据库发生变化的话,代码无需再次编写。
3.学习门槛高,需要对数据关系模型有良好的基础,而且在设置OR映射的时候,需要考虑好性能和对象模型的权衡。
4.程序员不能自主的去进行SQL性能优化。
Mybatis应用场景:
需求多变的互联网项目,例如电商项目。
Hibernate应用场景:
需求明确、业务固定的项目,例如OA项目、ERP项目等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值