11、MyBatis的Dao层实现方式

1.MyBatis的Dao层实现

1.1 传统开发方式
  1. 编写UserDao接口

    public interface UserDao {
    List<User> findAll() throws IOException;
    }
  2. 编写UserDaoImpl实现

    public class UserDaoImpl implements UserDao {
    public List<User> findAll() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    List<User> userList = sqlSession.selectList("userMapper.findAll");
    sqlSession.close();
    return userList;
    }
    }
  3. 测试传统方式

    @Test
    public void testTraditionDao() throws IOException {
    UserDao userDao = new UserDaoImpl();
    List<User> all = userDao.findAll();
    System.out.println(all);
    }
1.2 代理开发介绍
  1. 代理开发方式介绍

    采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。

    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的类型相同
  2. 编写UserMapper接口

  1. 测试代理方式

    @Test
    public void testProxyDao() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //获得MyBatis框架生成的UserMapper接口的实现类
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = userMapper.findById(1);
    System.out.println(user);
    sqlSession.close();
    }

12、MyBatis映射文件深入

1.MyBatis映射文件深入

1.1 动态sql语句
  1. 动态sql语句概述

    Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。

    参考的官方文档,描述如下:

  2. 动态SQL 之<if>

    我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

    <select id="findByCondition" parameterType="user" resultType="user">
    select * from User
    <where>
    <if test="id!=0">
    and id=#{id}
    </if>
    <if test="username!=null">
    and username=#{username}
    </if>
    </where>
    </select>

    当查询条件id和username都存在时,控制台打印的sql语句如下:

    … … …
    //获得MyBatis框架生成的UserMapper接口的实现类
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User condition = new User();
    condition.setId(1);
    condition.setUsername("lucy");
    User user = userMapper.findByCondition(condition);
    … … …

    当查询条件只有id存在时,控制台打印的sql语句如下:

    … … …
    //获得MyBatis框架生成的UserMapper接口的实现类
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User condition = new User();
    condition.setId(1);
    User user = userMapper.findByCondition(condition);
    … … …
  3. 动态 SQL 之<foreach>

    循环执行sql的拼接操作,例如:SELECT * FROM USER WHERE id IN (1,2,5)。

    <select id="findByIds" parameterType="list" resultType="user">
    select * from User
    <where>
    <foreach collection="array" open="id in(" close=")" item="id" separator=",">
    #{id}
    </foreach>
    </where>
    </select>

    测试代码片段如下:

    … … …
    //获得MyBatis框架生成的UserMapper接口的实现类
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    int[] ids = new int[]{2,5};
    List<User> userList = userMapper.findByIds(ids);
    System.out.println(userList);
    … … …

    foreach标签的属性含义如下:

    标签用于遍历集合,它的属性:

    • collection:代表要遍历的集合元素,注意编写时不要写#{}

    • open:代表语句的开始部分

    • close:代表结束部分

    • item:代表遍历集合的每个元素,生成的变量名

    • sperator:代表分隔符

1.2 SQL片段抽取
  • Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

1.3 小结

MyBatis映射文件配置:

  • <select>: 查询

  • <insert>:插入

  • <update>:修改

  • <delete>:删除

  • <where>:where条件

  • <if>:if判断

  • <foreach>:循环

  • <sql>:sql片段抽取


13、MyBatis核心配置文件深入

1.MyBatis核心配置文件深入

1.1 typeHandlers标签

无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器(截取部分)。

你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个JDBC类型。例如需求:一个Java中的Date数据类型,我想将之存到数据库的时候存成一个1970年至今的毫秒数,取出来时转换成java的Date,即java的Date与数据库的varchar毫秒值之间转换。

开发步骤:

  1. 定义转换类继承类BaseTypeHandler

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

  3. 在MyBatis核心配置文件中进行注册

  4. 测试转换是否正确

    public class MyDateTypeHandler extends BaseTypeHandler<Date> {
    //将java类型 转换成 数据库需要的类型
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType type) {
    preparedStatement.setString(i,date.getTime()+"");
    }
    // 将数据库中类型 转换成java类型
    public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
    return new Date(resultSet.getLong(s));
    }
    // 将数据库中类型 转换成java类型
    public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
    return new Date(resultSet.getLong(i));
    }
    // 将数据库中类型 转换成java类型
    public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
    return callableStatement.getDate(i);
    }
    }
    <!--注册类型自定义转换器-->
    <typeHandlers>
    <typeHandler handler="com.itheima.typeHandlers.MyDateTypeHandler"></typeHandler>
    </typeHandlers>

    测试添加操作:

    user.setBirthday(new Date());
    userMapper.add2(user);

    数据库数据:

    测试查询操作:

1.2 plugins标签

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

开发步骤:

  1. 导入通用PageHelper的坐标

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

  3. 测试分页数据获取


  1. 导入通用PageHelper坐标

    <!-- 分页助手 -->
    <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>0.9.1</version>
    </dependency>
  2. 在mybatis核心配置文件中配置PageHelper插件

    <!-- 注意:分页助手的插件  配置在通用馆mapper之前 -->
    <plugin interceptor="com.github.pagehelper.PageHelper">
    <!-- 指定方言 -->
    <property name="dialect" value="mysql"/>
    </plugin>
  3. 测试分页代码实现

    @Test
    public void testPageHelper(){
    //设置分页参数 当前页+每页现实的条数
    PageHelper.startPage(1,2);
    List<User> select = userMapper2.select(null);
    for(User user : select){
    System.out.println(user);
    }
    }

    获得分页相关的其他参数:

    //其他分页的数据
    PageInfo<User> pageInfo = new PageInfo<User>(select);
    System.out.println("总条数:"+pageInfo.getTotal());
    System.out.println("总页数:"+pageInfo.getPages());
    System.out.println("当前页:"+pageInfo.getPageNum());
    System.out.println("每页显示长度:"+pageInfo.getPageSize());
    System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
    System.out.println("是否最后一页:"+pageInfo.isIsLastPage());
