MyBatisMyBatis 详解(一对一,一对多,多对多)

4、MyBatis 入门实例  一对多,多对一  按照xml配置

  那里大家以班级和学员为例,一个班级内部对应多少个学生,那是一对多;反过来,多少个学生对应一个班级,那是多对一

  ①、建立学生和班级的实体类

  Student.java

package one.to.many;

public class Student {
    private int sid;
    private String sname;
    private Classes classes;
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public Classes getClasses() {
        return classes;
    }
    public void setClasses(Classes classes) {
        this.classes = classes;
    }
    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + ", classes=" + classes + "]";
    }

}

    Classes.java

package one.to.many;

import java.util.Set;

public class Classes {
    private int cid;
    private String cname;
    private Set<Student> students;

    public int getCid() {
        return cid;
    }
    public void setCid(int cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    @Override
    public String toString() {
        return "Classes [cid=" + cid + ", cname=" + cname + ", students=" + students + "]";
    }
}

  

  ②、在数据库中依据实体类创造相应的数据表

 

  ③、多对一:定义操作 Classes 表的sql映射文件classesMapper.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="one.to.many.classesMapper">
    <select id="getClasses" resultMap="getClassesMap">
        select * from classes c,student s where s.cid=c.cid and c.cid=#{cid}
    </select>
    <resultMap type="one.to.many.Classes" id="getClassesMap">
        <id column="cid" property="cid"></id>
        <result column="cname" property="cname"/>
        <collection property="students" ofType="one.to.many.Student">
            <id column="sid" property="sid"/>
            <result column="sname" property="sname"/>
        </collection>
    </resultMap>

</mapper>

  ④、一对多:定义操作 Student 表的sql映射文件studentMapper.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="many.to.one.studentMapper">
    <select id="getStudents" resultMap="getStudentMap">
        select * from classes c,student s where s.cid=c.cid and s.sid=#{sid}
    </select>
    <resultMap type="one.to.many.Student" id="getStudentMap">
        <id column="sid" property="sid"></id>
        <result column="sname" property="sname"/>
        <association property="classes" javaType="one.to.many.Classes">
            <id column="cid" property="cid"/>
            <result column="cname" property="cname"/>
        </association>
    </resultMap>

</mapper>

  ⑤、向 mybatis-configuration.xml 配置文件中注册 classesMapper.xml
、studentMapper.xml文件

  ⑥、编写测试类

package one.to.many;

import java.io.InputStream;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import com.ys.test.MyBatisTest;

public class OneToManyTest {
SqlSession session;

    @Before
    public void beforeLoadXML(){
        //加载 mybatis 配置文件
        InputStream inputStream = MyBatisTest.class.
                getClassLoader().getResourceAsStream("mybatis-configuration.xml");
        //构建sqlSession的工厂
        SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(inputStream);
        //根据 sqlSessionFactory 产生 session
        session = sqlSessionFactory.openSession();
    }

    //一对多嵌套结果方式:根据班级id查询班级所有的学生信息
    @Test
    public void testGetClasses(){
        String statement = "one.to.many.classesMapper.getClasses";
        Classes c = session.selectOne(statement, 1);
        System.out.println(c);
        System.out.println(c.getStudents().size());
    }


    //多对一嵌套结果方式:根据学生id查询班级信息
    @Test
    public void testGetStudents(){
        String statement = "many.to.one.studentMapper.getStudents";
        Student s = session.selectOne(statement, 1);
        System.out.println(s);
        System.out.println(s.getClasses());
    }



}

 

3、MyBatis 入门实例表明配置

   ①、下面的眼前四步都是一律的,不过第五步不雷同,大家不必要创设personMapper.xml 文件,首先在 src 目录下创办 personMapper.java 文件

  MyBatis 1

   内容如下:

package com.ys.annocation;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import com.ys.bean.Person;

public interface PersonMapper {

    @Insert("insert into person(pid,pname,page) values(#{pid},#{pname},#{page})")
    public int add(Person person); 

