学习目标

第一章 - MyBatis缓存【了解】

知识点-缓存概述

1.目标

2.路径

  1. 缓存概述
  2. 为什么使用缓存
  3. 缓存的适用情况
  4. MyBatis缓存类别

3.讲解

3.1缓存概述

​ 缓存就是一块内存空间.保存临时数据

3.2为什么使用缓存

​ 将数据源(数据库或者文件)中的数据读取出来存放到缓存中,再次获取的时候 ,直接从缓存中获取,可以减少和数据库交互的次数,这样可以提升程序的性能!

3.3缓存的适用情况

  • 适用于缓存的:经常查询但不经常修改的(eg: 省市,类别数据),数据的正确与否对最终结果影响不大的
  • 不适用缓存的:经常改变的数据 , 敏感数据(例如:股市的牌价,银行的汇率,银行卡里面的钱)等等,

3.4MyBatis缓存类别

​ 一级缓存:它是sqlSession对象的缓存,自带的(不需要配置)不可卸载的(不想使用还不行). 一级缓存的生命周期与sqlSession一致。

​ 二级缓存:它是SqlSessionFactory的缓存。只要是同一个SqlSessionFactory创建的SqlSession就共享二级缓存的内容,并且可以操作二级缓存。二级缓存如果要使用的话,需要我们自己手动开启(需要配置的)。

4.小结

  1. 缓存: 内存空间, 保存临时数据
  2. 为什么要使用缓存? 提高性能
  3. 适合使用缓存? 经常查询的, 不经常改变
  4. MyBatis的缓存类别
    • 一级缓存 : 默认开启的,属于sqlsession级别
    • 二级缓存 : 需要配置,默认不开启, 属于sqlsessionfactory

知识点-一级缓存

1.目标

2.路径

  1. 证明一级缓存的存在
  2. 一级缓存分析
  3. 测试一级缓存清空

3.讲解

3.1证明一级缓存的存在

只有查询的操作,才有缓存的必要性。增删改的操作不会有缓存。 其他的代码这里就不提供了,大家可以理解为了其实就是重复调用一个findByUid()方法,并且查询的用户id一样。

package com.itheima.test;

import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class TestUserDao {
  /*
        证明一级缓存的存在:
            1. 一级缓存是跟着sqlsession同生共死。
            2. 只要重复查询即可,必须要查一样的id的用户
     */
    @Test
    public void testFindByUid(){

        //1. 问工具类要sqlSession
        SqlSession session = SqlSessionFactoryUtil.getSession();

        //2. 问sqlSession要代理对象
        UserDao userDao = session.getMapper(UserDao.class);

        //3. 调用方法
        User user = userDao.findByUid(1);
        System.out.println("user = " + user);

        //再查一次!
        User user2 = userDao.findByUid(2);
        System.out.println("user2 = " + user2);

        //4. 收尾
        session.close();

    }
}

3.2一级缓存分析

img

​ 第一次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。第二次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,缓存中有,直接从缓存中获取用户信息。mybatis里面判定是否存在现在要执行的操作的缓存数据,是通过sql语句判断的。在前面保存到缓存里面去的时候,就使用了sql语句充当KEY , 缓存数据充当Value来保存。

😃如果 sqlSession 去执行 commit操作(执行插入、更新、删除),清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。 commit动作一定会清空缓存,因为有可能存在一种假设: 原来查询的是id为1的用户信息,接着做了更新操作,把id为1的用户信息给修改了,那么此时缓存里面的数据就是过期数据。

3.3测试一级缓存清空

  • 增删改动作会清空一级缓存
package com.itheima.test;

import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class TestUserDao {

//证明:清空一级缓存
    @Test
    public void testFindByUid02(){

        //1. 问工具类要sqlSession
        SqlSession session = SqlSessionFactoryUtil.getSession();

        //2. 问sqlSession要代理对象
        UserDao userDao = session.getMapper(UserDao.class);

        //3. 调用方法
        User user = userDao.findByUid(1);
        System.out.println("user = " + user);

        //删除其中的一条数据。
        int row = userDao.deleteByUid(5);
        System.out.println("删除的结果:" + row);

        //再查一次!
        User user2 = userDao.findByUid(1);
        System.out.println("user2 = " + user2);

        //4. 收尾
        session.close();
    }
}

