第2章 MyBatis 3常用技能
本章是MyBatis框架扩展的章节,本章的内容在使用MyBatis框架时一定会用到,尤其是动态SQL在使用MyBatis框架时较为常用,在本章中读者应该着重掌握如下内容:
• 使用Properties对象连接数据库。
• 动态SQL中要使用的标签。
• 动态SQL中对null值的处理。
• 对超大字符串及分页的处理。
2.1 MyBatis 3的SQL映射文件
因为MyBatis框架是基于SQL映射的,所以SQL映射文件在此框架中的位置非常重要,但好在SQL映射文件非常简单。本章将介绍SQL映射文件的具体内容及实例使用。
2.2 连接DB数据库的参数来自于Properties对象
在前面的示例中,连接数据库时的具体参数是直接在mybatis-config.xml文件中进行定义的,比如url.username和password这些信息。MyBatis还支持将这些参数值写入*.properties属性文件中。
更改mybatis-config.xml配置文件的部分代码如下。
  <dataSource type= 
 "POOLED"> 
 
 <property name= 
 "driver" value= 
 "${drivername}" /> 
 
 <property name= 
 "url" value= 
 "${url}" /> 
 
 <property name= 
 "username" value= 
 "${username}" /> 
 
 <property name= 
 "password" value= 
 "${password}" /> 
 
 </dataSource> 
在src中创建db.properties属性文件,内容如下。
  url=jdbc:sqlserver://localhost:1079;databaseName=ghydb 
 
 drivername=com.microsoft.sqlserver.jdbc.SQLServerDriver 
 
 username=sa 
 
 password= 
使用如下Java代码即可进行数据库的操作:
  InputStream isRef = GetSqlSession. 
 class 
 
 .getResourceAsStream("/db.properties"); 
 
 Properties prop = 
 new Properties(); 
 
 prop.load(isRef); 
 
 String resource = "mybatis-config.xml"; 
 
 InputStream inputStream = Resources. 
 getResourceAsStream(resource); 
 
 SqlSessionFactory sqlSessionFactory = 
 new SqlSessionFactoryBuilder() 
 
 .build(inputStream, prop); 
 
 SqlSession sqlSsession = sqlSessionFactory.openSession(); 
2.3 <resultMap>标签
如果数据表中字段的名称和Java实体类中属性的名称不一致,就要使用<resultMap>标签来进行映射。
创建名为resultMapTest的Java项目,映射配置文件userinfoMapping.xml代码如下。
  <?xml version= 
 "1.0" encoding= 
 "UTF-8" ?> 
 
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> 
 
 <mapper namespace= 
 "mybatis.testcurd"> 
 
 <resultMap type= 
 "entity.Userinfo" id= 
 "userinfo"> 
 
 <result column= 
 "id" property= 
 "idghy" /> 
 
 <result column= 
 "username" property= 
 "usernameghy" /> 
 
 <result column= 
 "password" property= 
 "passwordghy" /> 
 
 <result column= 
 "age" property= 
 "ageghy" /> 
 
 <result column= 
 "insertdate" property= 
 "insertdateghy" /> 
 
 </resultMap> 
 
 <select id= 
 "getUserinfoAll" resultMap= 
 "userinfo"> 
 
 select * from 
 
 userinfo 
 
 </select> 
 
 </mapper> 
实体类Userinfo.java的结构如图2-1所示。
创建Run.java运行类,核心代码如下。
 
 public class Run { 
 
 
 public static void main(String[] args) { 
 
 try { 
 
 String resource = "mybatis-config.xml"; 
 
 InputStream inputStream = Resources. 
 getResourceAsStream(resource); 
 
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() 
 
 .build(inputStream); 
 
 SqlSession sqlSession = sqlSessionFactory.openSession(); 
 
 List<Userinfo> listUserinfo = sqlSession 
 
 .selectList("getUserinfoAll"); 
 
 for (int i = 0; i < listUserinfo.size(); i++) { 
 
 Userinfo userinfo = listUserinfo.get(i); 
 
 System. 
 out.println(userinfo.getIdghy() + " " 
 
 + userinfo.getUsernameghy() + " " 
 
 + userinfo.getPasswordghy() + " " 
 
 + userinfo.getAgeghy() + " " 
 
 + userinfo.getInsertdateghy()); 
 
 } 
 
 } catch (IOException e) { 
 
 // TODO Auto-generated catch block 
 
 e.printStackTrace(); 
 
 } 
 
 } 
 
 } 
