Java Web学习day18------Mybatis(接口代理、动态SQL、分页、多表操作)

一. 接口代理方式实现Dao

1. 使用注意

(1)映射配置文件中的名称空间要和接口的全类名相同
(2)映射配置文件中标签的id属性值要和接口的方法名相同 形象比喻为namespace+id=接口全类名+方法名
(3)映射配置文件中标签的parameterType属性值要和方法的参数类型一致
(4)映射配置文件中标签的resultType属性值要和方法的返回值类型一致在这里插入图片描述

2. 代码演示

2.1 删除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);
}

2.2 修改映射配置文件(StudentMapper.xml)

只需要修改配置文件中名称空间为接口的全类名 
<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>

2.3 修改service层实现类

public class StudentServiceImpl implements StudentService {

    @Override
    public List<Student> selectAll() {
        //1.获取SqlSession对象(使用自定义的工具类获取)
        SqlSession  sqlSession = MyBatisUtils.getSqlSession();
        //2.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //3.通过实现类对象中的方法来完成操作
        List<Student>  list = mapper.selectAll();
        //4.释放资源
        sqlSession.close();
        //5.返回结果
        return list;
    }

    @Override
    public Student selectById(Integer id) {
        //1.获取SqlSession对象
        SqlSession  sqlSession = MyBatisUtils.getSqlSession();
        //2.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //3.通过实现类对象中的方法来完成操作
        Student stu = mapper.selectById(id);
        //4.释放资源
        sqlSession.close();
        //5.返回结果
        return stu;
    }

    @Override
    public Integer insert(Student stu) {
        //1.获取SqlSession对象
        SqlSession  sqlSession = MyBatisUtils.getSqlSession();
        //2.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //3.通过实现类对象中的方法来完成操作
        Integer result = mapper.insert(stu);
        //4.释放资源
        sqlSession.close();
        //5.返回结果
        return result;
    }

    @Override
    public Integer update(Student stu) {
        //1.获取SqlSession对象
        SqlSession  sqlSession = MyBatisUtils.getSqlSession();
        //2.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //3.通过实现类对象中的方法来完成操作
        Integer result = mapper.update(stu);
        //4.释放资源
        sqlSession.close();
        //5.返回结果
        return result;
    }

    @Override
    public Integer delete(Integer id) {
        //1.获取SqlSession对象
        SqlSession  sqlSession = MyBatisUtils.getSqlSession();
        //2.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //3.通过实现类对象中的方法来完成操作
        Integer result = mapper.delete(id);
        //4.释放资源
        sqlSession.close();
        //5.返回结果
        return result;
    }
}

二. 动态SQL(理解)

1. 使用场景

  搜索、筛选…
在这里插入图片描述

2. if标签判断

2.1 配置SQL

<!--多条件查询-->
<select id="selectCondition" resultType="student" parameterType="student">
	select * from student
	<where>
		<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>

2.2 测试

@Test
public void selectCondition() throws Exception{
	//1.加载核心配置文件
	InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

	//2.获取SqlSession工厂对象
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
	//3.通过工厂对象获取SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	//4.获取StudentMapper接口的实现类对象
	StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
	Student stu = new Student();
	stu.setId(2);
	//stu.setName("李四");
	//stu.setAge(24);
	//5.调用实现类的方法,接收结果
	List<Student> list = mapper.selectCondition(stu);
	//6.处理结果
	for (Student student : list) {
		System.out.println(student);
	}
	//7.释放资源
	sqlSession.close();
	is.close();
}

3. foreach标签遍历

3.1 配置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>

3.2 测试

@Test
public void selectByIds() throws Exception{
	//1.加载核心配置文件
	InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
	//2.获取SqlSession工厂对象
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
	//3.通过工厂对象获取SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	//4.获取StudentMapper接口的实现类对象
	StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
	List<Integer> ids = new ArrayList<>();
	ids.add(1);
	ids.add(2);
	ids.add(3);
	//5.调用实现类的方法,接收结果
	List<Student> list = mapper.selectByIds(ids);
	//6.处理结果
	for (Student student : list) {
		System.out.println(student);
	}
	//7.释放资源
	sqlSession.close();
	is.close();
}

三. 分页插件【重要】

1. 导入开发jar包

  jsqlparser-3.1.jar 和pagehelper-5.1.10.jar

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

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

3. 在查询所有信息之前设置查询的页数和每页展示条数

@Test
public void selectPaging() throws Exception{
	//1.加载核心配置文件
	InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
	//2.获取SqlSession工厂对象
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
	//3.通过工厂对象获取SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	//4.获取StudentMapper接口的实现类对象
	StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
	//通过分页助手来实现分页功能
    //参数1:当前页码,参数2:每页显示条数
	// 第一页:显示3条数据
	//PageHelper.startPage(1,3);//使用分页助手设置页数和每页条数
	// 第二页:显示3条数据
	//PageHelper.startPage(2,3);//使用分页助手设置页数和每页条数
	// 第三页:显示3条数据
	PageHelper.startPage(3,3);//使用分页助手设置页数和每页条数
	//5.调用实现类的方法,接收结果
	List<Student> list = mapper.selectAll();
	//6.处理结果
	for (Student student : list) {
		System.out.println(student);
	}
	//7.释放资源
	sqlSession.close();
	is.close();
}

