除了前面介绍的数据库的简单应用之外,MyBatis还提供了多种的特性,这些都是非常有用的。如,以分页加载数据,储蓄或查看CLOB/BLOB类型的数据,和操作枚举类型的值等。让我们来看一下这些特性。
MyBatis提供了使用枚举类型的应用。想像一下,现在STUDENTTS表中拥有一个性别的字段是gender,这个字段的值可是是MALE或FEMALE。所以STUDENT表中这个gender的字段就是枚举类型。
public enum Gender { FEMALE, MALE }
默认情况下,MyBatis会使用EnumTypeHandler的类去操作枚举的属性,和储蓄枚举的值。你不需要额外的配置,你只需要像下面的代码调用就行了。
public class Student { private Integer id; private String name; private String email; private PhoneNumber phone; private Address address; private Gender gender; //setters and getters }
<insert id="insertStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="id"> insert into students(name,email,addr_id, phone,gender) values(#{name},#{email},#{address.addrId},#{phone},#{gender}) </insert>
当你在执行insertStudent的声明时,MyBatis将会把FEMALE或MALE的值填充到Grender中。如果你想要储蓄额外的信息,如0代表FEMALE,1代表MALE的话,那么你需要在mybatis-config.xml的文件中配置EnumOrdinalTypeHandler.
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.owen.mybatis.domain.Gender"/>
现在我们添加这样的一张储蓄图片的表,表中含有BLOB的属性。
CREATE TABLE USER_PICS ( ID INT(11) NOT NULL AUTO_INCREMENT, NAME VARCHAR(50) DEFAULT NULL, PIC BLOB, BIO LONGTEXT, PRIMARY KEY (ID) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=LATIN1;
这个图片可以是PNG、JPG等形式,这个表可以跟student和tutor相关联。
默认情况下,MyBatis映射CLOB类型是java.lang.String,而BLOB是byte[]。
public class UserPic { private int id; private String name; private byte[] pic; private String bio; //setters & getters }
创建UserPicMapper.xml文件和配置映射声明:
<insert id="insertUserPic" parameterType="UserPic"> INSERT INTO USER_PICS(NAME, PIC,BIO) VALUES(#{name},#{pic},#{bio}) </insert> <select id="getUserPic" parameterType="int" resultType="UserPic"> SELECT * FROM USER_PICS WHERE ID=#{id} </select>
下面的方法insertUserPic()展示了如何插入数据CLOB/BLOB的数据。
public void insertUserPic() { byte[] pic = null; try { File file = new File("C:\\Images\\UserImg.jpg"); InputStream is = new FileInputStream(file); pic = new byte[is.available()]; is.read(pic); is.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } String name = "UserName"; String bio = "put some lenghty bio here"; UserPic userPic = new UserPic(0, name, pic , bio); SqlSession sqlSession = MyBatisUtil.openSession(); try { UserPicMapper mapper = sqlSession.getMapper(UserPicMapper.class); mapper.insertUserPic(userPic); sqlSession.commit(); } finally { sqlSession.close(); } }
下面的getuserPic()方法展示了如何以String读取CLOB类型,和如何以byte[]读取BLOB类型。
public void getUserPic() { UserPic userPic = null; SqlSession sqlSession = MyBatisUtil.openSession(); try { UserPicMapper mapper = sqlSession.getMapper(UserPicMapper.class); userPic = mapper.getUserPic(1); } finally { sqlSession.close(); } byte[] pic = userPic.getPic(); try { OutputStream os = new FileOutputStream(new File("C:\\Images\\UserImage_FromDB.jpg")); os.write(pic); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
MyBatis提供了另外一个方式来映射多个参数的声明。现在我们可以查找学习通过所给的name和email。
Public interface StudentMapper { List<Student> findAllStudentsByNameEmail(String name, String email); }
MyBatis提供的多值映射参数,使用的是#{param}语法。
<select id="findAllStudentsByNameEmail" resultMap="StudentResult" > select stud_id, name,email, phone from Students where name=#{param1} and email=#{param2} </select>
这个#{param1}就是name,#{param2}就是email。
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper. class); studentMapper.findAllStudentsByNameEmail(name, email);
如果我们查询学生这张表,查询的结果是多行的,我们希望是可以以map的形式,也就是就key、value的形式来展现,那我们可以使用下面的方法。
<select id=" findAllStudents" resultMap="StudentResult"> select * from Students </select> Map<Integer, Student> studentMap = sqlSession.selectMap("com.owen.mybatis.mappers.StudentMapper. findAllStudents", "studId");
上面的studentMap将会包含studId的key和Student对象。
有时候,我们的数据表中会有大量的数据,一张表中可能的万条数据,那我们我们不可能一次性全部加载到页面上显示。我们需要对数据进行分页显示。MyBatis就提供了Rowbounds来实现分页功能。RowBounds对象是有offset和limit的参数,offset是开始的位置,limit是每页面显示多少条。下面是每一页显示25条数据的例子。
<select id="findAllStudents" resultMap="StudentResult"> select * from Students </select>
你可以加载第一页的数据是25条
<pre name="code" class="java">int offset =0 , limit =25; RowBounds rowBounds = new RowBounds(offset, limit); List<Student> = studentMapper.getStudents(rowBounds);
如果显示第二面,那么offset=25和limit=25;第三页是offset=50,limit=25.
通过页面的几个章节,我们学习了MyBatis的关系表之间的查询,还有就是Mybatis的动态语句的应用。相信通过这几个章节的学习,你对MyBatis有了进一步的认识。而这个新认识也是MyBatis中重要的部分。下一章节,我们将要学习如何通过注解来使用本章的功能。源码下载:https://github.com/owenwilliam/mybatis.com.git