day02——mybatis

回顾

创建和配置映射文件

<mapper namespace="">
	<select id="selectById" parameterType="int" resultType="student">
  	select * from student where id=#{id}
  </select>
  <insert></insert>
  <update></update>
  <delete></delete>
</mapper>

创建和配置核心文件

<typeAliases>
  <package name="com.itheima.bean"></package>
</typeAliases>
<environments default="mysql">
  <environment id="mysql">
    	<transactionManager type="jdbc"></transactionManager>
    	<dataSource type="pooled">
        <property name="" value=""></property>
      </dataSource>
  </environment>
</environments>
<mappers>
  <mapper resource="映射文件位置"></mapper>
</mappers>

测试类编编码测试

1、加载核心配置文件
2、获取工厂对象
3、获取SqlSession核心对象
4、执行操作获取结果
5、处理/打印结果
6、释放资源


昨天:    操作 数据库的时候, 使用 mybatis
     a) 没有写接口  
     b) 写接口, 写实现类
     c) 只写接口, 不写实现类 (mybatis 会根据你的接口产生 代理 对象, )
        
        sqlSession.selectList
       

【第一章】接口代理方式实现Dao【重要】

1 接口代理的要求【记住】

'1、映射配置文件中的名称空间要和接口的全类名相同
'2、映射配置文件中标签的id属性值要和接口的方法名相同     形象比喻为namespace+id=接口全类名+方法名
3、映射配置文件中标签的parameterType属性值要和方法的参数类型一致
4、映射配置文件中标签的resultType属性值要和方法的返回值类型一致

在这里插入图片描述

2 代码演示

第一步:准备接口
package com.itheima.mapper;

/*
    持久层接口
 */
public interface StudentMapper {
    //查询全部
    public abstract List<Student> selectAll();
    //根据id查询
    public abstract Student selectById(Integer id);
    //新增数据
    public abstract Integer insert(Student stu);
    //修改数据
    public abstract Integer update(Student stu);
    //删除数据
    public abstract Integer delete(Integer id);
    //多条件查询
    public abstract List<Student> selectCondition(Student stu);
    //根据多个id查询
    public abstract List<Student> selectByIds(List<Integer> ids);
}
第二步:编写/修改映射文件
<!--namespace="com.itheima.mapper.StudentMapper" :接口的全类名-->

<mapper namespace="com.itheima.mapper.StudentMapper">
  
  
  <!--id必须是接口的方法名-->
  <!--查询所有学生信息-->
  <select id="selectAll" resultType="student">
    select * from student
  </select>

  <!--根据id查询学生信息-->
  <select id="selectById" parameterType="int" resultType="student">
    select * from student where id=#{ID}
  </select>

  <!--添加学生-->
  <insert id="insert" parameterType="student">
    insert into student values(null,#{name},#{age})
  </insert>

  <!--修改学生信息-->
  <update id="update" parameterType="student">
    update student set name=#{name},age=#{age} where id=#{id}
  </update>

  <!--删除学生信息-->
  <delete id="delete" parameterType="int">
    delete from student where id=#{id}
  </delete>
</mapper>
第三步:编程测试类测试
public class StudentTest {

  @Test
  public void testSelectAll() throws IOException {
    //1、加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
    //2、获取工厂对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //3、获取SqlSession核心对象
    SqlSession sqlSession = factory.openSession(true);
    
    //4、获取接口的实现类代理对象,执行操作
    //返回了一个代理对象, 这个 代理对象 是通过 jdk的 动态代理来实现的 
    // Proxy.newInstance();
    
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
    
    List<Student> list = mapper.selectAll();
    
    
    //5、处理/打印结果
    list.forEach(stu-> System.out.println(stu));
    //6、释放资源
    sqlSession.close();
  }


  @Test
  public void testSelectById() throws IOException {
    //1、加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
    //2、获取工厂对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //3、获取SqlSession核心对象
    SqlSession sqlSession = factory.openSession(true);
    
    //4、获取接口的实现类代理对象,执行操作
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Student student = mapper.selectById(3);
    //5、处理/打印结果
    System.out.println(student);
    //6、释放资源
    sqlSession.close();
  }

  @Test
  public void testSelectDelete() throws IOException {
    //1、加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
    //2、获取工厂对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //3、获取SqlSession核心对象
    SqlSession sqlSession = factory.openSession(true);
    //4、获取接口的实现类代理对象,执行操作
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Integer count = mapper.delete(8);
    //5、处理/打印结果
    System.out.println("count = " + count);//返回影响的行数
    //6、释放资源
    sqlSession.close();
  }
}

总结

1.	掌握接口代理的要求

2.  跟踪源代码 后发现 两个点:  --- 了解 

   第一个点:
			 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); 拿到了 代理对象, 代理对象是怎么产生的呢?
       跟源代码后发现 最后调用到了 Proxy.newInstace(...) , 这个代码就是之前咱们学习的  动态代理的代码.

   第二个点:
       拿到代理对象后, 调用 select, insert 这样的方法, 最后 跟踪 发现,  还是 使用到了 sqlSession 中的select, insert 这样的方法来操作 数据库的 
         
         
      比敲强的 学习能力, 喜欢翻看框架源代码,  例如 , 翻看 mybatis 的源代码, 熟系mybatis 底层的一些代码的原理.   