运行程序后的结果如图2-2所示。
2.4 <sql>标签
重复的SQL语句永远不可避免,<sql>标签就是用来解决这个问题的。
创建名为sqlTest的Java项目,映射配置文件userinfoMapping.xml的代码如下。
  <?xml version= 
 "1.0" encoding= 
 "UTF-8" ?> 
 
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> 
 
 <mapper namespace= 
 "mybatis.testcurd"> 
 
 <sql id= 
 "userinfoField">id,username,password,age,insertdate</sql> 
  <select id= 
 "getUserinfoAll" resultType= 
 "map"> 
 
 select 
 
 <include refid= 
 "userinfoField" /> 
 
 from 
 
 userinfo 
 
 </select> 
 
 <select id= 
 "getUserinfoById" resultType= 
 "map" parameterType= 
 "int"> 
 
 select 
 
 <include refid= 
 "userinfoField" /> 
 
 from 
 
 userinfo where id=#{0} 
 
 </select> 
 
 </mapper> 
因为上述代码中的id、username、password和insertdate这4个字段在映射文件中多处出现,所以可以将这4个字段封装进<sql>标签中,以减少配置的代码量。
创建Run.java运行测试类,代码如下。
  public class Run { 
 
 public static void main(String[] args) { 
 
 try { 
 
 String resource = "mybatis-config.xml"; 
 
 InputStream inputStream = Resources. 
 getResourceAsStream(resource); 
 
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() 
 
 .build(inputStream); 
 
 SqlSession sqlSession = sqlSessionFactory.openSession(); 
 
 List<Map> listUserinfo = sqlSession.selectList("getUserinfoAll"); 
 
 for (int i = 0; i < listUserinfo.size(); i++) { 
 
 Map map = listUserinfo.get(i); 
 
 System. 
 out.println(map.get("ID") + " " + map.get("USERNAME") 
 
 + " " + map.get("PASSWORD") + " " + map.get("AGE") 
 
 + " " + map.get("INSERTDATE")); 
 
 } 
 
 System. 
 out.println(""); 
 
 System. 
 out.println(""); 
 
 listUserinfo = sqlSession.selectList("getUserinfoById", 5); 
 
 for (int i = 0; i < listUserinfo.size(); i++) { 
 
 Map map = listUserinfo.get(i); 
 
 System. 
 out.println(map.get("ID") + " " + map.get("USERNAME") 
 
 + " " + map.get("PASSWORD") + " " + map.get("AGE") 
 
 + " " + map.get("INSERTDATE")); 
 
 } 
 
 } catch (IOException e) { 
 
 // TODO Auto-generated catch block 
 
 e.printStackTrace(); 
 
 } 
 
 } 
 
 } 
程序运行后的结果如图2-3所示。
2.5 将SQL语句作为字符串变量传入
在MyBatis中也支持将SQL语句当成变量传入。
新建名为sqlStringVar的Java项目,映射文件userinfoMapping.xml的内容如下。
  <?xml version= 
 "1.0" encoding= 
 "UTF-8" ?> 
 
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> 
 
 <mapper namespace= 
 "mybatis.testcurd"> 
 
 <select id= 
 "getUserinfo" parameterType= 
 "map" resultType= 
 "map"> 
 
 select 
 
 id,username,password,age,insertdate 
 
 from 
 
 userinfo where id>#{id} order 
 
 by ${orderSql} 
 
 </select> 
 
 </mapper> 
