MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到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
①、创建MySQL数据库:mybatisDemo和表:person
create database mybatisDemo;
use mybatisDemo;
create table person(pid int primary key AUTO_INCREMENT, pname varchar(50), page int);
②、建立一个Java工程,并导入相应的jar包
相应的 jar 包下载链接:http://pan.baidu.com/s/1skZM09Z 密码:nkt6
③、在 MyBatisDemo 工程中添加数据库配置文件 mybatis-configuration.xml
④、定义表所对应的实体类
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 [p, pname=" + pname + ", page=" + page
+ "]";
}
}
⑤、定义操作 person 表的sql映射文件personMapper.xml
update person set pname=#{pname},page=#{page} where pid = #{pid}
insert into person(pid,pname,page) values(#{pid},#{pname},#{page})
delete from person where pid=#{pid}
⑥、向 mybatis-configuration.xml 配置文件中注册 personMapper.xml 文件
如下图所示:
⑦、创建测试类
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 文件中 两个部分构成
// 的 namespace 的值
//
①、上面的前面四步都是一样的,但是第五步不一样,我们不需要创建 personMapper.xml 文件,首先在 src 目录下创建 personMapper.java 文件
内容如下:
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 文件
③、编写测试类
@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();
}
这里我们以老师和班级为例,假设一般班级只能拥有有一个老师,一个老师只能带一个班级。
①、创建实体类
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 [t, 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 [c, cname=" + cname + ", teacher=" + teacher + "]";
}
}
②、在数据库中根据实体类创建相应的数据表
③、定义操作 Classes 表的sql映射文件classesMapper.xml
说明:我们这里一对一的关联操作,有两种方式:
1、使用嵌套结果映射来处理重复的联合结果的子集
2、通过执行另外一个SQL映射语句来返回预期的复杂类型
相关属性解释:
④、向 mybatis-configuration.xml 配置文件中注册 classesMapper.xml 文件
⑤、编写测试类
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);
}
}
这里我们以班级和学生为例,一个班级里面对应多个学生,这是一对多;反过来,多个学生对应一个班级,这是多对一
①、建立学生和班级的实体类
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 [s, 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 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 getStudents() {
return students;
}
public void setStudents(Set students) {
this.students = students;
}
@Override
public String toString() {
return "Classes [c, cname=" + cname + ", students=" + students + "]";
}
}
②、在数据库中根据实体类创建相应的数据表
③、多对一:定义操作 Classes 表的sql映射文件classesMapper.xml
④、一对多:定义操作 Student 表的sql映射文件studentMapper.xml
⑤、向 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());
}
}
这里我们以 users 表和 groups 表为例,一个 users 可能加入多个 groups,而一个 groups 可能包含多个 users,故构成 多对多 的关联
①、在数据库中建立相应的表
users 表
groups 表
两者之间的关联表users_groups表
②、建立对应的实体类
Users.java
package many.to.many;
import java.util.Set;
public class Users {
private int uid;
private String uname;
private Set 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 getGroups() {
return groups;
}
public void setGroups(Set groups) {
this.groups = groups;
}
@Override
public String toString() {
return "User [u, 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;
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 getUsers() {
return users;
}
public void setUsers(Set users) {
this.users = users;
}
@Override
public String toString() {
return "Group [g, 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
⑤、向 mybatis-configuration.xml 配置文件中注册 userMapper.xml文件
⑥、编写测试类
//多对多:根据根据用户 id 查询所有的用户组信息
@Test
public void testGetGroups(){
String statement = "many.to.many.userMapper.getUsers";
List listGroup = session.selectList(statement,1);
for(Groups g : listGroup){
System.out.println(g.toString());
}
}