《Java EE核心框架实战》—— 2.6 动态SQL的使用

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();
  userinfo.setInsertdate(new Date());
  SqlSession sqlSessionRef = GetSqlSession.getSqlSession();
  sqlSessionRef.insert("insertUserinfo", userinfo);
  sqlSessionRef.commit();
  sqlSessionRef.close();
 }
}```
在映射文件userinfoMapping.xml中添加如下配置。

select idauto.nextval from dual

insert into userinfo(id,username,password,age,insertdate)
values(#{id},#{username},#{password},#{age},#{insertdate})
`
程序运行后出现如下异常信息。

### 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" ?>

select idauto.nextval from dual

insert into userinfo(id,username,password,age,insertdate)
values(#{id,jdbcType=INTEGER},#{username,jdbcType=VARCHAR},#{password,
jdbcType=VARCHAR},#{age,jdbcType=INTEGER},#{insertdate,jdbcType=TIMESTAMP})

`
这里在#{}格式中加入了数据类型的声明,这样可以明确地告诉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();
userinfo1.setInsertdate(new Date());
Userinfo userinfo2 = new Userinfo();
userinfo2.setUsername("法国");
userinfo2.setPassword("法国人");
userinfo2.setAge();
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 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 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 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();
userinfo.setUsername(null);
userinfo.setPassword("新密码");
userinfo.setAge();
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 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所示的结果。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

时间: 2024-09-24 05:50:17

《Java EE核心框架实战》—— 2.6 动态SQL的使用的相关文章

《Java EE核心框架实战》—— 2.4 &lt; sql &gt;标签

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" &q

《Java EE核心框架实战》—— 2.5 将SQL语句作为字符串变量传入

2.5 将SQL语句作为字符串变量传入 Java EE核心框架实战 在MyBatis中也支持将SQL语句当成变量传入. 新建名为sqlStringVar的Java项目,映射文件userinfoMapping.xml的内容如下. <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" &

《Java EE核心框架实战》—— 导读

前言 从近几年用人单位对人才招聘的要求来看,越来越趋向于"实战性",也就是要求新入职的员工能立即融入团队,迅速上手项目开发,快速创造经济利益. 多年以来,我一直从事与软件开发相关的工作.我的很多学员建议我写一本内容精悍而又不失实用价值的主流Java EE开源框架图书,使其只包含主流框架最重要.最核心.最常用的内容.这样他们就可以尽快上手,可以自行在工作和学习中不断拓展和深掘.这也是我写作本书的主要目的. 的确,他们的建议非常有道理,因为Java EE世界非常庞大,市面上没有任何一本书能

《Java EE核心框架实战》—— 第2章 MyBatis 3常用技能

第2章 MyBatis 3常用技能 本章是MyBatis框架扩展的章节,本章的内容在使用MyBatis框架时一定会用到,尤其是动态SQL在使用MyBatis框架时较为常用,在本章中读者应该着重掌握如下内容: 使用Properties对象连接数据库. 动态SQL中要使用的标签. 动态SQL中对null值的处理. 对超大字符串及分页的处理. 本文仅用于学习和交流目的,不代表异步社区观点.非商业转载请注明作译者.出处,并保留本文的原始链接.

《Java EE核心框架实战》—— 2.7 插入超大的字符串文本内容

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"

《Java EE核心框架实战》—— 2.3 &lt; resultMap &gt;标签

2.3 < resultMap >标签 如果数据表中字段的名称和Java实体类中属性的名称不一致,就要使用< resultMap>标签来进行映射. 创建名为resultMapTest的Java项目,映射配置文件userinfoMapping.xml代码如下. <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org

《Java EE核心框架实战》—— 2.1 MyBatis 3的SQL映射 文件

2.1 MyBatis 3的SQL映射 文件 因为MyBatis框架是基于SQL映射的,所以SQL映射文件在此框架中的位置非常重要,但好在SQL映射文件非常简单.本章将介绍SQL映射文件的具体内容及实例使用. 本文仅用于学习和交流目的,不代表异步社区观点.非商业转载请注明作译者.出处,并保留本文的原始链接.

《Java EE核心框架实战》—— 2.8 分页

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"&

jsf-有没有《经典Java EE企业应用实战》的光盘内容?

问题描述 有没有<经典Java EE企业应用实战>的光盘内容? 有没有<经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发> 的光盘内容? 解决方案 http://down.51cto.com/data/1150461 解决方案二: http://vdisk.weibo.com/s/uamgkixENqRy3