Mtbatis 快速复习(2021年7月21日)

Mybatis复习:

ORM :对象关系映射框架

基础

快速入门:
//加载配置文件:
InputStream resourceAsStream = Resources.getResourceAsStream("MybatisConfig.xml");
//获取SqlSession对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行SQL语句
List<Object> objects = sqlSession.selectList("StudentMapper.selectAll");
//输出结果
objects.forEach((s) -> {
    System.out.println(s);
});
sqlSession.close();
Mybatis相关API:
  • Resources

    • 加载资源的工具类

    • String resource = "org/mybatis/builder/mybatis-config.xml"; 
      InputStream inputStream = Resources.getResourceAsStream(resource); 
      
  • SqlSessionFactoryBuilder

    • 获取 SqlSessionFactory 工厂对象的功能类

    • SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 
      
  • SqlSessionFactory

    • 获取 SqlSession 构建者对象的工厂接口。

    • SqlSessionFactory factory = builder.build(inputStream);
      
  • SqlSession:

  • //获取sqlSession  如果里面是true的话就会自动提交事务
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    
  • 构建者对象接口。用于执行 SQL、管理事务、接口代理。

image-20210721095204302

增删改

注意:增删改要提交事务,在openSession中可以设置参数为True 自动提交事务,或者手动提交事务

sqlSeeion.commit();

<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束,提示约束-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--
Mapper:核心根标签
namespace:名称空间,自己取
-->
<mapper namespace="StudentMapper">
    <!--id:唯一标识, 配合名称空间使用。
        parameterType:指定参数映射的对象类型。
        resultType:指定结果映射的对象类型。
        parametertype:指定参数映射对象类型,如果是一个对象的参数,就写对象
        -->
    <select id="selectAll" resultType="SSM.Mybatis.entity.Student">
        SELECT *
        FROM student;
    </select>
    <select id="selectOne" resultType="SSM.Mybatis.entity.Student" parameterType="java.lang.Integer">
        SELECT *
        From student
        WHERE id = #{id}
    </select>

    <!--返回影响的行数  resultType 不写resulttype-->
    <insert id="insert" parameterType="SSM.Mybatis.entity.Student">
        Insert INTO student
        VALUES (#{id}, #{name}, #{age})
    </insert>

    <update id="update" parameterType="SSM.Mybatis.entity.Student">
        UPDATE student
        SET name=#{name},
            age=#{age}
        where id = #{id}
    </update>

    <delete id="del" parameterType="SSM.Mybatis.entity.Student">
        delete
        FROM student
        where id = #{id}  
</delete>
</mapper>
配置文件说明(起别名,数据库配置,mapper文件,配置文件引入,log4j配置)
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<!--configuration 核心根标签-->
<configuration>
     <!--引入数据库连接配置文件-->
    <properties resource="jdbc.properties"></properties>
    <!--配置log4j 日志输出-->
    <settings>
        <setting name="logImpl" value="log4j"/>
    </settings>
	<typeAliases>
        <!--起别名-->
        <typeAlias type="SSM.Mybatis.entity.Student" alias="student"</typeAlias>
        <!--全部起别名,默认为类名-->
        <package name="SSM.Mybatis.entity"></package>
    </typeAliases>
    <!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
    <environments default="mysql">
        <!--environment配置数据库环境  id属性唯一标识-->
        <environment id="mysql">
            <!-- transactionManager事务管理。  type属性,采用JDBC默认的事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- dataSource数据源信息   type属性 连接池-->
            <dataSource type="POOLED">
                <!-- property获取数据库连接的配置信息 -->
                <property name="driver" value="${driver}" />
    			<property name="url" value="${url}" />
   				<property name="username" value="${username}" />
    			<property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>

    <!-- mappers引入映射配置文件 -->
    <mappers>
        <!-- mapper 引入指定的映射配置文件   resource属性指定映射配置文件的名称 -->
        <mapper resource="StudentMapper.xml"/>
    </mappers>
</configuration>
java默认别名:

image-20210721103532841

Mybatis配置Log4j
  • 倒入jar包
  • 修改配置文件
  • 编写log4j文件

Mybatis进阶

接口代理方式实现Dao

Mapper 接口开发需要遵循以下规范

  1. 映射配置文件中的名称空间必须和 Dao 层接口的全类名相同。
  2. 映射配置文件中的增删改查标签的 id 属性必须和 Dao 层接口的方法名相同。
  3. 映射配置文件中的增删改查标签的 parameterType 属性必须和 Dao 层接口方法的参数相同。
  4. 映射配置文件中的增删改查标签的 resultType 属性必须和 Dao 层接口方法的返回值相同。 
  5. 获取动态代理对象 SqlSession 功能类中的 getMapper() 方法。

1590937589503

 public Student selectById(Integer id) {
        Student stu = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); 
            // StudentMapper mapper = new StudentMapperImpl();

            //5.通过实现类对象调用方法,接收结果
            stu = mapper.selectById(id);

        } catch (Exception e) {

        } finally {
            //6.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //7.返回结果
        return stu;
    }