1.3 小结

MyBatis核心配置文件常用标签:

  1. properties标签:该标签可以加载外部的properties文件

  2. typeAliases标签:设置类型别名

  3. environments标签:数据源环境配置标签

  4. typeHandlers标签:配置自定义类型处理器

  5. plugins标签:配置MyBatis的插件

SSM自学笔记(六)的更多相关文章

  1. SSM自学笔记(七)

    14.MyBatis的多表操作 1.MyBatis的多表操作 1.1 一对一查询 一对一查询的模型 用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单 ...

  2. SSM自学笔记(五)

    10.MyBatis入门操作 1.MyBatis的简介 1.1 原始jdbc操作(查询数据) 1.2 原始jdbc操作(插入数据) ##### 1.3 **原始**jdbc操作的分析 原始jdbc开发 ...

  3. SSM自学笔记(四)

    8.面向切面编程AOP 1.Spring 的 AOP 简介 1.1 什么是 AOP AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运 ...

  4. SSM自学笔记(三)

    5.Spring JdbcTemplate 1.Spring JdbcTemplate基本使用 1.1 JdbcTemplate概述 它是spring框架中提供的一个对象,是对原始繁琐的Jdbc AP ...

  5. SSM自学笔记(二)

    3.SpringMVC入门 1.Spring与Web环境集成 1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplication ...

  6. SSM自学笔记(一)

    本文内容 Ioc和DI Spring快速入门 Spring配置文件 Spring IoC和DI注解开发 Spring配置数据源 Spring注解开发 Spring整合Junit IoC 和 DI 1. ...

  7. vue 自学笔记记录

    vue 自学笔记(一): 知识内容:  安装vue ,创建vue实例,安装第一个组件,单项数据流 https://www.cnblogs.com/baili-luoyun/p/10763163.htm ...

  8. JavaScript高级程序设计之自学笔记(一)————Array类型

    以下为自学笔记. 一.Array类型 创建数组的基本方式有两种: 1.1第一种是使用Array构造函数(可省略new操作符). 1.2第二种是使用数组字面量表示法. 二.数组的访问 2.1访问方法 在 ...

  9. 《Linux内核设计与实现》课本第四章自学笔记——20135203齐岳

    <Linux内核设计与实现>课本第四章自学笔记 进程调度 By20135203齐岳 4.1 多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统.多任务操作系统使多个进程处于堵 ...

随机推荐

  1. B 站崩了,受害程序员聊聊

    非吃瓜,B 站事件始末分析 + 防治技术分享 大家好,我是鱼皮,昨天小破站崩了的事情相信很多朋友都听说了. 这要是搁以前,不爱吃瓜的我根本不会去关注这种事,崩了就崩了呗,反正天塌下来有程序员大佬们扛着 ...

  2. 【Python从入门到精通】(十一)Python的函数的方方面面【收藏下来保证有用!!!】

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 本文主要介绍Python的函数,函数的定义,使用,可变参数等等都有详细介绍. 干货满满,建议收藏,需要用到时常看看. 小伙伴们如有问题及需要,欢迎 ...

  3. python 爬取网络小说 清洗 并下载至txt文件

    什么是爬虫 网络爬虫,也叫网络蜘蛛(spider),是一种用来自动浏览万维网的网络机器人.其目的一般为编纂网络索引. 网络搜索引擎等站点通过爬虫软件更新自身的网站内容或其对其他网站的索引.网络爬虫可以 ...

  4. Day4 包机制 及JavaDoc文档.

    包机制 为了更好地组织类,java提供了包机制,用于区别类名的命名空间. 包的本质是文件夹 它语句的语法格式为: package pkg1[. pkg2 [.pkg3...] ] ; 一般利用公司域名 ...

  5. python + Poium 库操作

    1.支持pip安装 pip install poium 2.基本用法 from poium import PageElement,Page,PageElements# 1.poium支持的8种定位方法 ...

  6. python基础之面向对象OOP

    #类(面向对象) PageObject设计模式 unittest 知识体系#函数式编程import datetimebook_info = { "title":"Pyth ...

  7. request - cookie 操作(一)

    from urllib import request#headers 带cookieblog_url = "http://www.renren.com/452057374/profile?r ...

  8. 微信小程序云开发-云存储-下载并打开文件文件(word/excel/ppt/pdf)

    一.wxml文件 1.写文本框,用来获取文件链接. 2.按钮,点击下载文件 <!-- 下载文件(word/excel/ppt/pdf等) --> <view class=" ...

  9. 搭建NFS服务

    说明:这里是Linux服务综合搭建文章的一部分,本文可以作为单独搭建yum仓库的参考. 注意:这里所有的标题都是根据主要的文章(Linux基础服务搭建综合)的顺序来做的. 如果需要查看相关软件版本和主 ...

  10. springmvc学习指南 之---第25篇 Spring Bean有三种配置方式

    writed by不要张艳涛, 从tomcat转到了springmvc 现在开始有点不知道该看什么书了,看完了springmvc 学习指南之后 又查了一些书,好多都是内容相近,在找书的过程之中,发现s ...