【第二章】动态SQL【理解】

1 使用场景

搜索、筛选…

在这里插入图片描述

2 if 标签判断[重要]

第一步:配置SQL
<!--多条件查询-->
<select id="selectCondition" resultType="student" parameterType="student">
  select * from student
  <where>
    <!--test="" 是判断条件-->
    <if test="id != null">
      id=#{id}
    </if>
    <if test="name != null and name !='' ">
      and name=#{name}
    </if>
    <if test="age != null">
      and age=#{age}
    </if>
  </where>
</select>
第二步:测试
@Test
public void testSelectCondition() throws IOException {
  //1、加载核心配置文件
  InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
  //2、获取工厂对象
  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
  //3、获取SqlSession核心对象
  SqlSession sqlSession = factory.openSession(true);
  //4、获取接口的实现类代理对象,执行操作
  StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
  //创建条件
  Student stu=new Student();
  //stu.setId(2);
  stu.setAge(25);
  //执行查询
  List<Student> list = mapper.selectCondition(stu);
  
  //5、处理/打印结果
  list.forEach(student -> System.out.println(student));
  //6、释放资源
  sqlSession.close();
}

3 foreach标签遍历–了解

第一步:配置SQL
<!--多条件查询-->
<select id="selectByIds" resultType="student">
  select * from student
  <where>
    <!--
                collection="" 遍历数组写array,遍历集合写list,遍历map集合写map
                open="id in(" 以xxx开头
                close=")" 以xxx结尾
                item="" 遍历的每一个元素的名称,变量名随便写,写啥后面就用啥
                separator="," 分隔符
                index="" 如果遍历的是数组或者单列集合,就表示索引。如果遍历的是map就表示key
            -->
    <foreach collection="list" open="id in(" close=")" item="id" separator=",">
      <!--#{id} 大括号中的名称就是item的属性值-->
      #{id}
    </foreach>
  </where>
</select>

select * from student where id in(1,2,3,4)
第二步:测试
@Test
public void testSelectByIds() throws IOException {
  //1、加载核心配置文件
  InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
  //2、获取工厂对象
  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
  //3、获取SqlSession核心对象
  SqlSession sqlSession = factory.openSession(true);
  //4、获取接口的实现类代理对象,执行操作
  StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
	
  //创建条件
  List<Integer> ids = List.of(1, 2,3);
  //执行查询
  List<Student> list = mapper.selectByIds(ids);
  //5、处理/打印结果
  list.forEach(student -> System.out.println(student));
  //6、释放资源
  sqlSession.close();
}

4: 动态sql的小结


1.  if 标签 大家需要掌握 , 这个以后用的 多一些

2.  foreach 了解, 以后用的不是那么多

3.  sql, include 标签, 用于 抽取 重复的sql语句, 以及 引用 抽取的 sql语句
		 <sql id="ss">select * from student</sql>

    <!--id必须是接口的方法名-->
    <select id="selectAll" resultType="student">
      <include refid="ss"/>
    </select>

【第三章】分页插件【重要】

【第一步】导入开发jar包

​ jsqlparser-3.1.jar 和pagehelper-5.1.10.jar , 记得要 add as library

【第二步】在mybatis的核心配置文件中集成分页插件

<!--集成PageHelper分页插件-->
<plugins>
  <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

【第三步】在查询所有信息之前设置查询的页数和每页展示条数

@Test
public void testSelectAll() throws IOException {
  //1、加载核心配置文件
  InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
  //2、获取工厂对象
  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
  //3、获取SqlSession核心对象
  SqlSession sqlSession = factory.openSession(true);
  //4、获取接口的实现类代理对象,执行操作
  StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

  //使用分页助手设置页数和每页条数
  PageHelper.startPage(1,3); //------------------------------

  List<Student> list = mapper.selectAll();
  
 
  
  //5、处理/打印结果
  list.forEach(stu-> System.out.println(stu));
  //6、释放资源
  sqlSession.close();
}