4.小结

  1. 一级缓存: 依赖sqlSession对象的, 自带的不可卸载的. 一级缓存的生命周期和sqlSession一致
  2. 一级缓存清空
    • sqlSession销毁 , 调用close()
    • 增删改 提交之后 , 调用了commit

知识点-二级缓存

1.目标

2.路径

  1. 二级缓存的结构
  2. 二级缓存的使用
  3. 二级缓存的测试

3.讲解

​ 二级缓存是SqlSessionFactory的缓存。只要是同一个SqlSessionFactory创建的SqlSession就共享二级缓存的内容,并且可以操作二级缓存. 默认mybatis不会开启二级缓存,需要手动配置,因为范围太大,而且工厂很可能永远不会关闭!

3.1二级缓存的结构

img

3.2二级缓存的使用

3.2.1 在 SqlMapConfig.xml 文件开启二级缓存

二级缓存它有两个开关: 一个是在SQLMapConfig.xml里面,这个开关默认是开启的。还有一个开关,这个开关需要在每一个mapper.xml(映射文件)里面开启。哪个映射文件配置了这个开关,那么即表示这个映射文件里面的所有查询操作会可以使用二级缓存。

img

因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为 false 代表不开启二级缓存。

3.2.2 配置相关的 Mapper 映射文件
  1. 默认情况下mybatis已经全局性开启了二级缓存,但是所有的查询动作都不会把数据放在二级缓存里面。
  2. 如果希望某一个查询的动作,把数据存放在二级缓存里里面,那么需要在映射文件中配置

<cache> 标签表示当前这个 mapper 映射将使用二级缓存,即:该mapper文件中的所有查询操作都将使用二级缓存, 无需单独为每一个

2.路径

  1. @Insert:实现新增
  2. @Update:实现更新
  3. @Delete:实现删除
  4. @Select:实现查询
  5. @SelectKey:保存之后 获得保存的id

3.实现

  • Dao
package com.itheima.dao;

import com.itheima.bean.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

/*
    这里使用注解来替代crud的 映射文件
 */
public interface UserDao {

    @Insert("insert into t_user values (null , #{username}, #{sex} , #{birthday} , #{address})")
    int add(User user);

    @Delete("delete from t_user where uid = #{uid}")
    int delete(int uid);

    @Update("update t_user set username = #{username} , sex = #{sex} , birthday=#{birthday} , address=#{address} where uid = #{uid}")
    int update(User user);

    @Select("select * from t_user where uid = #{uid}")
    User findByUid(int uid);

    @Select("select * from t_user")
    List<User> findAll();

  /* <selectKey keyProperty="" resultType="" order="">
        SELECT LAST_ISNERT_ID();
    </selectKey>*/

    /*
        SelectKey : 添加之后,获取主键返回
            keyProperty : 用什么属性来装
            resultType : 属性是什么类型
            before:
                false: 表明添加数据之后再去获取id值
                true:  表明在添加数据之前就获取id值
            statement: 查询id的语句 : SELECT LAST_INSERT_ID()
     */
    @SelectKey(keyProperty = "uid" , resultType = int.class , before = false , statement = "SELECT LAST_INSERT_ID()")
    @Insert("insert into t_user values (null , #{username}, #{sex} , #{birthday} , #{address})")
    int add02(User user);
}

  • SqlMapConfig.xml

1535361902219

  • 单元测试
package com.itheima.test;

import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Date;
import java.util.List;

public class TestUserDao {

    @Test
    public void testAdd(){

        SqlSession session = SqlSessionFactoryUtil.getSession();

        UserDao dao = session.getMapper(UserDao.class);

        User user = new User();
        user.setUsername("张三");
        user.setSex("男");
        user.setBirthday(new Date());
        user.setAddress("深圳");

        dao.add(user);

        session.close();
    }
    @Test
    public void testDelete(){

        SqlSession session = SqlSessionFactoryUtil.getSession();

        UserDao dao = session.getMapper(UserDao.class);

        dao.delete(16);

        session.close();
    }

