我是靠谱客的博主 活泼画笔,最近开发中收集的这篇文章主要介绍学习Mybatis之02-->配置文件开发之代理开发模式一、代理开发以及案例二、动态SQL语句三、SQL片段抽取四、核心配置文件深入五、plugins标签,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

学习Mybatis之02-->配置文件开发之代理开发模式

  • 一、代理开发以及案例
    • 概述
    • 开发步骤
  • 二、动态SQL语句
    • if
    • foreach
  • 三、SQL片段抽取
  • 四、核心配置文件深入
    • TypeHandlers(类型转换器)标签
  • 五、plugins标签

这一篇主要讲的是通过代理开发模式来进行配置文件的深入学习,其中的知识点有动态SQL语句、typeHandler类型处理、plugins插件标签、SQL片段抽取、pagehelper分页助手

一、代理开发以及案例

概述

在代理开发模式中,我们不在使用DAO层,而是用Mapper去替换它,Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis框架根据接口定义创建接口的动态代理对象,在理对象的方法体同DAO接口实现类方法。

Mapper 接口开发需要遵循以下规范:
1、 Mapper.xml文件中的namespace与mapper接口的全限定名相同
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

开发步骤

前言

关于坐标导入、以及SqlMapConfig.xml里面的详细配置、javaBean的创建都是必要的前提,在上一篇文章中有详细提到,这里就不在赘述了

Mybatis之01—>配置文件(????查看请点我)


1、创建Mapper所需的interface,并在Mapper文件中修改namespace与mapper接口的全限定名相同

创建Mapper所需的interface
在这里插入图片描述

修改namespace(需要是路径名称+接口名称)

<mapper namespace="Z.S.mapper.UserMapper">

2、在配置文件中编写SQL语句并让id与下面的接口方法名相同

SQL语句

<?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="Z.S.mapper.UserMapper">
   
    <!--插入操作-->
    <insert id="save" parameterType="user">   <!--parameterType(参数类型):应该与接口名的参数类型一致-->
        insert into user values (#{id},#{username},#{password},#{birthday})
    </insert>
    
    <!--查询操作-->
    <select id="findAll" resultType="user">   <!--resultType(结果类型):应该与接口方法的返回值类型保持一致-->
        select * from user
    </select>

	
    
</mapper>

接口方法

/**
 * @author 朱霸霸
 * @date 2022/5/26 17:12
 */
public interface UserMapper {
	public void save(User user);  //参数是user
    public List<User> findAll() throws IOException; //返回值类型为集合中的User
    


}

我们从上面可以看出,mapper的接口方法名是与statement的id名称是相对应的,Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同, Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同,这样可使我们的mybatis对其进行映射。

3、编写实现类并实现代理模式开发

public class Test {

    @org.junit.Test
    public void Test() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        
        //模拟新对象
        User user = new User();
		user.setUsername("wanwan");
        user.setPassword("123456");
        user.setBirthday(new Date());
        mapper.save(user);
        }
  }

4、实现成功
在这里插入图片描述


二、动态SQL语句

前言

首先我们应该了解什么是动态语句,动态语句的适用场景啊、以及动态语句的实现方式

what(是什么)?

动态SQL就是指根据不同的条件生成不同的SQL语句

environment(使用场景)?

if:
比如在用到多条件查询时,前端页面会提供三个条件输入框、但用户有可能只输入两个条件进行查询。这个条件的个数是变化的、那么对应SQL语句的查询字段也是变化的,这时候就可以使用动态SQL。

可以对应于SQL语句中的 where <条件> and <条件>and…去配套理解

foreach:
当用户输入查询条件时,查询满足这个条件的所有结果
可以对应SQL语句中的 where <条件> or <条件> or 或者 where

realize(如何实现)?

实现动态SQL的方式这里会介绍两种:
1️⃣if 2️⃣ foreach

if

SQL语句的编写

<!--动态语句查询-->
    <select id="findByCondition" parameterType="user" resultType="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>

实现测试类

public class Test {

    @org.junit.Test
    public void Test() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        //模拟条件
        User condition = new User();
        condition.setId(1);//只根据id进行查询
        List<User> userList =   mapper.ffindByCondition(codition);
        for(User user : userList){
        	System.out.println(user)
        }
		
        }
}

只根据id进行查询所执行的SQL语句
在这里插入图片描述

foreach

SQL语句编写

  <!--动态语句查询-->
    <select id="findByIds" parameterType="list"  resultType="user" >
        <include refid="selectUser"></include>
        <where>
            <foreach collection="list" open="id in (" close=")" item="id" separator=",">
             #{id}

            </foreach>
        </where>

    </select>

实现测试类

public class Test {

    @org.junit.Test
    public void Test() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //模拟ids的数据
        List<Integer> ids = new ArrayList<Integer>();
        idsList.add(1);
        idsList.add(2);

