Mybatis 简单数据库查询、多表查询、缓存

148 阅读3分钟

一、简单数据库查询

  1. 要通过mybatis进行数据库查询首先要加载主配置文件
 public static String resource = "mybatis-config.xml";
    private static SqlSessionFactory sf = null;
​
    static {
        /*
        * 加载主配置文件,得到SqlSessionfactory对象
        * 该对象是一个连接工厂对象
        * */
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sf = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public  static SqlSessionFactory sf() {
        return  sf;
    }
  1. 在mybatis中新建mapper文件夹,就相当于jdbc中的dao包,在mapper文件夹中创建接口文件和 xml文件,注意接口文件和xml文件的文件名要相同

EmpMapper 接口文件

    List<Emp> findAll();
    Emp findById( int id );  //单查询
    List<Emp> likeName(String name); // 模糊查询
    List<Emp> like(@Param("name") String name, @Param("job") String job); // 多个条件的模糊查询
    int add(Emp e); // 新增
    int update(@Param("id") int id,@Param("name") String name); // 更新
    int delete(int id); // 删除

EmpMapper 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  命名空间 全项目唯一表示当前mapper文件的唯一标识
    1. 不绑定顶接口时 可以随意命名
    2. 绑定接口 必须时接口的全限定名
-->
<mapper namespace="com.zking.mapper.EmpMapper">
    <select id="findAll" resultMap="myemp">
        select * from emp;
    </select>
    <select id="findById" parameterType="int" resultType="emp">
        select * from emp where empno=#{fhasui}
    </select>
    <select id="likeName"  resultType="emp">
        select * from emp where ename like '%${name}%'
    </select>
    <select id="like"  resultType="emp">
        select * from emp where ename like '%${name}%' or job like '%${job}%'
    </select>
​
    <insert id="add"  useGeneratedKeys="true" keyProperty="empno">
        insert into  emp values (null,#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
    </insert>
    <delete id="delete" >
        delete from emp where empno=#{empno}
    </delete>
    <update id="update" >
        update emp set ename=#{name} where empno=#{id}
    </update>
</mapper>

注意:

1、如果传多个条件操作数据库操作,推荐使用@param 注解的方式

2、实体类在类型定义中都要使用引用数据类型,不能出现基本数据类型,原因基本数据类型不能为null

3、 模糊查询使用的是 **** 符号 '%{name}%', 其他查询使用的是#,使用模糊查询存在代码注入问题,有漏洞!

3. 在测试类中: 需要打开一个连接对象,调用自己的mapper中的数据库

   @org.junit.Test
    public void t1() {
//        连接工具
        SqlSessionFactory sf = SqlSessionFactoryUtil.sf();
//        打开一个连接对象
        SqlSession sqlSession = sf.openSession();
//        调用自己的mapper中的sql
        EmpMapper em = sqlSession.getMapper(EmpMapper.class);
        List<Emp> list =em.findAll();
        for (Emp emp : list) {
            System.out.println(emp);
        }
    }

这样一个基本的mybatis数据库操作就完成了!

二、多表查询

1、 一对一的两张表进行联查基本步骤

以people表和card 表为例: 通过people查询card

people表和card表.png 2、 对entity包的处理

people 表中的处理:私有化card

public class People {
​
  private Integer pid;
  private String pname;
​
​
    public People(Integer pid, String pname) {
        this.pid = pid;
        this.pname = pname;
    }
​
    private Card card;
}

对card表的处理,私有化属性即可

public class Card {
​
  private Integer cid;
  private String cardnum;
  private Integer pid;
​
}

3、 mapper 中生命OnetoOne接口文件和xml文件

//接口文件
public interface OnetoOne {
    People findById(int id);
}
// 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">
<mapper namespace="com.zking.mapper.OnetoOne">
    <select id="findById" resultMap="people_card">
        select * from people where pid=#{id}
    </select>
    <resultMap id="people_card" type="people">
        <id property="pid" column="pid"></id>
        <association property="card" select="getCard" column="pid"></association>
    </resultMap>
​
    <select id="getCard" resultType="card">
        select * from card where pid=#{id}
    </select>
</mapper>

4、测试类

public class OneToOne {
    @Test
    public void test1(){
        SqlSessionFactory sf = SqlSessionFactoryUtil.sf();
        SqlSession sqlSession = sf.openSession();
        OnetoOne oto = sqlSession.getMapper(OnetoOne.class);
        People byId = oto.findById(111);
        System.out.println(byId.getCard());
    }
}

5、 运行结果

一对一查询结果.png

6、 一对多的两张表进行联查基本步骤

这个和一对一查询的步骤唯一的区别在于,将association 改成 collection 其他步骤都是一样的

一对多唯一区别.png

三、缓存

【重点】一级缓存和二级缓存的区别:

  • 一级缓存的作用域是一个sqlsession内;
  • 二级缓存作用域是针对mapper进行缓存;
  • 一级缓存是SqlSession级别的缓存,一级缓存缓存的是对象,当SqlSession提交、关闭以及其他的更新数据库的操作发生后,一级缓存就会清空。 二级缓存是SqlSessionFactory级别的缓存,同一个SqlSessionFactory产生的SqlSession都共享一个二级缓存,二级缓存中存储的是数据,当命中二级缓存时,通过存储的数据构造对象返回
  • 查询数据的时候,查询的流程是二级缓存>一级缓存>数据库
public class HuanCun {
        /*
        *   一级缓存是sqlsession级别,同一SQL session对象共享
            默认开启不可关闭,不需要任何设置
    * */
    @Test
    public void HUanCun() {
        SqlSessionFactory sf = SqlSessionFactoryUtil.sf();
        SqlSession sqlSession1 = sf.openSession();
        SqlSession sqlSession2 = sf.openSession();
​
        EmpMapper em = sqlSession1.getMapper(EmpMapper.class);
        List<Emp> list = em.findAll();
        System.out.println(list);
​
//        模拟增删改查,清空缓存
        sqlSession1.commit();
​
        System.out.println("===============");
        List<Emp> list1 = em.findAll();
        System.out.println(list1);
    }
}