    @Select("select * from person where pid = #{pid}")
    public Person getPerson(int pid);

    @Update("update person set pname=#{pname},page=#{page} where pid = #{pid}")
    public int updatePerson(Person preson);

    @Delete("delete from person where pid=#{pid}")
    public int deletePerson(int pid);

}

  ②、向 mybatis-configuration.xml 配置文件中登记 personMapper.xml
文件

MyBatis 2

 

   ③、编写测试类

   @Test
    public void testAnnocation(){
        PersonMapper mapper = session.getMapper(PersonMapper.class);
        Person p = new Person();
        p.setPid(7);
        p.setPname("abc");
        p.setPage(11);
        //调用增加方法
        mapper.add(p);
        //调用查询方法
        Person p1 = mapper.getPerson(3);
        System.out.println(p1);
        //调用更新方法
        p.setPage(100);
        mapper.updatePerson(p);
        //调用删除方法
        mapper.deletePerson(7);
        session.commit();
        session.close();
    }

 

4、MyBatis 入门实例  一对一  根据xml配置

  那里我们以名师和班级为例,假若一般班级只好拥有有一个助教,一个助教只好带一个班级。

  ①、创设实体类

  MyBatis 3

 

  Teacher.java

package one.to.one;

public class Teacher {
    private int tid;
    private String tname;
    private Classes classes;

    public int getTid() {
        return tid;
    }
    public void setTid(int tid) {
        this.tid = tid;
    }
    public String getTname() {
        return tname;
    }
    public void setTname(String tname) {
        this.tname = tname;
    }
    public Classes getClasses() {
        return classes;
    }
    public void setClasses(Classes classes) {
        this.classes = classes;
    }
    @Override
    public String toString() {
        return "Teacher [tid=" + tid + ", tname=" + tname + ", classes=" + classes + "]";
    }


}

  Classes.java

package one.to.one;

public class Classes {
    private int cid;
    private String cname;
    private Teacher teacher;

    public int getCid() {
        return cid;
    }
    public void setCid(int cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    @Override
    public String toString() {
        return "Classes [cid=" + cid + ", cname=" + cname + ", teacher=" + teacher + "]";
    }

}

 

  ②、在数据库中依照实体类成立相应的数据表

 

  ③、概念操作 Classes 表的sql映射文件classesMapper.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="one.to.one.classesMapper">
    <!-- 
         方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
                 封装联表查询的数据(去除重复的数据)
         select * from classes c, teacher t where c.tid=t.tid and c.tid=#{tid}
     -->
    <select id="getClasses" resultMap="getClassesMap" parameterType="int">
        select * from classes c ,teacher t 
            where c.tid=t.tid and c.tid=#{tid}
    </select>
    <resultMap type="one.to.one.Classes" id="getClassesMap">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <association property="teacher" javaType="one.to.one.Teacher">
            <id column="tid" property="tid"></id>
            <result column="tname" property="tname"/>
        </association>
    </resultMap>
    <!-- 
         方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
                 封装联表查询的数据(去除重复的数据)
         select * from teacher t,classes c where t.cid = c.cid and t.cid=#{cid}
     -->
    <select id="getTeacher" resultMap="getTeacherMap" parameterType="int">
        select * from teacher t,classes c
            where t.cid = c.cid and t.cid=#{cid}
    </select>
    <resultMap type="one.to.one.Teacher" id="getTeacherMap">
        <id column="tid" property="tid"/>
        <result column="tname" property="tname"/>
        <association property="classes" javaType="one.to.one.Classes">
            <id column="cid" property="cid"/>
            <result column="cname" property="cname"/>
        </association>
    </resultMap>