接口代理实现原理
  • 分析动态代理对象如何生成的?

    通过动态代理开发模式,我们只编写一个接口,不写实现类,我们通过 getMapper() 方法最终获取到 org.apache.ibatis.binding.MapperProxy 代理对象,然后执行功能,而这个代理对象正是 MyBatis 使用了 JDK 的动态代理技术,帮助我们生成了代理实现类对象。从而可以进行相关持久化操作。

  • 分析方法是如何执行的?

    动态代理实现类对象在执行方法的时候最终调用了 mapperMethod.execute() 方法,这个方法中通过 switch 语句根据操作类型来判断是新增、修改、删除、查询操作,最后一步回到了 MyBatis 最原生的 SqlSession 方式来执行增删改查。

动态SQL语句:
动态 SQL 之<if>
<select id="findByCondition" parameterType="student" resultType="student">
    select * from student
    <where>
        <if test="id!=0">
            and id=#{id}
        </if>
        <if test="username!=null">
            and username=#{username}
        </if>
    </where>
</select>
动态 SQL 之<foreach>

属性
collection:参数容器类型, (list-集合, array-数组)。
open:开始的 SQL 语句。
close:结束的 SQL 语句。
item:参数变量名。
separator:分隔符。

<select id="findByIds" parameterType="list" resultType="student">
    select * from student
    <where>
        <!--list代表集合,array代表数组,open开始的sql  close结束的sql item是参数变量名-->
        <foreach collection="array" open="id in(" close=")" item="id"                           separator=",">
            #{id}
        </foreach>
    </where>
</select>
SQL片段抽取
<!--抽取sql片段简化编写-->
<sql id="selectStudent" select * from student</sql>


<select id="findById" parameterType="int" resultType="student">
    
    <include refid="selectStudent"></include> where id=#{id}
    
</select>

<select id="findByIds" parameterType="list" resultType="student">
    
    <include refid="selectStudent"></include>
    
    <where>
        
        <foreach collection="array" open="id in(" close=")" item="id"  separator=",">
            #{id}
        </foreach>
    </where>
</select>
分页插件

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

开发步骤:

①导入与PageHelper的jar包

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>com.github.jsqlparser</groupId>
    <artifactId>jsqlparser</artifactId>
    <version>3.2</version>
</dependency>

②在mybatis核心配置文件中配置PageHelper插件

<plugins>
        <!-- 注意:分页助手的插件  配置在通用mapper之前 -->
        <plugin interceptor="com.github.pagehelper.c">
            <!-- 指定方言 -->
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>

③测试分页数据获取

@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());
}

PageHelper:分页助手功能类。

  1. startPage():设置分页参数
  2. PageInfo:分页相关参数功能类。
  3. getTotal():获取总条数
  4. getPages():获取总页数
  5. getPageNum():获取当前页
  6. getPageSize():获取每页显示条数
  7. getPrePage():获取上一页
  8. getNextPage():获取下一页
  9. isIsFirstPage():获取是否是第一页
  10. isIsLastPage():获取是否是最后一页
多表操作
  • 多表模型分类 一对一:在任意一方建立外键,关联对方的主键。
  • 一对多:在多的一方建立外键,关联一的一方的主键。
  • 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键。
一对一操作
<?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.itheima.table01.OneToOneMapper">
    <!--配置字段和实体对象属性的映射关系-->
    <resultMap id="oneToOne" type="card">
        <id column="cid" property="id" />
        <result column="number" property="number" />
        <!--
            association:配置被包含对象的映射关系,就是对象里面的对象
            property:被包含对象的变量名
            javaType:被包含对象的数据类型
        -->
        <association property="p" javaType="person">
            <id column="pid" property="id" />
            <result column="name" property="name" />
            <result column="age" property="age" />
        </association>
    </resultMap>

    <select id="selectAll" resultMap="oneToOne">
        SELECT c.id cid,number,pid,NAME,age FROM card c,person p WHERE c.pid=p.id
    </select>
</mapper>

配置总结:

<resultMap>:配置字段和对象属性的映射关系标签。
    id 属性:唯一标识
    type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。
    column 属性:表中字段名称
    property 属性: 实体对象变量名称
<association>:配置被包含对象的映射关系标签。
    property 属性:被包含对象的变量名
    javaType 属性:被包含对象的数据类型
一对多操作
<mapper namespace="com.itheima.table02.OneToManyMapper">
    <resultMap id="oneToMany" type="classes">
        <id column="cid" property="id"/>
        <result column="cname" property="name"/>

        <!--
            collection:配置被包含的集合对象映射关系,对象里面有个对象集合List
            property:被包含对象的变量名
            ofType:被包含对象的实际数据类型
        -->
        <collection property="students" ofType="student">
            <id column="sid" property="id"/>
            <result column="sname" property="name"/>
            <result column="sage" property="age"/>
        </collection>
    </resultMap>
    <select id="selectAll" resultMap="oneToMany">
        SELECT c.id cid,c.name cname,s.id sid,s.name sname,s.age sage FROM classes c,student s WHERE c.id=s.cid
    </select>