【第四步】在获取分页数据之后封装分页信息

@Test
public void testSelectAll() throws IOException {
  //1、加载核心配置文件
  InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
  //2、获取工厂对象
  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
  //3、获取SqlSession核心对象
  SqlSession sqlSession = factory.openSession(true);
  //4、获取接口的实现类代理对象,执行操作
  StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

  //使用分页助手设置页数和每页条数
  //参数1:当前页码,参数2:每页显示条数
  PageHelper.startPage(1,3); //------------------------------

  List<Student> list = mapper.selectAll();

  //封装分页信息
  PageInfo<Student> info=new PageInfo<>(list);//---------------------------
  
  
  //打印分页信息
  System.out.println("当前页数:"+info.getPageNum());  //1
  System.out.println("每页展示条数:"+info.getPageSize()); //3
  System.out.println("总页数:"+info.getPages());
  System.out.println("总条数:"+info.getTotal());
  System.out.println("当前页条数:"+info.getSize());
  System.out.println("上一页:"+info.getPrePage());
  System.out.println("下一页:"+info.getNextPage());
  System.out.println("是否是第一页:"+info.isIsFirstPage());
  System.out.println("是否是最后一页:"+info.isIsLastPage());

  //5、处理/打印结果
  list.forEach(stu-> System.out.println(stu));
  //6、释放资源
  sqlSession.close();
}

【第四章】mybatis多表操作【重要】

数据库准备

CREATE DATABASE db2;

USE db2;

-- 一对一
CREATE TABLE person(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(20),
  age INT
);

INSERT INTO person VALUES (NULL,'张三',23);
INSERT INTO person VALUES (NULL,'李四',24);
INSERT INTO person VALUES (NULL,'王五',25);

CREATE TABLE card(
  id INT PRIMARY KEY AUTO_INCREMENT,
  number VARCHAR(30),
  pid INT,
  CONSTRAINT cp_fk FOREIGN KEY (pid) REFERENCES person(id)
);

INSERT INTO card VALUES (NULL,'12345',1);
INSERT INTO card VALUES (NULL,'23456',2);
INSERT INTO card VALUES (NULL,'34567',3);


-- 一对多
CREATE TABLE classes( -- 班级表
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(20)
);
INSERT INTO classes VALUES (NULL,'黑马一班');
INSERT INTO classes VALUES (NULL,'黑马二班');


CREATE TABLE student( -- 学生表
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(30),
  age INT,
  cid INT,
  CONSTRAINT cs_fk FOREIGN KEY (cid) REFERENCES classes(id)
);
INSERT INTO student VALUES (NULL,'张三',23,1);
INSERT INTO student VALUES (NULL,'李四',24,1);
INSERT INTO student VALUES (NULL,'王五',25,2);
INSERT INTO student VALUES (NULL,'赵六',26,2);

-- 多对多
CREATE TABLE course(-- 课程
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(20)
);
INSERT INTO course VALUES (NULL,'语文');
INSERT INTO course VALUES (NULL,'数学');


CREATE TABLE stu_cr(
  id INT PRIMARY KEY AUTO_INCREMENT,
  sid INT,
  cid INT,
  CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id),
  CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id)
);
INSERT INTO stu_cr VALUES (NULL,1,1);
INSERT INTO stu_cr VALUES (NULL,1,2);
INSERT INTO stu_cr VALUES (NULL,2,1);
INSERT INTO stu_cr VALUES (NULL,2,2);

一对一关系

1 javabean类
public class Card {
    private Integer id;     //主键id
    private String number;  //身份证号
  
    private Person p;       //所属人的对象
  
}
public class Person {
    private Integer id;     //主键id
    private String name;    //人的姓名
    private Integer age;    //人的年龄
}
2 接口类
public interface OneToOneMapper {
    //查询全部
    public abstract List<Card> selectAll();
}
3 映射文件配置OneToOneMapper.xml

resultMap标签的作用:手动定义查询结果和bean对象的映射关系,一般用来处理查询结果和bean的属性不一致情况。

