翻过这座山之Mybatis知识回顾

之前我们通过自定义持久层框架来了解mybatis的一些实现思路,接下来让我们继续由浅至深的了解一下这个框架,这篇文章主要是回顾mybatis的基础入门以及一些高级应用
自定义mybatis框架链接

一、Mybatis相关概念

1.1 对象/关系数据库映射(ORM)

ORM全称:Object/Relation Mapping 表示对象-关系映射的缩写

ORM完成面向对象的编程语言到关系数据库的映射。当ORM框架完成映射后,程序员既可以利用面向对象程序设计语言的简单易用性,又可以利用关系数据库的技术优势。ORM把关系数据库包装成面向对象的模型。ORM框架是面向对象设计语言与关系数据库发展不同步时的中间解决方案。采用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的放松来操作持久化对象,而ORM框架则将这些面向对象的操作转换成底层SQL操作。ORM框架实现的效果:把对持久化对象的保存、修改、删除 等操作,转换为对数据库的操作

1.2 Mybatis简介

MyBatis是一款优秀的基于ORM的半自动(除了对象于数据库的简单映射,我们也可以通过编写sql的方式访问数据)轻量级(占用系统资源较少)持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO (Plain Old Java Objects,普通老式Java对 象)为数据库中的记录。

1.3 Mybatis历史

  1. 原是apache的一个开源项目iBatis, 2010年6月这个项目由apache software foundation 迁移到了google code,随着开发团队转投Google Code旗下,ibatis3.x正式更名为Mybatis ,代码于2013年11月迁移到Github。
  2. iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)

1.4 Mybatis优势

Mybatis是一个半自动化的持久层框架,对开发人员开说,核心sql还是需要自己进行优化,sql和java编码进行分离,功能边界清晰,一个专注业务,一个专注数据。
在这里插入图片描述

二、Mybatis基本应用

2.1 快速入门

MyBatis官网地址:http://www.mybatis.org/mybatis-3/

2.2 开发步骤

①添加MyBatis的坐标
②创建user数据表
③编写User实体类
④编写映射文件UserMapper.xml
⑤编写核心文件SqlMapConfig.xml
⑥编写测试类

2.3 环境搭建

1)首先创建一个maven工程在这里插入图片描述
2)引入Mybatis的坐标和其他需要的坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lagou</groupId>
    <artifactId>mybatis_quickStarter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--mybatis坐标-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--mysql驱动坐标-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency>
        <!--单元测试坐标-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--日志坐标-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
    </dependencies>
</project>

3)创建一张数据库表
在这里插入图片描述
4)编写实体类
需要注意属性名应该和数据库表字段名一致

package com.lagou;

public class User {
    
    private Integer id;
    
    private String username;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                '}';
    }
}

5)编写核心配置文件

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

    <!--environments: 运行环境 一个environment代表一个环境-->
    <environments default="development">
        <environment id="development">
            <!--transactionManager: 事务管理者 JDBC表示事务交由jdbc管理-->
            <transactionManager type="JDBC"></transactionManager>
            <!--使用mybatis提供的连接 UNPOOLED表示不使用连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--引入映射配置文件-->
    <mappers>
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>

</configuration>

6)编写mapper配置文件

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

    <!--namespace: 名称空间 与id组成sql的唯一标识
        resultType: 返回值类型-->
    <select id="findAll" resultType="com.lagou.pojo.User">
        select * from user;
    </select>
    
</mapper>

7)编写测试类并测试

public class MybatisTest {

    @Test
    public void test() throws IOException {
        //1.加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        //2.解析配置文件,并获取SqlSessionFactory工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //3.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //4.执行sql语句
        List<User> userList = sqlSession.selectList("user.findAll");
        //5.测试结果
        for (User user : userList) {
            System.out.println(user);
        }
        //6.释放资源
        sqlSession.close();
    }
}

打印结果

User{id=1, username='tom1'}
User{id=2, username='李四'}