    @Test
    public void testUpdate(){

        SqlSession session = SqlSessionFactoryUtil.getSession();

        UserDao dao = session.getMapper(UserDao.class);

        //先查询
        User user = dao.findByUid(1);
        user.setSex("女");

        //再修改
        dao.update(user);

        session.close();
    }
    @Test
    public void testFindAll(){

        SqlSession session = SqlSessionFactoryUtil.getSession();

        UserDao dao = session.getMapper(UserDao.class);

        //先查询
        List<User> list = dao.findAll();
        System.out.println("list = " + list);

        session.close();
    }

    //添加完毕,获取主键id
    @Test
    public void testAdd02(){

        SqlSession session = SqlSessionFactoryUtil.getSession();

        UserDao dao = session.getMapper(UserDao.class);


        User user = new User();
        user.setUsername("张三");
        user.setSex("男");
        user.setBirthday(new Date());
        user.setAddress("深圳");
        dao.add02(user);

        //打印id:
        System.out.println(user.getUid());

        session.close();
    }
}

4.小结

  1. 查询
@Select("sql语句")
  1. 新增
@SelectKey(keyProperty = "主键属性名",resultType = 主键Java类型,before = false,statement = "SELECT LAST_INSERT_ID()")
@Insert("sql语句")
  1. 更新
@Update("sql语句")
  1. 删除
@Delete("sql语句)

知识点-使用Mybatis注解实现复杂关系映射开发

1.目标

2.路径

  1. 复杂关系映射的注解说明
  2. 使用注解实现一对一复杂关系映射及延迟加载
  3. 使用注解实现一对多复杂关系映射及延迟加载

3.讲解

​ 实现复杂关系映射之前我们可以在映射文件中通过配置来实现, @ResultMap 这个注解不是封装用的。

​ 下面我们一起来学习 **@Results 注解, @Result 注解, @One 注解, @Many注解。 **

3.1复杂关系映射的注解说明

  • @Results 注解 , 代替的是标签
//该注解中可以使用单个@Result 注解,也可以使用@Result 集合
@Results({@Result(), @Result() })或@Results(@Result())

  • @Resutl 注解 ,代替了 标签和标签 ,
@Result(column="列名",property="属性名",one=@One(select="指定用来多表查询的 sqlmapper"),many=@Many(select=""))

@Resutl 注解属性说明	
    column 数据库的列名
    Property 需要装配的属性名
    one 需要使用的@One 注解(@Result(one=@One)()))
    many 需要使用的@Many 注解(@Result(many=@many)()))

  • @One 注解(一对一),代替了标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@Result(column="列名",property="属性名",one=@One(select="指定用来多表查询的 sqlmapper"))

  • @Many 注解(一对多) ,代替了标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合

    ​ 注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType(一般
    为 ArrayList) 但是注解中可以不定义;

@Result(property="",column="",many=@Many(select=""))

3.2使用注解实现(多)一对一复杂关系映射及延迟加载

3.2.1需求

查询账户(Account)信息并且关联查询用户(User)信息。

​ 先查询账户(Account)信息,当我们需要用到用户(User)信息时再查询用户(User)信息。

3.2.2实现
  • User02.java
package com.itheima.bean;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

@Data
public class User02 implements Serializable {
    private int uid;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
}

  • Account02.java
package com.itheima.bean;

import lombok.Data;

@Data
public class Account02 {
    private int aid;
    private double money;
    private int uid;

    //表示一对一的关系: 一个账户只能属于一个用户
    private  User02 user02;
}

  • AccountDao02.java
package com.itheima.dao;

import com.itheima.bean.Account02;
import com.itheima.bean.User02;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

//一口气查询所有的账户
public interface AccountDao02 {