        List<User> userList = mapper.findByIds(idsList);
        for(User user:userList){
        	sout(user)
		}
        

执行的SQL语句
在这里插入图片描述

foreach标签内参数说明:

参数描述
item循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。具体说明:在list和数组中是其中的对象,在map中是value。
collection要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。
当然在作为入参时可以使用@Param(“keyName”)来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:如果User有属性List ids。入参是User对象,那么这个collection = "ids"如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"上面只是举例,具体collection等于什么,就看你想对那个元素做循环。该参数为必选
separator元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
openforeach代码的开始符号,一般设置为“(“和close=")"合用。常用在in(),values()时。该参数可选。
closeoreach代码的关闭符号,一般设置为“)“和open="("合用。常用在in(),values()时。该参数可选。
index在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。

三、SQL片段抽取

前言
SQL中可将重复的SQL语句抽取出来,使用include引用即可,最终达到重用SQL语句的目的,一般来说:select * from 表 是最常用的 ,下面就是该语句作为案例


1.定义一个SQL标签,指定标签id,后期直接在include里面引用该id
2.在标签体类进行SQL语句的编写

 <!--sql语句抽取-->
    <sql id="selectUser">select * from user</sql>

3.在别处进行建立include标签进行引用

    <!--动态语句查询-->
    <select id="findByCondition" parameterType="user" resultType="user">
        <include refid="selectUser"></include> //引用SQL语句
        <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>

四、核心配置文件深入

TypeHandlers(类型转换器)标签

因为数据的数据类型与java数据类型并不统一、因此该标签的功能主要是进行数据库与java之间的数据类型转换。

在这里插入图片描述

通过该标签可以自己处理不支持的或非标准的类型。具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个JDBC类型。

开发步骤:

  1. 定义转换类继承类BaseTypeHandler T为要转换的java类型
  2. 覆盖4个未实现的方法,其中setNonNullParameter(java转数据库)为java程序设置数据到数据库的回调方法,getNullableResult(数据库转java)为查询时 mysql的字符串类型转换成 java的Type类型的方法
  3. 在MyBatis核心配置文件中进行注册
  4. 测试转换是否正确

实际操作:
需求:一个Java中的Date数据类型,我想将之存到数据库的时候存成一个1970年至今的毫秒数,取出来时转换成iava的Date,即iava的Date与数据库存储的毫秒值之间转换。

1、数据库设计:

在数据建立一个bigint类型(为什么是bigint?因为根据需求,要存储毫秒值在数据库内,毫秒值是一长串整数值,是一个java的long的类型,对应的数据库应是bigint)的字段
在这里插入图片描述

2.在实体类创建一个类型为Date的成员变量
在这里插入图片描述
3.定义转换类继承类BaseTypeHandler

public class DataTypeHandler extends BaseTypeHandler<Date> {
    //将java类型转换成数据库需要的类型
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
        long time = date.getTime();
        preparedStatement.setLong(i,time);
    }
    //将数据库中的数据类型转换成java类型
    //String参数 要转换的字段名称(数据库)
    //ResultSet 查询结果集
    @Override
    public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
        //获取结果集中需要的数据(long)将其转换成Date类型并返回
        long aLong = resultSet.getLong(s);
        Date date = new Date(aLong);

        return date;
    }
    //将数据库中的数据类型转换成java类型
    @Override
    public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
        long aLong = resultSet.getLong(i);
        Date date = new Date(aLong);

        return date;
    }
    //将数据库中的数据类型转换成java类型
    @Override
    public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        long aLong = callableStatement.getLong(i);
        Date date = new Date(aLong);
        return date;

    }

3、在核心配置文件中注册

    <!--自定义类型处理器-->
    <typeHandlers>
        <typeHandler handler="Z.S.handler.DataTypeHandler"></typeHandler>
    </typeHandlers>

4.编写测试类

        User user = new User();
        user.setUsername("wanwan");
        user.setPassword("123456");
        user.setBirthday(new Date());
        mapper.save(user);
        mapper.findById(15);

五、plugins标签

下面以PageHelper为案例进行介绍

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

开发步骤:

  • 导入通用PageHelper的坐标(pox.xml中导入)
  • 在mybatis核心配置文件中配置PageHelper插件
  • 测试分页数据获取

具体实现:

1、导入坐标(两个)

      <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>3.7.6</version>
        </dependency>
        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>0.9.1</version>
        </dependency>

2.在mybatis核心配置文件中配置PageHelper插件

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!--方言的指定-->
            <property name="dialect" value="mysql"></property>
        </plugin>
    </plugins>

3.编写测试类


public class Test {

    @org.junit.Test
    public void Test() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //设置分页相关参数  当前页、每页显示的条数
        PageHelper.startPage(1,3);

        List<User> userList = mapper.findAll();
        for (User user : userList) {
            System.out.println(user);
        }

        //获取与分页相关参数
        PageInfo<User> pageInfo = new PageInfo<User>(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());
        System.out.println("下一页:"+pageInfo.getNextPage());
        System.out.println("是否是第一页:"+pageInfo.isIsFirstPage());


        sqlSession.close();
        }
}

最后

以上就是活泼画笔为你收集整理的学习Mybatis之02-->配置文件开发之代理开发模式一、代理开发以及案例二、动态SQL语句三、SQL片段抽取四、核心配置文件深入五、plugins标签的全部内容,希望文章能够帮你解决学习Mybatis之02-->配置文件开发之代理开发模式一、代理开发以及案例二、动态SQL语句三、SQL片段抽取四、核心配置文件深入五、plugins标签所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部