<?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.mapper.OneToOneMapper">
  <!--配置查询结果和bean对象的对应关系-->
  <resultMap id="oneToOne" type="card">
    <!--封装主键信息,column="id"列名称,property="id"bean中的属性名称-->
    <id column="id" property="id"/>
    <!--封装非主键信息-->
    <result column="number" property="number"/>
    <!--配置包含的对象映射关系,配置一对一关系,javaType="person"表示bean的属性类型-->
    
    <association property="p" javaType="person">
      <!--封装主键信息-->
      <id column="pid" property="id"/>
      <!--封装非主键信息-->
      <result column="name" property="name"/>
      <result column="age" property="age"/>
    </association>
    
  </resultMap>

  <!-- 测试一对一关系:查询所有card的信息,包括每个card对应的person信息-->
  <select id="selectAll" resultMap="oneToOne">
    select c.*,p.NAME,p.age from card c ,person p where c.pid=p.id;
  </select>
  
</mapper>

注意:封装结果集不再使用resultType属性,而是使用resultMap属性。

4 测试类
/*
        测试一对一关系:查询所有card的信息,包括每个card对应的person信息
     */
@Test
public void testOneToOneMapper(){
  //加载资源
  SqlSession sqlSession = null;
  try {
    InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
    //获取SqlSessionFactory对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //获取SqlSession对象
    sqlSession = factory.openSession(true);
    //获取mapper接口的代理对象,执行方法
    OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);
    List<Card> cards = mapper.selectAll();
    //打印结果
    cards.forEach(card -> System.out.println(card));
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    //释放资源
    sqlSession.close();
  }
}

一对多关系 重要

1 javabean类
public class Classes {
  private Integer id;     //主键id
  private String name;    //班级名称

  private List<Student> students; //班级中所有学生对象,一个班级中有多名学生
  
  // 生成 get/set 方法 
}

public class Student {
    private Integer id;     //主键id
    private String name;    //学生姓名
    private Integer age;    //学生年龄
  
    // 生成 get/set 方法 
}
2 接口类
public interface OneToManyMapper {
  //查询全部
  public abstract List<Classes> selectAll();
}
3 映射文件配置
<resultMap id="oneToMany" type="Classes">
  <id column="cid" property="id"/>
  <result column="cname" property="name"/>
  <!--将剩下的查询结果映射到students中,映射集合中的对象,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>
4 测试类
/*
        测试一对多关系:查询所有班级以及该班级的所有学生信息
     */
@Test
public void testOneToManyMapper(){
  //加载资源
  SqlSession sqlSession = null;
  try {
    InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
    //获取SqlSessionFactory对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //获取SqlSession对象
    sqlSession = factory.openSession(true);
    //获取mapper接口的代理对象,执行方法
    OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);
    List<Classes> classes = mapper.selectAll();
    //打印结果
    classes.forEach(cla -> System.out.println(cla));
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    if(sqlSession!=null){
      //释放资源
      sqlSession.close();
    }
  }
}

多对多关系重要

1 javabean类
public class Student {
    private Integer id;     //主键id
    private String name;    //学生姓名
    private Integer age;    //学生年龄
    private List<Course> courses;   // 学生所选择的课程集合
}
public class Course {
    private Integer id;     //主键id
    private String name;    //课程名称
}
2 接口类
public interface ManyToManyMapper {
  //查询全部
  public abstract List<Student> selectAll();
}
3 映射文件配置
<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 s.id sid,s.NAME sname,s.age sage,c.id cid,c.NAME cname from student s,stu_cr sc,course c where s.id=sc.sid and c.id=sc.cid;
</select>
4 测试类
/*
        测试多对多关系:查询所有学生及其选课信息
     */
@Test
public void testManyToManyMapper(){
  //加载资源
  SqlSession sqlSession = null;
  try {
    InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
    //获取SqlSessionFactory对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //获取SqlSession对象
    sqlSession = factory.openSession(true);
    //获取mapper接口的代理对象,执行方法
    ManyToManyMapper mapper = sqlSession.getMapper(ManyToManyMapper.class);
    List<Student> list = mapper.selectAll();
    //打印结果
    list.forEach(stu -> System.out.println(stu));
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    if(sqlSession!=null){
      //释放资源
      sqlSession.close();
    }
  }
}

注意:javaType属性和ofType属性的区别?

javaType的值用来表示bean对象的属性类型,ofType的值用来表示集合中元素的类型。

4 .作业:

1. 能够使用 接口的方式, 产生代理, 去使用mybatis,  操作 数据库,  CRUD 
2. 动态sql ,   if 标签的使用  敲会
3. 分页插件 的 使用 弄会
4. mybatis 操作多表,   一对多,  多对多 至少 二 遍 

把之前的 复习复习( 看之前的笔记 ), 预习后面的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值