    /*
        @Select : 查询的注解
        @Results : 等价于 <resultMap> 标签,用于做映射处理
             @Result : 用于做具体的映射,每一个属性的映射,都需要用到这个注解
                property : 属性名
                column :列名
             如果有一个属性是对象类型,那么也需要用@Result来映射
             @Result:
                property : 属性名
                javaType : 属性的类型是什么
                column: 把什么列当成参数传递给下面调用的方法
                one :用来表示一对一的映射
                    select : 用于表示要调用哪个类的哪个方法来得到结果
                    fetchType : 用于设置懒加载,默认不用懒加载
                        FetchType.LAZY : 懒加载
                        FetchType.EAGER : 不懒
     */
    @Select("select * from t_account")
    @Results(value = {
            @Result(property = "aid" , column = "aid"),
            @Result(property = "money", column = "money"),
            @Result(property = "uid" , column = "uid"),
            @Result(property = "user02" ,
                    javaType = User02.class ,
                    column = "uid",
                    one = @One(select = "com.itheima.dao.UserDao02.findByUid" ))
    })
    List<Account02>  findAll();
}

  • UserDao02.java
package com.itheima.dao;

import com.itheima.bean.User;
import com.itheima.bean.User02;
import org.apache.ibatis.annotations.Select;

// 根据用户的id来查询用户的信息
public interface UserDao02 {

    @Select("select * from t_user where uid = #{uid}")
    User02 findByUid(int uid);

}

  • 测试
package com.itheima.test;

import com.itheima.bean.User;
import com.itheima.dao.AccountDao02;
import com.itheima.dao.UserDao;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Date;
import java.util.List;

public class TestAccountDao02 {

    @Test
    public void testFindAll(){

        SqlSession session = SqlSessionFactoryUtil.getSession();

        AccountDao02 dao = session.getMapper(AccountDao02.class);
        System.out.println(dao.findAll());
        session.close();

    }
}

3.3使用注解实现一对多复杂关系映射及延迟加载

3.3.1需求

​ 完成加载用户对象时,查询该用户所拥有的账户信息。

​ 等账户信息使用的时候再查询.

3.3.2实现
  • Account03.java
package com.itheima.bean;

import lombok.Data;

@Data
public class Account03 {
    private int aid;
    private double money;
    private int uid;
}


  • User03.java
package com.itheima.bean;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

@Data
public class User03 implements Serializable {
    private int uid;
    private String username;
    private String sex;
    private Date birthday;
    private String address;

    //表示一个用户有多个账户:
    private List<Account03> account03List;
}

  • UserDao03.java
package com.itheima.dao;

import com.itheima.bean.User03;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

//查询所有的用户
public interface UserDao03 {

    /*
        @Select :查询注解
        @Results :等价于<resultMap>
        @Result  : 等价于<id>和<result> 标签
            property:属性名
            column : 列名
        如果有一个属性是一个集合的类型,也需要用@Result来映射
         @Result : 也可以映射一对多
             property: 属性名
             column: 把哪个列值,当成参数,传递给下面的方法
             many: 表示一对多
                select :用于写调用的方法的全路径 :com.itheima.dao.AccountDao03.findByUid
     */
    @Select("select * from t_user")
    @Results(value={
        @Result(property = "uid",column = "uid" , id = true),
        @Result(property = "username",column = "username"),
        @Result(property = "sex",column = "sex"),
        @Result(property = "birthday",column = "birthday"),
        @Result(property = "address",column = "address"),
        @Result(property = "account03List" , column = "uid" ,
                many = @Many(select = "com.itheima.dao.AccountDao03.findByUid" ))
    })
    List<User03> findAll();
}

  • AccountDao03.java
package com.itheima.dao;

import com.itheima.bean.Account03;
import org.apache.ibatis.annotations.Select;

import java.util.List;

//根据用户的id,来查询账户的数据
public interface AccountDao03 {

    @Select("select * from t_account where uid = #{uid}")
    List<Account03> findByUid(int uid);
}

  • 测试
package com.itheima.test;

import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import com.itheima.dao.UserDao03;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Date;
import java.util.List;

//一对多查询: 查询所有的用户,并且把账户的信息也查询出来
public class TestUserDao03 {