    <!-- 
         方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
         SELECT * FROM classes WHERE cid=1;
         SELECT * FROM teacher WHERE tid=1   //1 是上一个查询得到的tid的值
         property:别名(属性名)    column:列名 -->
          <!-- 把teacher的字段设置进去 -->
    <select id="getClasses2" resultMap="getClassesMap2">
        select * from classes c where c.cid = #{cid}
    </select>
    <resultMap type="one.to.one.Classes" id="getClassesMap2">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <collection property="teacher" column="tid" select="getTeacherCollection">
        </collection>
    </resultMap>
    <select id="getTeacherCollection" resultType="one.to.one.Teacher">
        select tid tid,tname tname from teacher where tid=#{tid}
    </select>

</mapper>

  表达:大家那里非凡的涉及操作,有三种办法:

    1、使用嵌套结果映射来处理重复的一头结果的子集

    2、通过举行别的一个SQL映射语句来回到预期的繁杂类型

    相关属性解释:

    MyBatis 4

 

  ④、向 mybatis-configuration.xml 配置文件中登记 classesMapper.xml
文件

  MyBatis 5

  ⑤、编写测试类

package one.to.one;

import java.io.InputStream;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import com.ys.test.MyBatisTest;

public class OneToOneTest {
SqlSession session;

    @Before
    public void beforeLoadXML(){
        //加载 mybatis 配置文件
        InputStream inputStream = MyBatisTest.class.
                getClassLoader().getResourceAsStream("mybatis-configuration.xml");
        //构建sqlSession的工厂
        SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(inputStream);
        //根据 sqlSessionFactory 产生 session
        session = sqlSessionFactory.openSession();
    }

    //一对一嵌套结果方式:根据教师id查询班级信息
    @Test
    public void testGetClasses(){
        String statement = "one.to.one.classesMapper.getClasses";
        Classes c = session.selectOne(statement, 1);
        System.out.println(c);
    }

    //一对一嵌套结果方式:根据班级id查询教师信息
    @Test
    public void testGetTeacher(){
        String statement = "one.to.one.classesMapper.getTeacher";
        Teacher t = session.selectOne(statement, 1);
        System.out.println(t);
    }

    //一对一嵌套查询方式:根据教师id查询班级信息
    @Test
    public void testGetClasses2(){
        String statement = "one.to.one.classesMapper.getClasses2";
        Classes c = session.selectOne(statement, 1);
        System.out.println(c);
    }



}

  

 

1、什么是MyBatis?

  MyBatis 本是apache的一个开源项目iBatis, 二零一零年这么些项目由apache
software foundation 迁移到了google code,并且改名为MyBatis
。二〇一三年12月动迁到Github。

  iBATIS一词来源于“internet”和“abatis”的结缘,是一个基于Java的持久层框架。iBATIS提供的持久层框架包涵SQL
Maps和Data Access Objects(DAO)。

  MyBatis 是支撑普通
SQL查询,存储进度和高档映射的非凡持久层框架。MyBatis
消除了大约拥有的JDBC代码和参数的手工安装以及结果集的追寻。MyBatis
使用简便的 XML或表明用于配置和原始映射,将接口和 Java 的POJOs(Plain
Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。

PS:本文所有代码下载链接:http://pan.baidu.com/s/1gf8CPQN 密码:t2x9 

2、MyBatis 入门实例基于xml配置

  ①、创建MySQL数据库:mybatisDemo和表:person

create database mybatisDemo;
use mybatisDemo;
create table person(pid int primary key AUTO_INCREMENT, pname varchar(50), page int);

  MyBatis 6

 

  ②、建立一个Java工程,并导入相应的jar包

   MyBatis 7

  相应的 jar 包下载链接:http://pan.baidu.com/s/1skZM09Z  密码:nkt6

  

   ③、在 MyBatisDemo
工程中添加数据库配置文件 mybatis-configuration.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境   
  一、development:开发模式
   二、work:工作模式-->
 <environments default="development">
 <!--id属性必须和上面的default一样  -->
    <environment id="development">
    <!--事务管理器
        一、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围
        二、MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期
            比如 spring 或 JEE 应用服务器的上下文,默认情况下,它会关闭连接。然而一些容器并不希望这样,
            因此如果你需要从连接中停止它,就可以将 closeConnection 属性设置为 false,比如:
            <transactionManager type="MANAGED">
                <property name="closeConnection" value="false"/>
            </transactionManager>
      -->
      <transactionManager type="JDBC"/>
      <!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源  -->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
  </environments>
</configuration>

  

  ④、定义表所对应的实体类

  MyBatis 8

package com.ys.bean;

public class Person {
    private int pid;
    private String pname;
    private int page;

    public int getPid() {
        return pid;
    }
    public void setPid(int pid) {
        this.pid = pid;
    }
    public String getPname() {
        return pname;
    }
    public void setPname(String pname) {
        this.pname = pname;
    }
    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page;
    }
    @Override
    public String toString() {
        return "Person [pid=" + pid + ", pname=" + pname + ", page=" + page
                + "]";
    }
}

  

