一.准备
首先到mybati的网站上下载一个zip的包,里面所需要的jar包和文档,将包导进去,然后在src下面建立一个config.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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="xxxx" />
<property name="url" value="xxxx" />
<property name="username" value="xxxx" />
<property name="password" value="xxxx" />
</dataSource>
</environment>
</environments>
</configuration>
dataSource中就是一些数据库的配置,换成各自的配置就好了,这和hibernate以及jdbc连接的时候是类似的
二.无对应关系
1.创建无对应关系的单表
创建一个班级表,顺便插入两条数据,后面用,如下(主外键这些就不多说了)
2.创建对应实体类
<span style="font-family:SimSun;font-size:14px;">public class Classes {
private int classesid;
private String cname;
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
@Override
public String toString() {
return "Classes [classesid=" + classesid + ", cname=" + cname + "]";
}
}</span>
这样字段和列一一对应上就好了3.编写映射文件
创建一个映射文件,名字为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="mybatis.entity.ClassesMapper">
....
</mapper>
在....中编写对应的配置,namespace是命名空间,后面会用到,这个唯一
下面在mapper标签下编写增删改查语句
<select id="getClassesById" parameterType="int" resultType="mybatis.entity.Classes">
select * from classes where classesid = #{classesid}
</select>
<update id="updateClasses" parameterType="mybatis.entity.Classes">
update classes set cname = #{cname} where classesid = #{classesid}
</update>
<delete id="deleteClasses" parameterType="int">
delete from classes where classesid = #{classesid}
</delete>
<insert id="addClasses" parameterType="mybatis.entity.Classes">
insert into classes(cname) values(#{cname})
</insert>
可以看到,mysql的select,update,delete和insert
对应的标签是一样的,接下来解释一下分别是什么意思
id:唯一标识,调用的时候指定id来执行对应的语句
parameterType:参数类型,select中,需要传入的是id,所以是int类型,而在update中,我们传入的是对象,所以我这里写的是包名加类名,以此指定这个对象的类型
returnType:返回的类型,select会返回一个Classes类的对象,所以写上该对象的类加包名
#{xx}:类似el表达式的${},就是占位符,传进来的参数将会替换这里的占位符
需要注意的是:select中占位符不需要是classesid,这里可以任意,而update中不行,必须是和Classes中的属性对应
4.编写测试类
学过hibernate的都知道,增删改查需要基于session,mybatis也有它的session,增删改查也是基于session的
首先获得一个session
InputStream resourceAsStream = MybatisTest.class.getResourceAsStream("/config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
和hibernate很像,先获得factory再获得session,这里的build有一个重载的方法,由于我把config.xml放在了src下面,所以就用这个方法,另外的就不多说了
SqlSession中有对应的增删改查的方法,分别如下
查找:
查找:
// 查找id为1的班级信息
Classes classes = sqlSession.selectOne("mybatis.entity.ClassesMapper.getClassesById",1);
System.out.println(classes);// 打印出:Classes [classesid=1, cname=一班]
selectOne是用来查找的方法,第一个参数是namespace+id,这在配置文件中已经写好了,后面是要传入sql语句中的参数
更新
// 更新信息
classes.setCname("一班(改)");
sqlSession.update("mybatis.entity.ClassesMapper.updateClasses", classes);
System.out.println(classes);// 打印出:Classes [classesid=1, cname=一班(改)]
update的参数和select一样,由于在配置文件中指定了传入参数是一个对象,所以
二个参数传入classes对象,mybatis会把该对象中属性的值替换到配置中的sql占位符中,所以占位符和该对象中的属性名要对应
删除和增加和上面类似
sqlSession.delete("mybatis.entity.ClassesMapper.deleteClasses", 2);
classes = new Classes();
classes.setCname("二班");
sqlSession.insert("mybatis.entity.ClassesMapper.addClasses", classes);
三.一对一关系
1.创建数据库表
创建一个teacher表,与classes表对应,如下
cid是外键
2.创建实体类
public class Teacher {
private int teacherid;
private String tname;
private Classes clases;
public int getTeacherid() {
return teacherid;
}
public void setTeacherid(int teacherid) {
this.teacherid = teacherid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public Classes getClases() {
return clases;
}
public void setClases(Classes clases) {
this.clases = clases;
}
}
一对一的话,数据库的cid在类中就是一个Classes对象
3.编写映射文件
创建一个映射文件,名字为TeacherMapper.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="mybatis.entity.TeacherMapper">
....
</mapper>
接下来的查找就不一样了,如果需要查找一个老师的信息,顺便把他负责的班级信息给查出来,在mysql中可以使用表连接,如下
select * from classes c,teacher t where t.cid = c.classesid and t.teacherid = 1
这样就查出了老师和班级的信息
所以select标签中的sql是这样写的
<select id="getTeacherByid" parameterType="int" resultMap="">
select * from classes c,teacher t where t.cid = c.classesid and t.teacherid = #{id}
</select>
mysql里面怎么写,这里就怎么写
在单表查询的时候,所有的列会和returnType指定的类对应,然后将值封装成一个对象,一对多的关系中,对象中的属性有对象,classesid,cname就不能简单的封装到teacher中的classes了,必须我们来指定,所以,这里不是returnType而是returnMap,returnMap中的值是这样指定的
<select id="getTeacherById" parameterType="int" resultMap="teacher">
select * from classes c,teacher t where t.cid = c.classesid and t.teacherid = #{id}
</select>
<resultMap id="teacher" type="mybatis.entity.Teacher">
<id property="teacherid" column="teacherid"/>
<result property="tname" column="tname"/>
<association property="classes" javaType="mybatis.entity.Classes">
<id property="classesid" column="classesid"/>
<result property="cname" column="cname"/>
</association>
</resultMap>
returnMap标签可以指定查出来的列和对象之前的对应关系,其中的association用于一对一的关系,这里的type和javaType指的是对象的类型,id与select标签中的returnMap属性对应,这样就可以把查出来的数据封装成一个teacher对象了
测试的代码和一对一中的一样,改变namespace和id就OK了,查出来的数据如下
Teacher [teacherid=1, tname=老师1, classes=Classes [classesid=1, cname=一班]]
四.一对多关系
1.创建数据库表
创建一个学生student表2.创建实体类
public class Student {
private int studentid;
private String sname;
public int getStudentid() {
return studentid;
}
public void setStudentid(int studentid) {
this.studentid = studentid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
@Override
public String toString() {
return "Student [studentid=" + studentid + ", sname=" + sname + "]";
}
}
由于班级和学生是一对多的关系,所以在Classes对象中有一个List,list中集合都是Student对象
public class Classes {
private int classesid;
private String cname;
private List<Student> students = new ArrayList<Student>();
public int getClassesid() {
return classesid;
}
public void setClassesid(int classesid) {
this.classesid = classesid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Classes [classesid=" + classesid + ", cname=" + cname + ", students=" + students + "]";
}
}
3.编写映射文件
Student表的操作就是单表的操作,所以不再叙述,重要的是Classes现在有一个List,所对应的映射文件需要改变
首先我们需要查找Classes已经对应的student的信息,使用表连接,上面的表连接语句得到的结果如下
这里前面班级信息是一样的,后面的3列是不同的两个student信息,我们需要把前面的classes封装到classes对象中,后面的2个student信息封装到student中,配置文件如下
<select id="getClassesById" parameterType="int" resultMap="classes">
select * from classes c,student s where c.classesid = s.cid and c.classesid = #{classesid}
</select>
<resultMap type="mybatis.entity.Classes" id="classes">
<id column="classesid" property="classesid"/>
<result column="cname" property="cname"/>
<collection property="students" ofType="mybatis.entity.Student">
<id column="studentid" property="studentid"/>
<result column="sname" property="sname"/>
</collection>
</resultMap>
select中就是写的表连接的语句,和一对一一样,是returnMap,和一对一不同的是,returnMap中不是使用association标签,而是使用collection,因为这里是一对多的关系,其中的student是以List存在于classes中的,
property:classes对象中的list的名字
ofType:如果是使用association标签,则是javaType,collection则是ofType
其他的和一对一一样,把属性和列对应起来就行了
4.编写测试类
查找代码是之前一样,不一样的是结果
public static void main(String[] args) {
InputStream resourceAsStream = MybatisTest.class.getResourceAsStream("/config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 查找id为1的班级信息
Classes classes = sqlSession.selectOne("mybatis.entity.ClassesMapper.getClassesById",1);
System.out.println(classes);
// 打印出:Classes [classesid=1, cname=一班, students=[Student [studentid=1, sname=张三], Student [studentid=2, sname=李四]]]
}
五.最后
基础的mybatis操作和对应关系就这样了,上面的例子弄懂了基本算入门了,另外还有日志,动态sql之类的下次再介绍