    @Test
    public void testFinAll(){

        SqlSession session = SqlSessionFactoryUtil.getSession();

        UserDao03 dao = session.getMapper(UserDao03.class);

        System.out.println(dao.findAll());

        session.close();
    }

}

4.小结

  1. 代替ResultMap标签
@Results(value={
	@Result(column = "列名",property = "属性名",id = boolean值),
	@Result(column = "列名",property = "属性名", one=@One(select="", fetchType="") ),
    @Result(column = "列名",property = "属性名", many=@Many(select="", fetchType="") )
})

第四章 - 分页处理【重点】

知识点 - 分页

1.目标

2.路径

  1. 使用PageHelper实现分页效果

3.讲解

3.1 添加依赖

         <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.10</version>
        </dependency>

3.2 添加插件

需要在mybatis的核心配置(SqlMapConfig.xml)文件中,配置分页插件。 位于environments 的前面。 配置分页的插件其实就是配置拦截器。这个拦截器有什么作用呢? 它的作用是能够让我们在不侵入代码|源码的情况下实现分页的效果,也就是它会在底层的sql语句给我们追加 limit ? ,?

<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
       
	</plugin>
</plugins>

3.3 示例代码

  • javabean
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private int uid;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
}
  • dao
  1. 返回值使用pagehelper提供的 Page
  2. 最终的sql语句使用查询所有的语句
package com.itheima.dao;

import com.github.pagehelper.Page;
import com.itheima.bean.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserDao {

    /**
     * 分页查询
     * @return
     */
    @Select("select * from t_user")
    List<User> findPage();


    /**
     * 分页查询:
     *      1. 除了返回当前这一页的集合数据之外
     *      2. 还需要返回其他的数据(比如: 当前第几页,总共多少页,每页显示多少条,总共多少条!)
     *      3. pagehelper分页插件里面定义了一个专门用于包装分页数据的Bean :  Page
     *          3.1 Page 其实就是一个ArrayList
     *          3.2 Page 继承了ArrayList,再添加几个属性!
     * @return
     */
    @Select("select * from t_user")
    Page<User> findPage2();



}

  • 测试代码

在查询之前需要设置查询的参数。

package com.itheima.test;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class TestUserDao {

    @Test
    public void testFindPage(){
        SqlSession session = SqlSessionFactoryUtil.getSession();
        UserDao dao = session.getMapper(UserDao.class);

        //要想使用分页,必须在调用方法之前,配置想查询第几页,每页查询多少条!
        PageHelper.startPage(2, 2);

        List<User> list = dao.findPage();
        for (User user : list) {
            System.out.println("user = " + user);
        }

        session.close();
    }

    @Test
    public void testFindPage2(){
        SqlSession session = SqlSessionFactoryUtil.getSession();
        UserDao dao = session.getMapper(UserDao.class);

        //要想使用分页,必须在调用方法之前,配置想查询第几页,每页查询多少条!
        PageHelper.startPage(2, 2);

        Page<User> page = dao.findPage2();

        System.out.println("当前页:" + page.getPageNum());
        System.out.println("总动多少页:" + page.getPages());
        System.out.println("每页显示:" + page.getPageSize());
        System.out.println("总动多少条:" + page.getTotal());

        //直接打印这个result 打印出来的内容并不是我们平常见到的集合的样子,多了很多东西。
        System.out.println("当前这一页的集合:" + page.getResult());

        //这个不影响使用,直接遍历,也可以使用。
        for (User user : page.getResult()) {
            System.out.println("user=" + user);
        }

        session.close();
    }
}

4.总结

  1. 添加依赖
  2. 添加插件
  3. 查询的语句为 select * from t_user

第五章 - 综合案例

案例一 - 显示所有联系人

一,案例需求

img

