SSM-Mybatis-2-进阶使用

1 Mybatis的Dao层实现

1.1 传统开发方式

仍然在Dao层编写接口并实现,将Dao层对象和Service层对象配置成Bean,在Controller层使用Servcie层对象完成业务的处理
在这里插入图片描述

1.2 代理开发介绍

采用Mybatis的代理开发方式实现Dao层的开发,这种方式也是企业中的主流,Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同Dao接口的实现类方法

Mapper接口开发需要遵循的规范:
在这里插入图片描述
Dao层接口需要与Mapper.xml映射起来:
在这里插入图片描述

1,编写Dao层接口UserMapper:

public interface UserMapper {

    List<User> findAll() throws IOException;

	User findById(int id);
}

2,在UserMapper.xml中根据要求重新配置:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace对应Dao层某个接口的全限定名 -->
<mapper namespace="com.coisini.dao.UserMapper">

    <!-- id为findAll 对应接口中一定要存在findAll()方法 返回值类型和参数类型都需要是全限定名 -->
    <select id="findAll" resultType="com.coisini.domain.User">
        SELECT * FROM user
    </select>

    <select id="findById" resultType="com.coisini.domain.User" parameterType="int">
        SELECT * FROM user WHERE id=#{id}
    </select>

</mapper>

3,测试:
在这里插入图片描述

2 Mybatis映射文件深入

2.1 动态SQL语句

当业务逻辑复杂时,SQL语句可能是变化的,比如根据客户端传来的条件查询时,如果客户端传来了一个参数,则SQL可能是SELECT * FROM user WHERE id=#{id}但如果传来两个参数
可能就会是SELECT * FROM user WHERE id=#{id} AND password=#{password},这个查询的SQL语句就是不能确定的

2.1.1 动态SQL的if标签

在UserMapper.xml中配置一个模糊查询的SQL语句:

<select id="findByCondition" resultType="com.coisini.domain.User" parameterType="com.coisini.domain.User">
        SELECT * FROM user
        <where>
            <if test="id!=0">
                AND id=#{id}
            </if>

            <if test="username!=null">
                AND username=#{username}
            </if>

            <if test="password!=null">
                AND password=#{password}
            </if>
        </where>
    </select>

测试:
在这里插入图片描述

2.1.2 动态SQL的foreach标签

SELECT * FROM user WHERE id IN(1, 2, 4)这样的SQL语句也是不确定的,括号中的参数是可以不定的,这类SQL语句同样是不能确定的

在UserMapper.xml中配置一个动态SQL:

    <select id="findByIds" resultType="com.coisini.domain.User" parameterType="list">
        SELECT * FROM user
        <where>
            <foreach collection="list" open="id IN(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

测试:
在这里插入图片描述

2.2 SQL片段抽取

可以将多次重复出现的SQL语句抽取出来,使用时通过include标签,来引用
如在查询操作中,经常以SELECT * FROM user开头,这部分SQL语句就可以被抽取出来:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.coisini.dao.UserMapper">
    
    <!-- SQL语句的抽取 -->
    <sql id="selectUser">SELECT * FROM user</sql>

    <select id="findByCondition" resultType="com.coisini.domain.User" parameterType="com.coisini.domain.User">
        <include refid="selectUser"></include>
        <where>
            <if test="id!=0">
                AND id=#{id}
            </if>

            <if test="username!=null">
                AND username=#{username}
            </if>

            <if test="password!=null">
                AND password=#{password}
            </if>
        </where>
    </select>

    <select id="findByIds" resultType="com.coisini.domain.User" parameterType="list">
        <include refid="selectUser"></include>
        <where>
            <foreach collection="list" open="id IN(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

</mapper>

3 Mybatis核心配置文件深入

3.1 typeHandlers标签

无论是Mybatis在PreparedStatement中设置一个参数,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成Java类型,一些默认的类型处理器如下:
在这里插入图片描述
可以重写类型处理器或自定义类型处理器满足自己的需求,如一个Java中的Date数据类型,存到数据库时想存成一个1970至今的毫秒数,取出来时再转换成Date,即完成Date和varchar的相互转换,开发步骤:

1,定义转换继承类BasetypeHandle<T>

2,覆盖4个未实现方法
其中setNonNullPointer为Java程序设置数据到数据库的回调方法
getNullableResult为查询时mysql的字符串类型转换成JavaType类型方法

3,在SqlMapConfig.xml配置文件中进行注册

4,测试转换是否正确

3.2 plugins标签

Mybatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据

开发步骤:

1,导入PageHelper相关jar包

2,在SqlMapConfig.xml中使用plugins标签配置插件

3,测试分页数据获取

1,导入PageHelper相关jar包:

	<dependency>
          <groupId>com.github.pagehelper</groupId>
          <artifactId>pagehelper</artifactId>
          <version>3.7.5</version>
      </dependency>

      <dependency>
          <groupId>com.github.jsqlparser</groupId>
          <artifactId>jsqlparser</artifactId>
          <version>1.0</version>
      </dependency>

2,在SqlMapConfig.xml中使用plugins标签配置插件:

<!-- 配置分页助手插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql"></property>
        </plugin>
    </plugins>

sqlMapConfig.xml中标签之间存在一定的先后顺序,报错了调整顺序即可

3,测试分页数据获取:
在这里插入图片描述
通过PageHelper.startPage()就可以获取不同页中的若干条数据

还可以通过PageInfo来获取关于分页的信息

        // 获得与分页相关的参数
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        System.out.println("当前页: " + pageInfo.getPageNum());
        System.out.println("每页显示条数: " + pageInfo.getPageSize());
        System.out.println("总条数: " + pageInfo.getTotal());
        System.out.println("总页数: " + pageInfo.getPages());
        System.out.println("上一页: " + pageInfo.getPrePage());

4 Mybatis的注解开发

Mybatis常用的注解:

@Insert: 插入

@Update: 更新

@Delete: 删除

@Select: 查询

@Result: 实现结果集封装

@Results: 可以与@Result一起使用,封装多个结果集

@One: 实现一对一结果集封装

@Many: 实现一对多结果集封装

1,编写接口并在接口中使用注解完成持久层操作:

public interface UserMapper {

    @Insert("INSERT INTO user VALUES(#{id}, #{username}, #{password})")
    void save(User user);

    @Update("UPDATE user SET username=#{username}, password=#{password} WHERE id=#{id}")
    void update(User user);

    @Delete("DELETE FROM user WHERE id=#{id}")
    void delete(int id);

    @Select("SELECT * FROM user WHERE id=#{id}")
    User findById(int id);

    @Select("SELECT * FROM user")
    List<User> findAll();

}

2,在sqlMapConfig.xml中加载映射关系:

    <!-- 加载映射关系 -->
    <mappers>
        <!-- 指定接口所在的包 这些带注解的接口会被扫描  -->
        <package name="com.coisini.mapper"/>
    </mappers>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值