MyBatis总结

一、MyBatis介绍

1.1 什么是MyBatis

mybatis前身是apache的ibatis,是一个封装了jdbc的持久层框架,使开发者只需关注sql即可

1.2框架要解决的问题(jdbc的缺点)

问题:
1.手动创建和释放连接
2.sql语句在代码中硬编译
3.对结果的解析

二、MyBatis入门案例

创建工程

在这里插入图片描述

2.1 pom.xml(添加依赖)

mybatis、mysql-connection-java、log4j、junit根据版本不同自行配置

<build>
   <!-- 如果不添加此节点src/main/java目录下的所有配置文件都会被漏掉。 -->
                <resources>
                    <resource>
                        <directory>src/main/java</directory>
                        <includes>
                            <include>**/*.xml</include>
                        </includes>
                    </resource>
<!-- 如果出现找不到mybatis-config.xml配置文件的情况进行配置 --> 
                    <resource>
                        <directory>src/main/resources</directory>
                    </resource>
                </resources>
            </build>

2.2log4j.properties(配置文件)

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2.3 pojo(根据数据库创建的用户类)

public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    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;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

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

2.4UserDao(UserMapper)接口

public interface UserDao {
    public List<User> findAll();
}

2.5 UserDao.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">
<!--namespace:隔离sql,一般是接口名称的全类名-->
<mapper namespace="com.by.dao.UserDao">
    <!--
      id:和接口方法名保持一致
      resultType:和接口返回类型保持一致
     -->
    <select id="findAll" resultType="com.by.pojo.User">
        select * from user
    </select>
</mapper>

2.6 mybatis-config.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">
<configuration>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="dev">
        <!-- dev环境 -->
        <environment id="dev">
            <!-- 配置事务的类型:type="JDBC | MANAGED" 两种方式
                 JDBC:表示使用JDBC中原生的事务管理方式
                 MANAGED:被管理,例如Spring
			-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置连接数据库的信息:用的是数据源(连接池) -->
            <dataSource type="POOLED">
                 <!-- mysql5 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="1111"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 告知 mybatis 映射配置的位置 -->
    <mappers>
        <mapper resource="com/by/dao/UserDao.xml"/>
    </mappers>
</configuration>

** 注意mysql18的driver和url

<!-- mysql8 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=Asia/Shanghai"/>

2.7测试

public class MyBatisTest {

    private InputStream inputStream;
    private SqlSession sqlSession;

    @Before
    public void createSqlSession() throws IOException {
        // 加载配置文件
        String resource = "mybatis-config.xml";
        inputStream = Resources.getResourceAsStream(resource);

        // 创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = 
            				new SqlSessionFactoryBuilder().build(inputStream);
        //获得数据库会话实例
        sqlSession = sqlSessionFactory.openSession();
    }

    @Test
    public void testFindAll(){
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> userList = userDao.findAll();
        for(User user : userList) {
            System.out.println(user);
        }
    }

    @After
    public void closeSqlSession() throws IOException {
        sqlSession.close();
        inputStream.close();
    }
}

三、 MyBatis运行原理

在这里插入图片描述
MyBatis框架在操作数据库时,大体经过了8个步骤:

1.读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。

2.加载映射文件:映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

3.构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

4.创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法,是一个既可以发送sql执行并返回结果的,也可以获取mapper的接口

5.Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。

6.MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。

7.输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。

8.输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。
mybatis-config.xml
mapper.xml mapper.xml mapper.xml…(会有多个sql语句就会有多个sql文件)
|
|
Resources
|
|---->InputStream
|
SqlSessionFactoryBuilder
|
|---->Configuration(conn, Map<namespace+“.”+id, MappedStatement(sql, resultType)>)
|
SqlSessionFactory
|
|---->Configuration(conn, Map<namespace+“.”+id, MappedStatement(sql, resultType)>)
|
SqlSession
|
|---->conn, Map<namespace+“.”+id, MappedStatement(sql, resultType)>
|
ProxyFactory
|
|---->MappedStatement(sql, resultType), conn
|
Executor
| |
| |
| |
输出映射

四、Mybatis传递多个参数(重点)

1.传递一个参数

User findUserById(Integer id);

WHERE id=#{**}
{ }内可随意命名

2.按序号传参(不推荐)

User findUserByIdAndName(Integer id, String username);WHERE id=#{arg0} AND username=#{arg1}WHERE id=#{param1} AND username=#{param2}

3.注解传参(适用于少量参数)

User findUserByIdAndName2(@Param("id") Integer id, @Param("username") String username);
	 WHERE username=#{username} AND id=#{id} //注解的value值

4.对象传参(适用于多个参数)

User findUser(User userParam);
WHERE id=#{id} AND username=#{username} //对象的属性名

5.map传参(不推荐)

 User findUserByMap(Map<String, Object> map);
WHERE id=#{id} AND username=#{username} //map的key

五、#{}和${}的区别(重点)

#{ } :
1.单个简单参数类型:随便命名
2.底层:preparedStatement
3.数据类型转换:自动转换
4.sql注入:防止
${ }:
1.简单单个参数类型:value
2.底层:Statement
3.数据类型转换:不转换
4.sql注入:不防止

六、主键回填

方式一:

<selectKey order="AFTER" keyProperty="id" resultType="java.lang.Integer">
	    SELECT LAST_INSERT_ID()
	</selectKey>

方式二:

<insert id="" parameterType="" useGeneratedKeys="true" keyProperty="id">

七、Mybatis的ORM映射

1.字段起别名

SELECT role_name as roleName, role_desc as roleDesc From......

2.resultMap结果映射

<resultMap id="findAllResultMap" type="com.by.pojo.Role">
        <id column="id" property="id"></id>
        <result column="role_name" property="roleName"></result>
</resultMap>

<select id="findAll" resultMap="findAllResultMap">......

八、Mybatis的类别名

1.自定义别名

<typeAliases>
            <!--批量起别名-->
            <package name="com.by.pojo"/>
</typeAliases>

2.Mybatis默认支持的别名

统统小写、统统基本类型、集合统统写接口

九、批量加载mapper映射文件

<mappers>
    <!--批量加载映射文件-->
    <package name="com.by.mapper"/>
</mappers>

十、Mybatis的关联查询

1.一对一

<association property="对象的属性名" javaType="查询的结果集装到哪个对象里">
   <id column="id" property="id"/>
   <result column="username" property="username"/>
</association>

参考:

<?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.by.dao.AccountDao">
    <!-- 结果映射 -->
    <resultMap type="account" id="findAllResultMap">
        <id column="aid" property="id"/>
        <result column="uid" property="uid"/>
        <result column="money" property="money"/>
        <!-- 指定关系表中数据的封装规则 -->
        <association property="user" javaType="user">
            <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"/>
        </association>
    </resultMap>
    <select id="findAll" resultMap="findAllResultMap">
        select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id
    </select>
</mapper>

2.一对多

<collection property="对象的属性名" ofType="集合的泛型">
    <id column="aid" property="id"></id>
    <result column="uid" property="uid"></result>
</collection>

参考:

<?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.by.dao.UserDao">
    <resultMap type="user" id="findAllResultMap">
        <id column="id" property="id"></id>
        <result column="username" property="username"/>
        <result column="address" property="address"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <!-- collection 是用于建立一对多中集合属性的对应关系
        ofType 用于指定集合元素的数据类型
        -->
        <collection property="accounts" ofType="account">
            <id column="aid" property="id"/>
            <result column="uid" property="uid"/>
            <result column="money" property="money"/>
        </collection>
    </resultMap>
    <!-- 配置查询所有操作 -->
    <select id="findAll" resultMap="findAllResultMap">
      select u.*,a.id as aid ,a.uid,a.money 
      from user u left join account a on u.id =a.uid
    </select>
</mapper>

3.多对多

<collection property="对象的属性名" ofType="集合的泛型">
    <id column="rid" property="id"></id>
    <result column="role_name" property="roleName"></result>
</collection>

注:多对多和一对多雷同

十一、mybatis的延迟加载

    <resultMap id="findAllResultMap" resultType="user">
        ......
        <collection property="对象的属性名"
                    ofType="集合的泛型"
                    select="select标签的id"
                    column="参数"
                    fetchType="lazy"

        ></resultMap>
    <select id="findAll" resultMap="findAllResultMap">
        ......
    </select>

十二、mybatis的动态sql

1.if标签

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

2.where标签

        <!--where标签:把if包括起来,并且会去掉多余的'AND''OR'-->
        <where>
            <if test="">
            </if>
        </where>

3.set标签

        <!--set标签:去掉多余的“,”-->
        <set>
            <if test="">
            </if>
        </set>

4.trim标签

 <!--trim标签:添加前缀和后缀,去掉多余的前缀和后缀-->
       <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="">
            </if>
       </trim>

5.foreach标签

<!--
            collection="idList":取值array、list、map、@Param("value")
            item="id":集合中的每一个元素进行迭代时的别名
            open="in(":加前缀
            separator="," :分割符
            close=")":加后缀
        -->
        <foreach collection="idList" item="id" open="in(" separator="," close=")">
            #{id}
        </foreach>

6.sql标签

        <!--定义公共的sql片段-->
        <sql id="find_user_where">
            ......
        </sql>

        <!--引用sql片段-->
        <include refid="find_user_where"></include>

十三、mybatis的缓存

1、一级缓存

范围:sqlSession
配置:默认开启
走缓存:同一个sqlSession执行同一条sql
不走缓存:不同sqlSession 或 两次查询之间执行了增上改

2、二级缓存

范围:sqlSessionFactory
配置:
走缓存:同一个sqlSessionFactory走同一条sql
不走缓存:不同sqlSessionFactory 或 两次查询之间执行了增上改

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值