二 、实现步骤

  • 添加依赖

  <dependencies>
    <!--MyBatis坐标-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>
    <!--mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.37</version>
    </dependency>
    <!--单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>

    <!--lombok 依赖-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.18</version>
    </dependency>


    <!--日志-->
    <!-- log start -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.6.6</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.6</version>
    </dependency>

     <!-- 分页插件依赖 -->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.1.10</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
    <dependency>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
      <version>1.9.4</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>


    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.39</version>
    </dependency>

    <!-- dbutils :: 可以不添加 -->
    <dependency>
      <groupId>commons-dbutils</groupId>
      <artifactId>commons-dbutils</artifactId>
      <version>1.6</version>
    </dependency>

    <!-- c3p0:: 可以不添加 -->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.2.1</version>
    </dependency>
  </dependencies>

  • 设置maven的编译版本
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  • 拷贝配置文件 SqlMapConfig.xml db.properties log4j.properties 到 resources目录

记得修改db.propeties里面的数据库连接

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/linkman的数据库
jdbc.user=root
jdbc.password=root
  • 拷贝工具类 SqlSessionFactoryUtil
  • dao代码
package com.itheima.dao;

import com.github.pagehelper.Page;
import com.itheima.bean.LinkMan;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface LinkManDao02 {

    /**
     * 查询所有的联系人
     * @return
     */
    @Select("select * from linkman")
    List<LinkMan> findAll();

}

  • service代码
package com.itheima.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.bean.LinkMan;
import com.itheima.bean.PageBean;
import com.itheima.dao.LinkManDao;
import com.itheima.dao.LinkManDao02;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class LinkManService {  
	/**
     * 查询所有联系人
     * @return List<LinkMan>
     */
    public List<LinkMan> findAll() throws SQLException {

        System.out.println("使用mybatis来查询所有的联系人!");

        //1. 从工具类获取SqlSession
        SqlSession session = SqlSessionFactoryUtil.getSession();

        //2. 从sqlsession获取代理对象
        LinkManDao02 dao02 = session.getMapper(LinkManDao02.class);

        //3. 调用方法
        List<LinkMan> list = dao02.findAll();

        //4. 返回、收尾
        session.close();

        return list;

    }
}

案例二 - 添加联系人

一、案例需求

  1. 点击添加联系人跳转添加联系人页面

    1571568952279

  2. 在添加联系人页面,点击提交按钮,把数据提交到服务器,保存到数据库

    1571568994445

  3. 在添加完成,可以查看到新建的联系人信息

    1571569023876

二、实现步骤

  • dao 代码
package com.itheima.dao;

import com.github.pagehelper.Page;
import com.itheima.bean.LinkMan;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface LinkManDao02 {


    @Insert("insert into linkman values(null , #{name} , #{sex}, #{age} , #{address}, #{qq}, #{email})")
    int add(LinkMan linkMan);
}

  • service代码
package com.itheima.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.bean.LinkMan;
import com.itheima.bean.PageBean;
import com.itheima.dao.LinkManDao;
import com.itheima.dao.LinkManDao02;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class LinkManService {

    /**
     * 添加联系人
     * @param linkMan 要添加到数据库的联系人对象
     * @return 影响的行数,如果 >0 表示添加成功,否则添加失败
     */
    public int add(LinkMan linkMan) throws SQLException {

        System.out.println("使用mybatis来添加联系人!");

        //1. 从工具类获取SqlSession
        SqlSession session = SqlSessionFactoryUtil.getSession();

        //2. 从sqlsession获取代理对象
        LinkManDao02 dao02 = session.getMapper(LinkManDao02.class);

        //3. 调用方法
        int row = dao02.add(linkMan);

        //4. 返回、收尾
        session.close();

        return row;

    }

}

案例三 - 分页展示联系人

一、案例需求

1533810941749

二、 实现步骤

  • dao实现
package com.itheima.dao;

import com.github.pagehelper.Page;
import com.itheima.bean.LinkMan;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface LinkManDao02 {


    @Select("select * from linkman")
    Page<LinkMan>  findPage();
}

  • service实现