Java类文件Run.java的代码如下。
 
 public class Run { 
 
 
 public static void main(String[] args) { 
 
 
 try { 
 
 HashMap mapParam = new HashMap(); 
 
 mapParam.put("id", 5); 
 
 mapParam.put("orderSql", "id desc"); 
 
 String resource = "mybatis-config.xml"; 
 
 InputStream inputStream = Resources. 
 getResourceAsStream(resource); 
 
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() 
 
 .build(inputStream); 
 
 SqlSession sqlSession = sqlSessionFactory.openSession(); 
 
 List<Map> listUserinfo = sqlSession.selectList("getUserinfo", 
 
 mapParam); 
 
 for (int i = 0; i < listUserinfo.size(); i++) { 
 
 Map map = listUserinfo.get(i); 
 
 System. 
 out.println(map.get("ID") + " " + map.get("USERNAME") 
 
 + " " + map.get("PASSWORD") + " " + map.get("AGE") 
 
 + " " + map.get("INSERTDATE")); 
 
 } 
  } catch (IOException e) { 
 
 // TODO Auto-generated catch block 
 
 e.printStackTrace(); 
 
 } 
 
 } 
 
 } 
上述代码从map中get(字段名称)的形式取得字段对应的值,但字段名称在Oracle中是大写字母,所以这里的字段名称也必须要写成大写形式。为了支持方便的小写形式,可以在映射文件中为定义的SQL语句为字段指定一个别名。
  select id "id",username "username",password "password",age "age" 
这样从map中就可以以小写的形式取得字段值。
运行结果如图2-4所示。
2.6 动态SQL的使用
MyBatis框架还支持动态SQL标签的使用,而且某些标签的使用率还非常高。
2.6.1 插入null值时的处理第1种方法——jdbcType
创建名为dynSqlTest的Web项目,创建名为test1的Servlet对象,核心代码如下。
 
 public 
 class test1 
 extends HttpServlet { 
 
 
 public 
 void doGet(HttpServletRequest request, HttpServletResponse response) 
 
 
 throws ServletException, IOException { 
 
 Userinfo userinfo = 
 new Userinfo(); 
 
 userinfo.setUsername("中国"); 
 
 userinfo.setPassword( 
 null); 
 
 userinfo.setAge(200L); 
 
 userinfo.setInsertdate( 
 new Date()); 
 
 SqlSession sqlSessionRef = GetSqlSession. 
 getSqlSession(); 
 
 sqlSessionRef.insert("insertUserinfo", userinfo); 
 
 sqlSessionRef.commit(); 
 
 sqlSessionRef.close(); 
 
 } 
 
 } 
