MyBatis进阶

371 阅读5分钟

MyBatis接口代理方式实现Dao层

图片.png

规则:

1.映射配置文件中的 名称空间 必须和Dao层接口的全类名相同

2.映射配置文件中的 增删改查标签的id属性 必须和Dao层接口的方法名相同

3.映射配置文件中的 增删改查标签的parameterType属性 必须和Dao层接口方法的参数相同

4.映射配置文件中的 增删改查标签的resultType属性 必须和Dao层接口方法的返回值相同

具体实现

直接把mapperImpl删掉,MyBatis会帮我们搞

1.删除mapper层接口的实现类

2.修改映射配置文件

3.修改service层接口的实现类,采用接口代理方式实现功能

StudentMapper持久层、不再需要他的Impl实现类了

图片.png

StudentMapper.xml

满足规则1 1.映射配置文件中的 名称空间 必须和Dao层接口的全类名相同

图片.png

StudentServiceImpl业务层:持久层对象Impl已经没有了,所以删除,里面的实现逻辑也要删除改进。变成接口代理的相关功能

图片.png

改进后的selectAll方法:
public List<Student> selectAll(){
    //获取SqlSession对象
    SqlSession sqlSession =  MyBatisUtils.getSqlSession();
    
    //获取StudentMapper接口的实现类对象
    StudentMapper mapper =  sqlSession.getMapper(StudentMapper.class);
        该语句等价于-->StudentMapper mapper = new StudentMapperImpl();
        只不过这个实现类不是我们自己写的,而是MyBatis帮我们生成
    
    //调用实现类对象中的方法来完成操作,返回拿到的集合对象
    List<Student> = mapper.selectAll();
    
    //释放资源
    sqlSession.close();
    
    //返回结果
    return list;
}
selectById

图片.png

insert

图片.png

update

图片.png

delete

图片.png

控制层测试持久层能否成功

图片.png

图片.png

图片.png

执行结果:

demo08.gif

@Param注解

图片.png

想查询年龄是24或者名字是张三 的信息

图片.png

业务层实现类对象

图片.png

持久层

图片.png

使用@Params

图片.png

映射配置文件(为多个参数设置类型)、这里就不用再设置parameterType了,因为我们已经通过@Params来设置了

图片.png

通过映射文件 实现 动态SQL

sql条件有很多,如果我们要一条一条的实现也太累了,我们通过动态SQL来实现

图片.png

StudentMapper.xml映射配置文件

图片.png

StudentMapper.java持久层实现对DB的操作

图片.png

测试类Test01.java

InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml") 图片.png 如果我在这里将setName注释掉,程序是会报错的,因为这三个参数我必须都要传,才可以成功。如果是这样的话,就相当于限定死了每一条sql语句,那么如何解决呢?

if标签

图片.png

StudentMapper.xml

<select id = "selectCondition" resultType = "student" parameterType = "student">

//只需要写前面的select
    SELECT * FROM student

//where语句被下放的where标签代替了,可以删除了
//WHERE id = #{id} AND name = #{name} AND age = #{age}

//使用where标签代替where关键字
    <where>
    查询条件,根据id来查询,但是name和age可以作为备选条件查询
        <if test = "id!=null">
            id = #{id}
        </if>
        <if test = "name!=null">
            AND name = #{name}
        </if>
        <if test = "age!=null">
            AND age = #{age}
        </if>
    </where>
</select>

Test01.java测试类测试

图片.png

就算对其中一个备选数据进行注释,我也依然可以根据已知的条件查询出对应的数据。

图片.png

foreach标签

多个参数 或者的关系 :多个id查询出多个数据

图片.png

StudentMapper.xml

//多个参数存在集合里
<select id = "selectByIds" resultType="student" parameterType="list">
//查询id是1、2、3的数据
//SELECT * FROM student WHERE id IN(1,2,3)
    