  ⑤、定义操作 person 表的sql映射文件personMapper.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.ys.bean.personMapper">
  <!-- 根据 pid 查询 person 表中的数据
       id:唯一标识符,此文件中的id值不能重复
       resultType:返回值类型,一条数据库记录也就对应实体类的一个对象
       parameterType:参数类型,也就是查询条件的类型
   -->
  <select id="selectPersonById" 
            resultType="com.ys.bean.Person" parameterType="int">
    <!-- 这里和普通的sql 查询语句差不多,对于只有一个查询条件后面的 #{pid}表示占位符,里面不一定要写pid,写啥都可以,但是不要空着;如果有多个查询条件,则要写pojo类里面的属性 -->
    select * from person where pid = #{pid}
  </select>

  <!-- 查询person 表所有数据 -->
  <select id="getAllPerson" resultType="com.ys.bean.Person">
    select * from person
  </select>

  <!-- 根据id更新数据 -->
  <update id="updatePersonById" parameterType="com.ys.bean.Person">
    update person set pname=#{pname},page=#{page} where pid = #{pid}
  </update>

  <!-- 向 person 表插入一条数据 -->
  <insert id="addPerson" parameterType="com.ys.bean.Person">
    insert into person(pid,pname,page) values(#{pid},#{pname},#{page})
  </insert>

  <!-- 根据 pid 删除数据 -->
  <delete id="deletePersonById" parameterType="Long">
    delete from person where pid=#{pid}
  </delete>

</mapper>

  

  ⑥、向 mybatis-configuration.xml 配置文件中登记 personMapper.xml
文件

  <mappers>
         <!-- 注册personMapper.xml文件, 
         personMapper.xml位于com.ys.bean这个包下,所以resource写成com/ys/bean/personMapper.xml-->
         <mapper resource="com/ys/bean/personMapper.xml"/>
  </mappers>

  如下图所示:

MyBatis 9

 

MyBatis,   ⑦、创设测试类

package com.ys.test;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import com.ys.bean.Person;

public class MyBatisTest {
    SqlSession session;

    @Before
    public void beforeLoadXML(){
        //加载 mybatis 配置文件
        InputStream inputStream = MyBatisTest.class.
                getClassLoader().getResourceAsStream("mybatis-configuration.xml");
        //构建sqlSession的工厂
        SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(inputStream);
        //根据 sqlSessionFactory 产生 session
        session = sqlSessionFactory.openSession();
    }

    //根据 pid 查询 person 表中的数据
    @Test
    public void testSelectById(){
        //这个字符串有 personMapper.xml 文件中 两个部分构成
        //<mapper namespace="com.ys.bean.personMapper"> 的 namespace 的值
        //<select id="selectPersonById" > id 值
        String statement = "com.ys.bean.personMapper"+".selectPersonById";
        Person p = session.selectOne(statement, 1);
        System.out.println(p);
        session.close();
    }

    //查询person 表所有数据
    @Test
    public void testGetAllPerson(){
        String statement = "com.ys.bean.personMapper.getAllPerson";
        List<Person> listPerson = session.selectList(statement);
        System.out.println(listPerson);
        session.close();
    }

    //根据id更新数据 
    @Test
    public void updateById(){
        String statement = "com.ys.bean.personMapper.updatePersonById";
        Person p = new Person();
        p.setPid(1);
        p.setPname("aaa");
        p.setPage(11);
        session.update(statement, p);
        session.commit();
        session.close();
    }

    //向 person 表插入一条数据
    @Test
    public void addPerson(){
        String statement = "com.ys.bean.personMapper.addPerson";
        Person p = new Person();
        //由于我们设置了主键的自增长机制,故这里不需要手动设置 pid 的值
        //p.setPid(1);
        p.setPname("add");
        p.setPage(11);
        session.insert(statement, p);
        session.commit();
        session.close();
    }

    //根据 pid 删除person 表中的数据
    @Test
    public void deletePersonById(){
        String statement = "com.ys.bean.personMapper.deletePersonById";
        session.delete(statement, 1);
        session.commit();
        session.close();

    }


}

  

 

5、MyBatis 入门实例  多对多  基于xml配置

  那里大家以 users 表和 groups 表为例,一个 users 可能参与多个groups,而一个 groups 可能带有多少个 users,故构成 多对多 的关系

  ①、在数据库中建立相应的表

  users 表

  MyBatis 10

  groups 表

  MyBatis 11

  两者之间的涉嫌表users_groups表

  MyBatis 12

  ②、建立相应的实体类

  Users.java

package many.to.many;

import java.util.Set;

public class Users {
    private int uid;
    private String uname;
    private Set<Groups> groups;
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public Set<Groups> getGroups() {
        return groups;
    }
    public void setGroups(Set<Groups> groups) {
        this.groups = groups;
    }
    @Override
    public String toString() {
        return "User [uid=" + uid + ", uname=" + uname + ", groups=" + groups + "]";
    }

}

    Groups.java

package many.to.many;

import java.util.Set;

public class Groups {
    private int gid;
    private String gname;
    private Set<Users> users;
    public int getGid() {
        return gid;
    }
    public void setGid(int gid) {
        this.gid = gid;
    }
    public String getGname() {
        return gname;
    }
    public void setGname(String gname) {
        this.gname = gname;
    }
    public Set<Users> getUsers() {
        return users;
    }
    public void setUsers(Set<Users> users) {
        this.users = users;
    }
    @Override
    public String toString() {
        return "Group [gid=" + gid + ", gname=" + gname + ", users=" + users + "]";
    }

}

    Users_Groups.java

package many.to.many;

public class Users_Groups {
    private Users user;
    private Groups group;
    public Users getUser() {
        return user;
    }
    public void setUser(Users user) {
        this.user = user;
    }
    public Groups getGroup() {
        return group;
    }
    public void setGroup(Groups group) {
        this.group = group;
    }

}

  ③、多对多:定义操作 sql映射文件userMapper.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="many.to.many.userMapper">
    <!-- 给一个用户 id,查看该用户下的所有用户组信息 -->
    <select id="getUsers" resultMap="getGroupMap">
        select g.gid,g.gname from users_groups ug,groups g 
            where ug.group_id=g.gid and ug.user_id=#{uid}
    </select>
    <resultMap type="many.to.many.Groups" id="getGroupMap">
        <id column="gid" property="gid"/>
        <result column="gname" property="gname"/>
        <collection property="users" ofType="many.to.many.Users">
            <id column="uid" property="uid"/>
        <result column="uname" property="uname"/>
        </collection>
    </resultMap>

</mapper>

  

  ⑤、向 mybatis-configuration.xml
配置文件中注册 userMapper.xml文件

  ⑥、编写测试类

//多对多:根据根据用户 id 查询所有的用户组信息
    @Test
    public void testGetGroups(){
        String statement = "many.to.many.userMapper.getUsers";
        List<Groups> listGroup = session.selectList(statement,1);
        for(Groups g : listGroup){
            System.out.println(g.toString());
        }
    }

  

 

网站地图xml地图