4. 在查询所有信息之后获取分页相关参数

@Test
public void selectPaging() throws Exception{
	//1.加载核心配置文件
	InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
	//2.获取SqlSession工厂对象
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
	//3.通过工厂对象获取SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	//4.获取StudentMapper接口的实现类对象
	StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
	//通过分页助手来实现分页功能
	//参数1:当前页码,参数2:每页显示条数
	// 第一页:显示3条数据
	//PageHelper.startPage(1,3);//使用分页助手设置页数和每页条数
	// 第二页:显示3条数据
	//PageHelper.startPage(2,3);//使用分页助手设置页数和每页条数
	// 第三页:显示3条数据
	PageHelper.startPage(3,3);//使用分页助手设置页数和每页条数
	//5.调用实现类的方法,接收结果
	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());

	//6.处理结果
	for (Student student : list) {
		System.out.println(student);
	}
	//7.释放资源
	sqlSession.close();
	is.close();
}

四. mybatis多表操作【重要】

1. 数据库准备

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);

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.2 接口类

public interface OneToOneMapper {
    //查询全部
    public abstract List<Card> selectAll();
}

2.3 映射文件配置

  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对象的对应关系-->
	<!--association:配置被包含对象的映射关系
		property:被包含对象的变量名
		javaType:被包含对象的数据类型-->
  <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属性。

2.4 测试类

/*
   测试一对一关系:查询所有card的信息,包括每个card对应的person信息
*/
@Test
public void selectAll() throws Exception{
	//1.加载核心配置文件
	InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
	//2.获取SqlSession工厂对象
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
	//3.通过工厂对象获取SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	//4.获取OneToOneMapper接口的实现类对象
	OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);
	//5.调用实现类的方法,接收结果
	List<Card> list = mapper.selectAll();
	//6.处理结果
	for (Card c : list) {
		System.out.println(c);
	}
	//7.释放资源
	sqlSession.close();
	is.close();
}

3. 一对多关系

3.1 javabean类

public class Classes {
  private Integer id;     //主键id
  private String name;    //班级名称
  private List<Student> students; //班级中所有学生对象,一个班级中有多名学生
}
public class Student {
    private Integer id;     //主键id
    private String name;    //学生姓名
    private Integer age;    //学生年龄
}

3.2 接口类

public interface OneToManyMapper {
  //查询全部
  public abstract List<Classes> selectAll();
}

3.3 映射文件配置

<!--
	collection:配置被包含的集合对象映射关系
	property:被包含对象的变量名
	ofType:被包含对象的实际数据类型
-->
<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>

3.4 测试类

/*
    测试一对多关系:查询所有班级以及该班级的所有学生信息
*/
@Test
public void selectAll() throws Exception{
	//1.加载核心配置文件
	InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
	//2.获取SqlSession工厂对象
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
	//3.通过工厂对象获取SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	//4.获取OneToManyMapper接口的实现类对象
	OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);
	//5.调用实现类的方法,接收结果
	List<Classes> classes = mapper.selectAll();
	//6.处理结果
	for (Classes cls : classes) {
		System.out.println(cls.getId() + "," + cls.getName());
		List<Student> students = cls.getStudents();
		for (Student student : students) {
			System.out.println("\t" + student);
		}
	}
	//7.释放资源
	sqlSession.close();
	is.close();
}

4. 多对多关系

4.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;    //课程名称
}

4.2 接口类

public interface ManyToManyMapper {
  //查询全部
  public abstract List<Student> selectAll();
}

4.3 映射文件配置

<!--配置字段和实体对象属性的映射关系-->
	<!--
		collection:配置被包含的集合对象映射关系
		property:被包含对象的变量名
		ofType:被包含对象的实际数据类型
	-->
<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.4 测试类

/*
	测试多对多关系:查询所有学生及其选课信息
*/
@Test
public void selectAll() throws Exception{
	//1.加载核心配置文件
	InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
	//2.获取SqlSession工厂对象
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
	//3.通过工厂对象获取SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	//4.获取ManyToManyMapper接口的实现类对象
	ManyToManyMapper mapper = sqlSession.getMapper(ManyToManyMapper.class);
	//5.调用实现类的方法,接收结果
	List<Student> students = mapper.selectAll();
	//6.处理结果
	for (Student student : students) {
		System.out.println(student.getId() + "," + student.getName() + "," + student.getAge());
		List<Course> courses = student.getCourses();
		for (Course cours : courses) {
			System.out.println("\t" + cours);
		}
	}
	//7.释放资源
	sqlSession.close();
	is.close();
}

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值