package com.itheima.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.bean.LinkMan;
import com.itheima.bean.PageBean;
import com.itheima.dao.LinkManDao;
import com.itheima.dao.LinkManDao02;
import com.itheima.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class LinkManService {
/**
     * 分页查询联系人
     * @param currentPage 想看第几页
     * @param pageSize 每页想看多少条
     * @return PageBean 里面封装了当前页的集合数据以及页码使用的信息。
     */
 public PageBean<LinkMan> findByPage(int currentPage , int pageSize) throws SQLException {

        System.out.println("使用mybatis来完成分页功能...");
        //1. 创建PageBean
        PageBean<LinkMan> pageBean  = new PageBean<LinkMan>();

        //2. 调用dao得到结果

        //2.1. 从工具类获取SqlSession
        SqlSession session = SqlSessionFactoryUtil.getSession();

        //2.2. 从sqlsession获取代理对象
        LinkManDao02 dao02 = session.getMapper(LinkManDao02.class);

        //2.3. 调用方法
        //设置想要查询第几页,每页查询多少条
        PageHelper.startPage(currentPage, pageSize);
        Page<LinkMan> page = dao02.findPage();

        //2.4. 返回、收尾
        session.close();

        //3. 封装PageBean
        pageBean.setCurrentPage(currentPage);
        pageBean.setTotalPage(page.getPages());

        pageBean.setPageSize(pageSize);
        pageBean.setTotalSize((int) page.getTotal());

        pageBean.setList(page.getResult());


        return pageBean;
    }
}

总结

缓存:

	1. mybatis为了提高程序的执行效率,设置了两级缓存: 一级缓存和二级缓存
	2. 一级缓存: 属于SqlSession级别的缓存,只在当前的SqlSession内有效,自动设置
		2.1 当进行增删改操作的时候,有事务的提交,那么缓存就会清空掉


	3. 二级缓存: 属于SqlSessionFactory级别的缓存,只要是从这个SqlsessionFactory
		做出来的Sqlsession,都可以共享这个二级缓存。
		2.1 当进行增删改操作的时候,有事务的提交,那么缓存就会清空掉
		2.2 二级缓存有两个开关,默认已经在全局性的开启了二级缓存,但是哪一个映射文件
			想使用二级缓存,那么需要在自己的映射文件里面添加:
			<cache/>

	4. 一般很少去使用二级缓存,因为范围太大,所以很少使用它。

懒加载:


	1. 懒加载只会出现在多表查询里面,在对从表(第二张表)处理的时候,可以稍微偷懒,不是
		一口气就把所有的表的数据给查询出来,而是等用到了之后再去查询!

	2. 懒加载的步骤:
		2.1 永远会先查询第一张表的所有数据
			findAll();

		2.2 再去查询第二张表,一般是根据主键|外键来查询。
			findByXXX(int id);

	2. 一对一: 一个账户属于一个用户

		public class Account{

			...
			private User user;
		}


		AccountDao.xml:
			<resultMap id="accountMap" type="account">
				<id property="" column=""/>
				<result property="" column=""/>

				<association property="user" javaType="user" select="com.itheima.dao.UserDao.findByUid" column="uid" fetchType="lazy"/>

			</resultMap>
			<select id="findAll" resultMap="">
				select * from t_account;
			</select>


	3. 一对多: 一个用户有很多的账户


		public class User{

			...
			private List<Account> accountList;
		}


		UserDao.xml:
			<resultMap id="accountMap" type="account">
				<id property="" column=""/>
				<result property="" column=""/>

				<collection property="accountList" ofType="account" select="com.itheima.dao.AccountDao.findByUid" column="uid" fetchType="lazy"/>

			</resultMap>
			<select id="findAll" resultMap="">
				select * from t_user;
			</select>

注解开发:

基本CRUD:
	@Insert
	@Delete
	@Update
	@Select
	@SelectKey

多表关系:
	@Results : 匹配 <resultMap>标签
	@Result : 匹配 <id> 和 <result标签>
	@One : 一对一 匹配 association
	@Many : 多对多 匹配 collection

分页插件:

1. 导入依赖
2. 配置插件
3. 查询之前先设置查询第几页,每页查询多少条。
posted on 2022-04-23 16:53  ofanimon  阅读(34)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css