2.4 mybaits的增删改查回顾

我们先将加载配置文件和生成sqlsession对象提取方法

    private UserDao userDao;

    private OrdersDao ordersDao;

    private SqlSession sqlSession;

    @Before
    public void before() throws IOException {
        //加载核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //解析配置文件,获取SqlSessionFactory工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //生产SqlSession
        sqlSession = sqlSessionFactory.openSession();
        //生成动态代理对象
        userDao = sqlSession.getMapper(UserDao.class);
        ordersDao = sqlSession.getMapper(OrdersDao.class);
    }

  1. Mybatis的插入数据操作

编写UserMapper.xml映射文件

    <!--插入用户-->
    <insert id="insertUser" parameterType="com.yx.pojo.User">
        insert into user(id, username)
        values (#{id}, #{username});
    </insert>

编写插入实体User的代码

    @Test
    public void insertUserTest() {
        User user = new User();
        user.setId(4);
        user.setUsername("测试");
        Integer count = userDao.insertUser(user);
        //增删改需要提交事务
        sqlSession.commit();
        System.out.println("是否执行成功: " + (count > 0 ? "是" : "否"));
    }
  • 插入语句使用insert标签
  • 在映射文件中使用parameterType属性指定要插入的数据类型
  • Sql语句中使用#{实体属性名}方式引用实体中的属性值
  • 插入操作涉及数据库数据变化,所以要使用sqlSession对象显示的提交事务,即sqlSession.commit()
  1. MyBatis的修改数据操作

编写UserMapper映射文件

    <!--修改用户-->
    <update id="updateUser" parameterType="com.yx.pojo.User">
        update user
        set username = #{username}
        where id = #{id};
    </update>

编写修改实体User的代码

    @Test
    public void updateUserTest() {
        User user = new User();
        user.setId(1);
        user.setUsername("lisi");
        Integer count = userDao.updateUser(user);
        //增删改需要提交事务
        sqlSession.commit();
        System.out.println("是否执行成功: " + (count > 0 ? "是" : "否"));
    }
  • 修改语句使用update标签
  • 需要提交事务
  1. MyBatis的删除数据操作

编写UserMapper映射文件

    <delete id="deleteUserById" parameterType="java.lang.Integer">
        delete from user where id = #{id}
    </delete>

编写删除数据的代码

    @Test
    public void deleteUserTest() {
        Integer count = userDao.deleteUserById(3);
        //增删改需要提交事务
        sqlSession.commit();
        System.out.println("是否执行成功: " + (count > 0 ? "是" : "否"));
    }
  • 删除语句使用delete标签
  • Sql语句中使用#{任意字符串}方式引用传递的单个参数

2.5 MyBatis的映射文件概述

在这里插入图片描述

2.6 Mybatis核心配置文件分析

在这里插入图片描述
MyBatis常用配置解析

  1. environments标签在这里插入图片描述
    其中,事务管理器(transactionManager)类型有两种:
    • JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
    • MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。
    其中,数据源(dataSource)类型有三种:
    • UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
    • POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
    • JNDI:这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
  2. mapper标签
    该标签的作用是加载映射的,加载方式有如下几种:
•使用相对于类路径的资源引用,例如: 
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/> 
•使用完全限定资源定位符(URL),例如: 
<mapper url="file:///var/mappers/AuthorMapper.xml"/> 
•使用映射器接口实现类的完全限定类名,例如: 
<mapper class="org.mybatis.builder.AuthorMapper"/> 
•将包内的映射器接口实现全部注册为映射器,例如: 
<package name="org.mybatis.builder"/>
  1. Properties标签
    实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件
    在这里插入图片描述
  2. typeAliases标签

typeAliases标签下有两个标签,typeAlias 标签通过属性type和属性alias进行取别名
还有批量取别名package,该包下的所有对象类名,首字母小写作为别名

    <typeAliases>
        <!-- 取别名 -->
        <typeAlias type="com.yx.pojo.User" alias="user"/>
        <!-- 该包下所有对象类名,首字母小写 -->
        <package name="com.yx.pojo"/>
    </typeAliases>

不仅如此mybatis也为我们定义了一些基本类型的别名,基本类型的包装类别名就是基本类型 比如 Integer 的别名是int

2.7 Mybatis的动态sql

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

  1. if 标签: 条件判断中不能使用&&,要使用and. 标签的 test 属性中写的是对象的属性
  2. where 标签: 简化 where 1=1 的条件拼装,我们可以采用标签来简化开发,会自动删去第一个and
  3. foreach 标签: 用来遍历集合
  4. sql 标签: 抽取重复的语句代码片段
  5. include 标签: 使用 sql标签里的sql

这里由于我太熟了就不写很详细啦,嘻嘻

2.8 Mybatis的复杂映射

  1. 一对一查询
    一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户
    对应的sql语句:select * from orders o,user u where o.uid=u.id;
    在这里插入图片描述
    实体类
    在这里插入图片描述
    配置OrderMapper.xml
<mapper namespace="com.yx.dao.OrdersDao">
    <resultMap id="orderMap" type="com.lagou.domain.Order">
        <result property="id" column="id"></result>
        <result property="ordertime" column="ordertime"></result>
        <result property="total" column="total"></result>
        <association property="user" javaType="com.lagou.domain.User">
            <result column="uid" property="id"></result>
            <result column="username" property="username"></result>
            <result column="password" property="password"></result>
            <result column="birthday" property="birthday"></result>
        </association>
    </resultMap>

    <select id="findAll" resultMap="OrdersUserMap">
        select * from orders o,user u where o.uid=u.id;
    </select>
</mapper>
  1. 一对多查询
    一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
    对应的sql语句:select *,o.id oid from user u left join orders o on u.id=o.uid;
    在这里插入图片描述
    实体类
    在这里插入图片描述
    在这里插入图片描述
  2. 多对多查询
    多对多查询的需求:查询用户同时查询出该用户的所有角色
    对应的sql语句:select u.,r.,r.id rid from user u left join user_role ur on u.id=ur.user_id inner join role r on ur.role_id=r.id;
    在这里插入图片描述
    实体类
    在这里插入图片描述
    在这里插入图片描述

2.9 Mybatis的注解开发

@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
修改核心配置文件,使用了注解代替xml配置文件,所以我们只需要加载使用了
注解的mapper接口即可

<mappers>
 <!--扫描使用注解的类--> 
 	<mapper class="com.lagou.mapper.UserMapper"></mapper>
 	<!--扫描使用注解的类所在的包-->
 	<package name="com.lagou.mapper"></package>
 </mappers>

注解的复杂映射查询

  1. 一对一
    在这里插入图片描述

  2. 一对多

    public interface UserMapper {
        @Select("select * from user")
        @Results({@Result(id = true, property = "id", column = "id"),
                @Result(property = "username", column = "username"),
                @Result(property = "password", column = "password"),
                @Result(property = "birthday", column = "birthday"),
                @Result(property = "orderList", column = "id", javaType = List.class,
                many = @Many(select = "com.lagou.mapper.OrderMapper.findByUid"))})
        List<User> findAllUserAndOrder();
    }

    public interface OrderMapper {
        @Select("select * from orders where uid=#{uid}")
        List<Order> findByUid(int uid);
    }
  1. 多对多
    public interface UserMapper {
        @Select("select * from user")
        @Results({@Result(id = true, property = "id", column = "id"),
                @Result(property = "username", column = "username"),
                @Result(property = "password", column = "password"),
                @Result(property = "birthday", column = "birthday"),
                @Result(property = "roleList", column = "id", javaType = List.class,
                        many = @Many(select = "com.lagou.mapper.RoleMapper.findByUid"))})
        List<User> findAllUserAndRole();
    }

    public interface RoleMapper {
        @Select("select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=#{uid}")
        List<Role> findByUid(int uid);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值