</mapper>
<resultMap>:配置字段和对象属性的映射关系标签。
	id 属性:唯一标识
	type 属性:实体对象类型
 <id>:配置主键映射关系标签。
 <result>:配置非主键映射关系标签。
	column 属性:表中字段名称
	property 属性: 实体对象变量名称
<collection>:配置被包含集合对象的映射关系标签。
	property 属性:被包含集合对象的变量名
	ofType 属性:集合中保存的对象数据类型
多对多操作
<?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.itheima.table03.ManyToManyMapper">
    <resultMap id="manyToMany" type="student">
        <id column="sid" property="id"/>
        <result column="sname" property="name"/>
        <result column="sage" property="age"/>

        <collection property="courses" ofType="course">
            <id column="cid" property="id"/>
            <result column="cname" property="name"/>
        </collection>
    </resultMap>
    <select id="selectAll" resultMap="manyToMany">
        SELECT sc.sid,s.name sname,s.age sage,sc.cid,c.name cname FROM student s,course c,stu_cr sc WHERE sc.sid=s.id AND sc.cid=c.id
    </select>
</mapper>
 <resultMap>:配置字段和对象属性的映射关系标签。
    id 属性:唯一标识
    type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。
	column 属性:表中字段名称
	property 属性: 实体对象变量名称
<association>:配置被包含对象的映射关系标签。
	property 属性:被包含对象的变量名
	javaType 属性:被包含对象的数据类型
<collection>:配置被包含集合对象的映射关系标签。
	property 属性:被包含集合对象的变量名
	ofType 属性:集合中保存的对象数据类型

MyBatis高级 (注解开发)

@Insert:实现新增

@Update:实现更新

@Delete:实现删除

@Select:实现查询

@Result:实现结果集封装

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

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

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

MyBatis的增删改查
  • 步骤一:创建mapper接口
public interface StudentMapper {
    //查询全部
    @Select("SELECT * FROM student")
    public abstract List<Student> selectAll();

    //新增操作
    @Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
    public abstract Integer insert(Student stu);

    //修改操作
    @Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}")
    public abstract Integer update(Student stu);

    //删除操作
    @Delete("DELETE FROM student WHERE id=#{id}")
    public abstract Integer delete(Integer id);
}
  • 步骤二:配置映射关系

    <mappers> <package name="接口所在包"/> </mappers>    
    
    一对一多表

    图片11图片10

public interface CardMapper {
    //查询全部
    @Select("SELECT * FROM card")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "number",property = "number"),
            @Result(
                    property = "p",             // 被包含对象的变量名
                    javaType = Person.class,    // 被包含对象的实际数据类型
                    column = "pid",             // 根据查询出的card表中的pid字段来查询person表
                    /*
                        one、@One 一对一固定写法
                        select属性:指定调用哪个接口中的哪个方法
                     */
                    one = @One(select = "com.itheima.one_to_one.PersonMapper.selectById")
            )
    })
    public abstract List<Card> selectAll();
}

一对一配置总结
@Results:封装映射关系的父注解。
	Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
	column 属性:查询出的表中字段名称
	property 属性:实体对象中的属性名称
	javaType 属性:被包含对象的数据类型
	one 属性:一对一查询固定属性
 @One:一对一查询的注解。
	select 属性:指定调用某个接口中的方法
一对多多表 @Many注解
创建StudentMapper接口
public interface StudentMapper {
    //根据cid查询student表
    @Select("SELECT * FROM student WHERE cid=#{cid}")
    public abstract List<Student> selectByCid(Integer cid);
}

2.3.4 使用注解配置Mapper
public interface ClassesMapper {
    //查询全部
    @Select("SELECT * FROM classes")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "name",property = "name"),
            @Result(
                    property = "students",  // 被包含对象的变量名
                    javaType = List.class,  // 被包含对象的实际数据类型
                    column = "id",          // 根据查询出的classes表的id字段来查询student表
                    /*
                        many、@Many 一对多查询的固定写法
                        select属性:指定调用哪个接口中的哪个查询方法
                     */
                    many = @Many(select = "com.itheima.one_to_many.StudentMapper.selectByCid")
            )
    })
    public abstract List<Classes> selectAll();
}
多对多实现
public interface StudentMapper {
    //查询全部
    @Select("SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "name",property = "name"),
            @Result(column = "age",property = "age"),
            @Result(
                    property = "courses",   // 被包含对象的变量名
                    javaType = List.class,  // 被包含对象的实际数据类型
                    column = "id",          // 根据查询出student表的id来作为关联条件,去查询中间表和课程表
                    /*
                        many、@Many 一对多查询的固定写法
                        select属性:指定调用哪个接口中的哪个查询方法
                     */
                    many = @Many(select = "com.itheima.many_to_many.CourseMapper.selectBySid")
            )
    })
    public abstract List<Student> selectAll();
}

SQL 构建对象介绍

1590943921472

image-20210721182624776

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码码哈哈0.0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值