在映射文件userinfoMapping.xml中添加如下配置。
  <insert id="insertUserinfo" parameterType="orm.Userinfo"> 
 
 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Long"> 
 
 select idauto.nextval from dual 
 
 </selectKey> 
 
 insert into userinfo(id,username,password,age,insertdate) 
 
 values(#{id},#{username},#{password},#{age},#{insertdate}) 
 
 </insert> 
程序运行后出现如下异常信息。
  ### Error updating database. Cause: org.apache.ibatis.type.TypeException: Error setting 
 
 null for parameter #3 with JdbcType OTHER . Try setting a different JdbcType for this parameter 
 
 or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 无效的列类型: 1111 
从出错信息中可以看到,是用null值对password字段进行了设置,造成MyBatis无法识别,这种情况可以通过设置映射的数据类型来解决。更改映射配置userinfoMapping.xml的代码如下。
  <?xml version= 
 "1.0" encoding= 
 "UTF-8" ?> 
 
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> 
 
 <mapper namespace= 
 "mybatis.testcurd"> 
 
 <insert id= 
 "insertUserinfo" parameterType= 
 "orm.Userinfo"> 
 
 <selectKey keyProperty= 
 "id" order= 
 "BEFORE" resultType= 
 "java.lang.Long"> 
 
 select idauto.nextval from dual 
 
 </selectKey> 
 
 insert into userinfo(id,username,password,age,insertdate) 
 
 values(#{id,jdbcType=INTEGER},#{username,jdbcType=VARCHAR},#{password, 
 
 jdbcType=VARCHAR},#{age,jdbcType=INTEGER},#{insertdate,jdbcType=TIMESTAMP}) 
 
 </insert> 
 
 </mapper> 
这里在#{}格式中加入了数据类型的声明,这样可以明确地告诉MyBatis框架如果遇到null值该如何处理。再次运行程序,成功插入数据表,运行结果如图2-5所示。
2.6.2 插入null值时的处理第2种方法——<if>
通过在#{}格式中加入jdbcType即可避免插入null值时的异常,其实使用动态SQL标签也可以达到同样的效果。
在映射文件userinfoMapping.xml添加如下代码。
  <insert id="insertUserinfo2" parameterType="orm.Userinfo"> 
 
 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Long"> 
 
 select idauto.nextval from dual 
 
 </selectKey> 
 
 <if test="password!=null"> 
 
 insert into userinfo(id,username,password,age,insertdate) 
 
 values(#{id},#{username},#{password},#{age},#{insertdate}) 
 
 </if> 
  <if test="password==null"> 
 
 insert into userinfo(id,username,age,insertdate) 
 
 values(#{id},#{username},#{age},#{insertdate}) 
 
 </if> 
 
 </insert> 
创建名为test2的Servlet,核心代码如下。
 
 public 
 class test2 
 extends HttpServlet { 
 
 
 public 
 void doGet(HttpServletRequest request, HttpServletResponse response) 
 
 
 throws ServletException, IOException { 
 
 Userinfo userinfo1 = 
 new Userinfo(); 
 
 userinfo1.setUsername("英国"); 
 
 userinfo1.setPassword( 
 null); 
 
 userinfo1.setAge(200L); 
 
 userinfo1.setInsertdate( 
 new Date()); 
 
 Userinfo userinfo2 = 
 new Userinfo(); 
 
 userinfo2.setUsername("法国"); 
 
 userinfo2.setPassword("法国人"); 
 
 userinfo2.setAge(200L); 
 
 userinfo2.setInsertdate( 
 new Date()); 
 
 SqlSession sqlSessionRef = GetSqlSession. 
 getSqlSession(); 
 
 sqlSessionRef.insert("insertUserinfo2", userinfo1); 
 
 sqlSessionRef.insert("insertUserinfo2", userinfo2); 
 
 sqlSessionRef.commit(); 
 
 sqlSessionRef.close(); 
 
 } 
 
 } 
程序运行后,成功向数据表中插入两条记录,如图2-6所示。
2.6.3 <choose>标签的使用
<choose>标签的作用是在众多的条件中选择出一个条件,它有些类似于Java语言中switch语句的作用。
在映射文件userinfoMapping.xml中添加如下配置代码。
  <select id="selectUserinfo1" parameterType="orm.Userinfo" 
 
 resultType="map"> 
 
 select * from userinfo where 1=1 
 
 <choose> 
 
 <when test="username!=null">and username like '%'||#{username}||'%'</when> 
 
 <when test="password!=null">and password like '%'||#{password}||'%'</when> 
 
 <otherwise>and age=200</otherwise> 
 
 </choose> 
 
 </select> 
创建名为test3的Servlet对象,核心代码如下。
 
 public 
 class test3 
 extends HttpServlet { 
 
 
 public 
 void doGet(HttpServletRequest request, HttpServletResponse response) 
 
 
 throws ServletException, IOException { 
 
 Userinfo userinfo1 = 
 new Userinfo(); 
 
 userinfo1.setUsername("英"); 
 
 Userinfo userinfo2 = 
 new Userinfo(); 
 
 userinfo2.setPassword("法"); 
 
 Userinfo userinfo3 = 
 new Userinfo(); 
 
 SqlSession sqlSessionRef = GetSqlSession. 
 getSqlSession(); 
 
 List<Map> listMap1 = sqlSessionRef.selectList("selectUserinfo1", 
 
 userinfo1); 
 
 
 for ( 
 int i = 0; i < listMap1.size(); i++) { 
 
 Map eachMap = listMap1.get(i); 
 
 System. 
 out.println("listMap1中的内容: " + eachMap.get("ID") + " " 
 
 + eachMap.get("USERNAME") + " " + eachMap.get("PASSWORD") 
 
 + " " + eachMap.get("AGE") + " " 
 
 + eachMap.get("INSERTDATE")); 
 
 } 
 
 List<Map> listMap2 = sqlSessionRef.selectList("selectUserinfo1", 
 
 userinfo2); 
 
 
 for ( 
 int i = 0; i < listMap2.size(); i++) { 
 
 Map eachMap = listMap2.get(i); 
 
 System. 
 out.println("listMap2中的内容: " + eachMap.get("ID") + " " 
 
 + eachMap.get("USERNAME") + " " + eachMap.get("PASSWORD") 
 
 + " " + eachMap.get("AGE") + " " 
 
 + eachMap.get("INSERTDATE")); 
 
 } 
 
 List<Map> listMap3 = sqlSessionRef.selectList("selectUserinfo1", 
 
 userinfo3); 
 
 
 for ( 
 int i = 0; i < listMap3.size(); i++) { 
 
 Map eachMap = listMap3.get(i); 
 
 System. 
 out.println("listMap3中的内容: " + eachMap.get("ID") + " " 
 
 + eachMap.get("USERNAME") + " " + eachMap.get("PASSWORD") 
 
 + " " + eachMap.get("AGE") + " " 
 
 + eachMap.get("INSERTDATE")); 
 
 } 
 
 sqlSessionRef.commit(); 
 
 sqlSessionRef.close(); 
 
 } 
 
 } 
数据表userinfo中的内容如图2-7所示。
程序运行后,在控制台输出如图2-8所示的信息。
2.6.4 <set>标签的使用
<set>标签可以用在update语句中,作用是动态指定要更新的列。在映射文件userinfoMapping.xml中添加如下映射代码。
<update id="updateUserinfo" parameterType="orm.Userinfo">
update userinfo
<set>
<if test="username!=null">username=#{username},</if>
<if test="password!=null">password=#{password},</if>
<if test="age!=null">age=#{age},</if>
<if test="insertdate!=null">insertdate=#{insertdate}</if>
</set>
<if test="id!=null">where id=#{id}</if>
</update>
创建名为test4的Servlet对象,核心代码如下。
 
 public 
 class test4 
 extends HttpServlet { 
 
 
 public 
 void doGet(HttpServletRequest request, HttpServletResponse response) 
 
 
 throws ServletException, IOException { 
 
 Userinfo userinfo = 
 new Userinfo(); 
 
 userinfo.setId(199L); 
 
 userinfo.setUsername( 
 null); 
 
 userinfo.setPassword("新密码"); 
 
 userinfo.setAge(1000L); 
 
 userinfo.setInsertdate( 
 new Date()); 
 
 SqlSession sqlSessionRef = GetSqlSession. 
 getSqlSession(); 
 
 sqlSessionRef.update("updateUserinfo", userinfo); 
 
 sqlSessionRef.commit(); 
 
 sqlSessionRef.close(); 
 
 } 
 
 } 
程序运行结果如图2-9所示。
2.6.5 <foreach>标签的使用
<foreach>标签有循环的功能,可以用来生成有规律的SQL语句。
<foreach>标签主要的属性有item、index、collection、open、separator和close。
item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次迭代之间以什么符号作为分隔符,close表示该语句以什么结束。
在映射文件userinfoMapping.xml中添加如下配置代码。
  <select id= 
 "selectUserinfo2" parameterType= 
 "list" resultType= 
 "map"> 
 
 select * from userinfo where id in 
 
 <foreach collection= 
 "list" item= 
 "eachId" index= 
 "currentIndex" 
 
 open= 
 "(" separator= 
 "," close= 
 ")"> 
 
 #{eachId} 
 
 </foreach> 
 
 </select> 
  <select id= 
 "selectUserinfo3" parameterType= 
 "orm.QueryUserinfo" 
 
 resultType= 
 "map"> 
 
 select * from userinfo where id in 
 
 <foreach collection= 
 "idList" item= 
 "eachId" index= 
 "currentIndex" 
 
 open= 
 "(" separator= 
 "," close= 
 ")"> 
 
 #{eachId} 
 
 </foreach> 
 
 and username like '%'||#{username}||'%' 
 
 </select> 
  <select id= 
 "selectUserinfo4" parameterType= 
 "map" resultType= 
 "map"> 
 
 select * from userinfo where id in 
 
 <foreach collection= 
 "idList" item= 
 "eachId" index= 
 "currentIndex" 
 
 open= 
 "(" separator= 
 "," close= 
 ")"> 
 
 #{eachId} 
 
 </foreach> 
 
 and username like '%'||#{username}||'%' 
 
 </select> 
创建名为test5的Servlet,核心代码如下。
 
 public 
 class test5 
 extends HttpServlet { 
 
 
 public 
 void doGet(HttpServletRequest request, HttpServletResponse response) 
 
 
 throws ServletException, IOException { 
 
 // id的值来自于List 
 
 List list = 
 new ArrayList(); 
 
 list.add(1); 
 
 list.add(3); 
 
 list.add(5); 
  SqlSession sqlSessionRef = GetSqlSession. 
 getSqlSession(); 
 
 List<Map> listMap1 = sqlSessionRef.selectList("selectUserinfo2", list); 
 
 
 for ( 
 int i = 0; i < listMap1.size(); i++) { 
 
 Map eachMap = listMap1.get(i); 
 
 System. 
 out.println("list1中的内容: " + eachMap.get("ID") + " " 
 
 + eachMap.get("USERNAME") + " " + eachMap.get("PASSWORD") 
 
 + " " + eachMap.get("AGE") + " " 
 
 + eachMap.get("INSERTDATE")); 
 
 } 
 
 // id的值来自于QueryUserinfo实体中的List 
 
 QueryUserinfo queryUserinfo = 
 new QueryUserinfo(); 
 
 queryUserinfo.setUsername("法"); 
 
 queryUserinfo.getIdList().add(198); 
 
 queryUserinfo.getIdList().add(199); 
 
 listMap1 = sqlSessionRef.selectList("selectUserinfo3", queryUserinfo); 
 
 
 for ( 
 int i = 0; i < listMap1.size(); i++) { 
 
 Map eachMap = listMap1.get(i); 
 
 System. 
 out.println("list2中的内容: " + eachMap.get("ID") + " " 
 
 + eachMap.get("USERNAME") + " " + eachMap.get("PASSWORD") 
 
 + " " + eachMap.get("AGE") + " " 
 
 + eachMap.get("INSERTDATE")); 
 
 } 
 
 // id的值来自于Map中的List 
 
 Map paramMap = 
 new HashMap(); 
 
 paramMap.put("username", "5"); 
 
 paramMap.put("idList", list); 
 
 listMap1 = sqlSessionRef.selectList("selectUserinfo4", paramMap); 
 
 
 for ( 
 int i = 0; i < listMap1.size(); i++) { 
 
 Map eachMap = listMap1.get(i); 
 
 System. 
 out.println("list3中的内容: " + eachMap.get("ID") + " " 
 
 + eachMap.get("USERNAME") + " " + eachMap.get("PASSWORD") 
 
 + " " + eachMap.get("AGE") + " " 
 
 + eachMap.get("INSERTDATE")); 
 
 } 
 
 sqlSessionRef.commit(); 
 
 sqlSessionRef.close(); 
 
 } 
 
 } 
运行程序后,控制台输出如图2-10所示的结果。
2.7 插入超大的字符串文本内容
MyBatis框架也支持Oracle的CLOB,不需要特别的环境配置即可完成对CLOB字段的操作。
创建名为bigCLOB的Web项目,映射文件userinfoMapping.xml的代码如下。
  <?xml version= 
 "1.0" encoding= 
 "UTF-8" ?> 
 
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> 
 
 <mapper namespace= 
 "mybatis.testcurd"> 
 
 <insert id= 
 "insertBigString" parameterType= 
 "map"> 
 
 <selectKey keyProperty= 
 "id" order= 
 "BEFORE" resultType= 
 "java.lang.Long"> 
 
 select idauto.nextval from dual 
 
 </selectKey> 
 
 insert into bigclob(id,bigstring) values(#{id},#{bigstring}) 
 
 </insert> 
 
 <select id= 
 "selectById" resultType= 
 "map"> 
 
 select * from bigclob where 
 
 id=10000 
 
 </select> 
 
 </mapper> 
创建名为test的Servlet,核心代码如下。
 
 public 
 class test 
 extends HttpServlet { 
 
 
 public 
 void doGet(HttpServletRequest request, HttpServletResponse response) 
 
 
 throws ServletException, IOException { 
 
 
 try { 
 
 SqlSession sqlSessionRef = GetSqlSession. 
 getSqlSession(); 
 
 Map map = sqlSessionRef.selectOne("selectById"); 
 
 Clob clobRef = (Clob) map.get("BIGSTRING"); 
 
 Reader reader = clobRef.getCharacterStream(); 
 
 BufferedReader brRef = 
 new BufferedReader(reader); 
 
 
 char[] charArray = 
 new 
 char[2048]; 
 
 
 int readLength = brRef.read(charArray); 
 
 
 while (readLength != -1) { 
 
 String bigString = 
 new String(charArray, 0, readLength); 
 
 System. 
 out.println(bigString); 
 
 readLength = brRef.read(charArray); 
 
 } 
 
 Map insertMap = 
 new HashMap(); 
 
 insertMap.put("id", 20000); 
 
 insertMap.put("bigstring", clobRef); 
 
 sqlSessionRef.insert("insertBigString", insertMap); 
 
 sqlSessionRef.commit(); 
 
 sqlSessionRef.close(); 
 
 } 
 catch (SQLException e) { 
 
 // 
 TODO Auto-generated catch block 
  e.printStackTrace(); 
 
 } 
 
 } 
 
 } 
默认情况下Oracle数据表中有一条包含50万行的CLOB字段,如图2-11所示。
程序运行后,在控制台输出了最后一行信息,如图2-12所示。
数据表中还插入了另外一条50万行的记录,如图2-13所示。
2.8 分页
MyBatis还支持分页功能,创建名为pageTest的Web项目。
数据表userinfo中的记录内容如图2-14所示。
映射文件的配置代码如下。
  <?xml version= 
 "1.0" encoding= 
 "UTF-8" ?> 
 
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> 
 
 <mapper namespace= 
 "mybatis.testcurd"> 
 
 <select id= 
 "selectPage" resultType= 
 "map"> 
 
 select * from userinfo 
 
 </select> 
 
 </mapper> 
创建名为test的Servlet,代码如下:
 
 public 
 class test 
 extends HttpServlet { 
 
 
 public 
 void doGet(HttpServletRequest request, HttpServletResponse response) 
 
 
 throws ServletException, IOException { 
 
 SqlSession sqlSession = GetSqlSession. 
 getSqlSession(); 
 
 List<Map> listMap = sqlSession.selectList("selectPage", 
 null, 
 
 
 new RowBounds(2, 4)); 
 
 // 2代表从第2个记录开始,往后移动4个记录 
 
 
 for ( 
 int i = 0; i < listMap.size(); i++) { 
 
 Map eachMap = listMap.get(i); 
 
 System. 
 out.println("page中的内容: " + eachMap.get("ID") + " " 
 
 + eachMap.get("USERNAME") + " " + eachMap.get("PASSWORD") 
 
 + " " + eachMap.get("AGE") + " " 
 
 + eachMap.get("INSERTDATE")); 
 
 } 
 
 } 
 
 } 
程序运行后,在控制台输出如图2-15所示的结果。