//使用foreach标签优化 将where后面的语句删除
    <where>
    开始:从where后,结束:小括号
        <foreach collection="list"
        open="id IN("
        close=")" 
        item="id"
        separator=",">
        //获取数据
            #{id}
        </foreach>
    </where>
</select>

接口中的语句: public abstract List<Studnet>selectByIds(List<Integer> ids)

测试方法:

图片.png

demo08.gif

sql片段抽取

对重复性的SQL语句进行抽取,达到复用的效果。

比如说对:SELECT * FROM student

图片.png

图片.png

MyBatis核心配置文件-分页插件

图片.png

图片.png

分页就是Sql中的limit限制显示的条数,效果是一样的

分页插件实现步骤

1.导入jar包

2.在核心配置文件中集成分页助手插件

在MyBatisConfig.xml核心配置文件
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
    </plugin>
</plugins>

3.在测试类中使用分页助手相关API实现分页功能

public void selectPaging() throws Exception{
    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
    //把8条数据分成3页来实现,通过分页助手实现
    PageHelper.startPage(1,3); //第1页-显示3条
    PageHelper.startPage(2,3); //第2页-显示3条

    List<Student> list = mapper.selectAll();
   
    for(Student student : list){
        System.out.println(student)
    }

----------------------在这里获取分页参数------------------

    sqlSession.close();
    is.close();
分页插件相关参数的了解

PageInfo:封装分页相关参数的功能类

图片.png

//获取分页参数,位置在上面的地方
PageInfo<Student> info = new PageInfo<>(list);
总条数:info.getTotal();
总页数:info.getPages();
当前页:info.getPageNum();
每页显示条数:info.getPageSize();
上一页:info.getPrePage();
下一页:info.getNextPage();
是否是第一页:info.isIsFirstPage();
是否是最后一页:info.isIsLastPage();

图片.png

总结:

图片.png

多表操作

图片.png

一对一的多表操作

图片.png

1.新建数据库表:Card和Person.class,里面初始化

图片.png

2.在核心配置文件中:导入映射配置文件

图片.png

3.书写映射配置文件的接口OneToOneMapper.java

public interface OneToOneMapper{
    public abstract List<Card> selectAll();

}

图片.png

4.设置他们俩的映射配置文件OneToOneMapper.xml

<mapper namespace="接口所在的全路径">
    //用来配置字段和实体对象属性的映射关系,给实体对象card配置映射关系
    <resultMap id = "oneToone" type="card">
        //column:给表中哪个字段进行封装?
        //property:给card实例类中的id赋值
        主键用id标签
        <id column="cid" property="id"/>
        其他字段用result标签
        <result column="number" property="number"/>

        //配置给被包含对象的映射关系(就是person表的字段)
        //property被包含对象的变量名Person p
        //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">
    //显示card表中的id 并且 取别名叫 cid,来自card表 取别名后的c表
        SELECT c.id cid,number,pid,name,age from card c,person p where c.pid = p.id
    </select>
</mapper>

5.测试类

图片.png

结果:

图片.png

小结:

图片.png

一对多

图片.png

实体类

Student 图片.png

classes 图片.png

映射配置文件OneToManyMapper.xml

<mapper namespace = "接口全类名">
//唯一标识,给哪一个实体对象进行映射关系
    <resultMap id = "oneToMany" type = "classes">
    //表中的主键名,classes.id赋值
        <id colum = "cid" property = "id" />
        //字段名,classes.name赋值
        <result column = "cname" property = "name"/>
        
        //学生表中的数据要单独写,collection是一对多的标签
        //被包含对象的变量名,ofType:实际类型
        <collection property="students" ofType="student">
            <id column="sid" property="id"/>
            <result column="sname" property="name"/>
            <result column="sage" property="age"/>
        </collection>
        
    </resultMap>
    //唯一标识,要和上方的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.id
</mapper>

核心配置文件MyBatisConfig.xml(引入映射配置文件)

图片.png

接口

图片.png

测试类Test

图片.png

结果:

图片.png

多对多

图片.png

图片.png

图片.png