11、myBatis的注解使用方式(了解。主要使用xml)
注解的使用示例:
publicinterface UserMapperAnnotation {
@Select("select id,last_name userName ,sexfrom t_user where id = #{id}")
public User selectUser(int id);
@Select("select *from t_user")
public List<User> selectUserList();
@Update("updatet_user set last_name = #{lastName}, sex = #{sex} where id= #{id}")
publicint updateUser(User user);
@Delete("deletefrom t_user where id = #{id}")
publicint deleteUserById(int id);
@Insert("insertinto t_user(`last_name`,`sex`)values(#{lastName},#{sex})")
@SelectKey(before = false, keyProperty = "id", resultType =Integer.class, statement = { "selectlast_insert_id()" })
publicint insertUser(User user);
}
mybatis-config.xml配置文件中导入
<mappers>
<mapper class="com.xypuxing.dao.UserMapperAnnotation"/>
</mappers>
12、mybatis的参数传递
12.1、一个普通数据类型
当一个方法中只有一个普通数据类型。在mapper配置文件中可以使用#{}占位符来进行占位输出。
#{} 占位符中,可以写参数的 #{变量名}。 也可以写 #{value}。
方法:
publicintdeleteUserById(int id);
#{变量名}
<delete id="deleteUserById" parameterType="int">
delete from t_user where id = #{id}
</delete>
#{value}
<delete id="deleteUserById" parameterType="int">
delete from t_user where id = #{value}
</delete>
12.2、多个普通数据类型
多个普通的参数。当我们需要使用#{} 占位输出的时候,可以使用
param1,param2 …… paramN
也就是 #{param1} …… #{paramN}
或者使用@Param命名参数
使用param1、param2 …… paramN 占位输出参数
方法:
public List<User>findUserByNameAndSex(String username, int sex);
使用param1、param2 ……paramN 的方式 占位输出参数
<select id="findUserByNameAndSex" resultType="com.xypuxing.bean.User">
select id,last_name lastName,sexfrom t_user where last_name = #{param1}and sex = #{param2}
</select>
使用@Param注解命名参数
方法:
public List<User> findUserByNameAndSex(@Param("username") String username, @Param("sex") int sex);
使用命名参数输出:
<select id="findUserByNameAndSex" resultType="com.xypuxing.bean.User">
select id,last_name lastName,sexfrom t_user where last_name = #{lastName} and sex = #{sex}
</select>
12.3、传递一个Map对象作为参数
当我们的参数为map对象的时候。我们可以使用 map对象的key来做为占位符,输出数据。
#{map的key} 来做为占位符的输出
使用示例如下:
方法:
public List<User> findUserByMap(Map<String, Object>map);
调用的代码:
@Test
publicvoid findUserByMap() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
Map<String,Object>map = newHashMap<String, Object>();
map.put("lastName", "admin");
map.put("sex", 1);
System.out.println(userMapper.findUserByMap(map) );
} finally {
session.close();
}
}
配置如下:
<select id="findUserByMap" resultType="com.xypuxing.bean.User">
select id,last_name lastName,sexfrom t_user where last_name = #{lastName} and sex = #{sex}
</select>
12.4、一个Pojo数据类型
当方法的参数是一个复杂类型的对象的时候。我们可以使用对象的属性名。当成占位符的名称。比如:#{ 属性名 }
示例:
publicint insertUser(User user);
mapper中的配置:
<insert id="insertUser" parameterType="com.xypuxing.bean.User" useGeneratedKeys="true" keyProperty="id">
insert into t_user(`last_name`,`sex`) values(#{lastName},#{sex})
</insert>
12.5、多个Pojo数据类型
当有多个复杂pojo对象做为参数传递给方法使用时候。我们要取出数据做为sql的参数。可以使用如下方式:
#{param1.属性名}
……
#{paramN.属性名}
也可以使用@Param命名参数。给每个pojo对象起一个别名。然后再通过 #{别名.属性名} 的方式取出数据值做为参数使用。
使用示例:
默认param1、param2、paramN形式取对象属性。配置如下:
方法:
publicList<User> findUserByTwoUser(User user1, User user2);
配置如下:
<select id="findUserByTwoUser" resultType="com.xypuxing.bean.User">
select id,last_name lastName,sexfrom t_user where last_name = #{param1.lastName} and sex =#{param2.sex}
</select>
@Param注解命名参数的形式:
方法:
public List<User> findUserByTwoUser(@Param("user1") Useruser1, @Param("user2") User user2);
配置如下:
<select id="findUserByTwoUser" resultType="com.xypuxing.bean.User">
select id,last_name lastName,sexfrom t_user where last_name = #{user1.lastName} and sex =#{user2.sex}
</select>
12.6、#{}和${}的区别
#{} 在mapper的配置文件的sql语句中,它是占位符, 相当于 ? 号。
${} 在 mapper 的配置文件的 sql 语句中,它是原样输出变量的值,然后以字符串拼接的功能进行操作。
${} 中只能写value,或者是@Param命名参数后的参数名称
在输出参数的时候,我们并不推荐使用 ${} 来输出。因为可能会导至 sql 注入问题的存在
比如:
select * form t_user where id = #{id}
相当于:
select * from t_user where id = ?
而
select * from t_user where id = ${value}
相当于
select * from t_user where id = 原样输出变量的值
12.7、模糊查询
现在要根据用户名查询用户对象。 也就是希望查询如下: select * from t_user where user_name like '%张%'
方法:
public List<User> findUserLikeName(String name);
12.7.1、#{} 的实现配置和调用
调用代码:
@Test
publicvoid findUserLikeName() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
// 需要在传递参数的时候,自己加上前后的两个百分号
System.out.println(userMapper.findUserLikeName("%a%") );
} finally {
session.close();
}
}
配置如下:
<select id="findUserLikeName" resultType="com.xypuxing.bean.User">
select id,last_name lastName ,sexfrom t_user where last_name like #{name}
</select>
12.7.2、${} 的实现配置和调用
${} 的实现,只是原样的输出参数的值。然后做字符串的拼接操作。
调用代码:
@Test
publicvoid findUserLikeName() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
// 需要在传递参数的时候,自己加上前后的两个百分号
System.out.println(userMapper.findUserLikeName("a") );
} finally {
session.close();
}
}
配置如下:
<select id="findUserLikeName" resultType="com.xypuxing.bean.User">
select id,last_name lastName ,sex,phone from t_user where last_name like '%${value}%'
</select>
12.7.3、MySQL的字符串拼接,concat函数实现。
在mysql中,有一个字符串拼接操作的函数。叫concat函数。当我们需要做类似于like 这种查询的时候。我们可以使用 #{} 组合 concat来解决参数输入,以及不需要在传递参数的时候,加两个%%的情况。还可以解决sql注入问题。使用如下:
代码调用下:
@Test
publicvoid findUserLikeName() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
// 需要在传递参数的时候,自己加上前后的两个百分号
System.out.println(userMapper.findUserLikeName("a") );
} finally {
session.close();
}
}
配置如下:
<select id="findUserLikeName"resultType="com.xypuxing.bean.User">
select id,last_name lastName,sex from t_user where user_name like concat('%',#{name},'%');
</select>
13、自定义结果集<resultMap></resultMap>
13.1、自定义结果集介绍
自定义结果集,可以给复杂的对象使用。也就是对象内又嵌套一个对象。或者一个集合。
在这种情况下。前面学过的知识点,已经无法直接获取出对象内对象的信息。
这个时候就需要使用resultMap自定义结果集来返回需要的数据。
13.2、创建一对一数据库表
## 一对一数据表
## 创建锁表
createtable t_lock(
`id` intprimarykey auto_increment,
`name` varchar(50)
);
## 创建钥匙表
createtable t_key(
`id` intprimarykey auto_increment,
`name` varchar(50),
`lock_id` int ,
foreignkey(`lock_id`) references t_lock(`id`)
);
## 插入初始化数据
insertinto t_lock(`name`) values('阿里巴巴');
insertinto t_lock(`name`) values('华为');
insertinto t_lock(`name`) values('联想');
insertinto t_key(`name`,`lock_id`) values('马云',1);
insertinto t_key(`name`,`lock_id`) values('任正非',2);
insertinto t_key(`name`,`lock_id`) values('柳传志',3);
13.3、创建实体对象
钥匙对象
publicclass Key {
privateintid;
private String name;
private Lock lock;
锁对象
publicclass Lock {
privateintid;
private String name;
13.4、一对一的使用示例
13.4.1、创建 KeyMapper 接口
publicinterface KeyMapper {
public Key queryKeyForSimple(int id);
}
13.4.2、级联属性的映射配置
<!--
resultMap标签专门用来定义自定义的结果集数据。
type属性设置返回的数据类型
id属性定义一个唯一标识
-->
<resultMap type="com.xypuxing.bean.Key" id="queryKeyForSimple_resultMap">
<!-- id定义主键列 -->
<idcolumn="id"property="id"/>
<!-- result 定义一个列和属性的映射 -->
<result column="name" property="name"/>
<!-- lock.id 和 lock.name 叫级联属性映射 -->
<result column="lock_id" property="lock.id"/>
<result column="lock_name" property="lock.name"/>
</resultMap>
<!--
select 标签用于定义一个select语句
id属性设置一个statement标识
parameterType设置参数的类型
resultMap 设置返回的结果类型
-->
<select id="queryKeyForSimple" parameterType="int"resultMap="queryKeyForSimple_resultMap">
select t_key.*,t_lock.name lock_name
from
t_key left join t_lock
on
t_key.lock_id = t_lock.id
where
t_key.id = #{id}
</select>
13.4.3、<association />嵌套结果集映射配置
<association /> 标签可以给返回结果中对象的属性是子对象的情况,进行映射。
比如:Key对象中有一个子对象Lock。就可以使用<association /> 来进行映射返回
<!--
resultMap标签专门用来定义自定义的结果集数据。
type属性设置返回的数据类型
id属性定义一个唯一标识
-->
<resultMap type="com.xypuxing.bean.Key" id="queryKeyForSimple_resultMap_association">
<!-- id定义主键列 -->
<idcolumn="id"property="id"/>
<!-- result 定义一个列和属性的映射 -->
<result column="name" property="name"/>
<!--
association 标签可以给一个子对象定义列的映射。
property 属性设置 子对象的属性名 lock
javaType 属性设置子对象的全类名
-->
<association property="lock" javaType="com.xypuxing.bean.Lock">
<!-- id 属性定义主键-->
<id column="lock_id" property="id"/>
<!-- result 标签定义列和对象属性的映射 -->
<result column="lock_name" property="name"/>
</association>
</resultMap>
13.4.4、KeyMapper的测试代码
@Test
publicvoid testQueryKeyForSimple() {
SqlSession session = sqlSessionFactory.openSession();
try {
KeyMapperkeyMapper = session.getMapper( KeyMapper.class );
System.out.println(keyMapper.queryKeyForSimple(1) );
} finally {
session.close();
}
}
运行的结果:
13.4.5、<association />定义分步查询
添加一个 LockMapper 接口
publicinterface LockMapper {
public Lock queryLockById(int lockId);
}
添加 LockMapper 接口对应的配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTDMapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xypuxing.dao.LockMapper">
<!-- 定义一个根据id查询锁的select -->
<select id="queryLockById" parameterType="int"resultType="com.xypuxing.bean.Lock">
select id , name from t_lock where id =#{value}
</select>
</mapper>
在KeyMapper接口中,添加另一个方法分步查询:
publicinterface KeyMapper {
public Key queryKeyForSimple(int id);
public Key queryKeyByTwoStep(int id);
}
修改KeyMapper中的配置
<!-- resultMap 标签定义复杂对象的结果集数据 -->
<resultMap type="com.xypuxing.bean.Key" id="queryKeyByTwoStep_resultMap">
<idcolumn="id"property="id"/>
<result column="name" property="name"/>
<!--
association标签定义一个子对象的集合集
property 属性映射子对象的名称
select 属性定义执行的查询语句
也就是说。property指定的lock子对象,是通过执行。select标识的查询语句返回
column 属性定义需要传递给select语句的参数
-->
<association property="lock" select="com.xypuxing.dao.LockMapper.queryLockById"column="lock_id"/>
</resultMap>
<!--
定义分步查询的select
-->
<select id="queryKeyByTwoStep" parameterType="int"resultMap="queryKeyByTwoStep_resultMap">
select id,name,lock_id from t_key where id = #{value}
</select>
分步查询的测试代码:
@Test
publicvoid testQueryKeyByTwoStep() {
SqlSession session = sqlSessionFactory.openSession();
try {
KeyMapper keyMapper =session.getMapper( KeyMapper.class );
System.out.println(keyMapper.queryKeyByTwoStep(1) );
} finally {
session.close();
}
}
运行结果:
13.5、延迟加载
延迟加载在一定程序上可以减少很多没有必要的查询。给数据库服务器提升性能上的优化。
要启用延迟加载,需要在mybatis-config.xml配置文件中,添加如下两个全局的settings配置。
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载 按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
懒加载还需要同时引入两个jar包
修改mybatis-config.xml配置文件,添加全局的设置
<!-- 配置全局mybatis的配置 -->
<settings>
<!-- 启用驼峰标识 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消息加载即按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
添加类库到工程项目中
13.6、多对一、一对多的使用示例
13.6.1、创建一对多数据库
## 一对多数据表
## 创建班级表
createtable t_clazz(
`id` intprimarykey auto_increment,
`name` varchar(50)
);
## 插入班级信息
insertinto t_clazz(`name`) values('javaEE20170228');
insertinto t_clazz(`name`) values('javaEE20170325');
insertinto t_clazz(`name`) values('javaEE20170420');
insertinto t_clazz(`name`) values('javaEE20170515');
## 创建学生表
createtable t_student(
`id` intprimarykey auto_increment,
`name` varchar(50),
`clazz_id` int,
foreignkey(`clazz_id`) references t_clazz(`id`)
);
## 插入班级信息
insertinto t_student(`name`,`clazz_id`)values('stu0228_1',1);
insertintot_student(`name`,`clazz_id`) values('stu0228_2',1);
insertintot_student(`name`,`clazz_id`) values('stu0228_3',1);
insertintot_student(`name`,`clazz_id`) values('stu0325_1',2);
insertinto t_student(`name`,`clazz_id`)values('stu0325_2',2);
insertintot_student(`name`,`clazz_id`) values('stu0420_1',3);
13.6.2、<collection/> 一对多,立即加载关联查询
创建实体对象
班级对象
publicclass Clazz {
privateintid;
private String name;
privateList<Student> stus;
学生对象
publicclass Student {
privateintid;
private String name;
创建ClazzMapper接口类:
publicinterface ClazzMapper {
public ClazzqueryClazzByIdForSimple(int id);
}
编写ClazzMapper.xml配置文件
<mapper namespace="com.xypuxing.dao.ClazzMapper">
<!--
resultMap可以定义一个自定义的结果集返回
-->
<resultMap type="com.xypuxing.bean.Clazz" id="queryClazzByIdForSimple_resultMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--
collection定义一个子集合对象返回
-->
<collection property="stus" ofType="com.xypuxing.bean.Student">
<id column="student_id" property="id"/>
<result column="student_name" property="name"/>
</collection>
</resultMap>
<!-- 定义一个立即加载的查询Clazz对象 -->
<select id="queryClazzByIdForSimple" parameterType="int"resultMap="queryClazzByIdForSimple_resultMap">
select t_clazz.* , t_student.idstudent_id,t_student.name student_name
from
t_clazzleft join t_student
on
t_clazz.id= t_student.clazz_id
where
t_clazz.id= #{id}
</select>
</mapper>
测试代码:
@Test
publicvoid testQueryClazzByIdForSimple(){
SqlSession session = sqlSessionFactory.openSession();
try {
ClazzMapperclazzMapper = session.getMapper( ClazzMapper.class );
System.out.println(clazzMapper.queryClazzByIdForSimple(1) );
} finally {
session.close();
}
}
运行效果:
13.6.3、一对多,赖加载
在ClazzMapper接口中添加一个分步查询延迟加载的方法
publicinterface ClazzMapper {
public ClazzqueryClazzByIdForSimple(int id);
public Clazz queryClazzByIdForLazy(int id);
}
创建一个StudentMapper接口
publicinterface StudentMapper {
public List<Student>queryStudentsByClazzId(int clazzId);
}
创建StudentMapper.xml配置文件
<!-- 根据班级id查询学生信息 -->
<select id="queryStudentsByClazzId" parameterType="int"resultType="com.xypuxing.bean.Student">
select id,name from t_student where clazz_id= #{value}
</select>
修改ClazzMapper.xml配置文件内容:
<!-- 创建一个自定义集合集 -->
<resultMap type="com.xypuxing.bean.Clazz" id="queryClazzByIdForLazy_resultMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="stus" ofType="com.xypuxing.bean.Student"
select="com.xypuxing.dao.StudentMapper.queryStudentsByClazzId"column="id"/>
</resultMap>
<!-- 创建一个懒加载Clazz对象的查询 -->
<select id="queryClazzByIdForLazy" parameterType="int"resultMap="queryClazzByIdForLazy_resultMap">
select id,name from t_clazz where id =#{value}
</select>
修改log4j日记配置文件如下:
# Global logging configuration
log4j.rootLogger=DEBUG,stdout
# MyBatis logging configuration...
#log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p[%t%d{HH:mm:ss}]-%m%n
上面日记中标黄的部分,是给日记添加当前时间的输出
测试延迟加载的代码
@Test
publicvoid testQueryClazzByIdForLazy(){
SqlSession session = sqlSessionFactory.openSession();
try {
ClazzMapper clazzMapper =session.getMapper( ClazzMapper.class );
Clazz clazz =clazzMapper.queryClazzByIdForLazy( 1 );
System.out.println(clazz.getName());
try {
//暂停一会儿
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(clazz.getStus());
} finally {
session.close();
}
}
运行效果:
13.6.4、双向关联
修改班级对象
publicclass Clazz {
privateintid;
private String name;
privateList<Student> stus;
修改学生对象
publicclass Student {
privateintid;
private String name;
private Clazz clazz;
修改StudentMapper配置文件
<resultMap type="com.xypuxing.bean.Student" id="queryStudentsByClazzId_resultMap">
<idcolumn="id"property="id"/>
<result column="name" property="name"/>
<association property="clazz" javaType="com.xypuxing.bean.Clazz"
select="com.xypuxing.dao.ClazzMapper.queryClazzByIdForLazy" column="clazz_id"></association>
</resultMap>
<!-- 根据班级id查询学生信息 -->
<select id="queryStudentsByClazzId" parameterType="int"
resultMap="queryStudentsByClazzId_resultMap">
select id,name,clazz_id from t_student where clazz_id = #{value}
</select>
注意:双向关联,要小心进入死循环,
1、防止死循环就是不要调用toString方法
2、最后一次查询返回resultType.
修改测试的代码如下:
@Test
publicvoidtestQueryClazzByIdForLazy() {
SqlSession session = sqlSessionFactory.openSession();
try {
ClazzMapper clazzMapper =session.getMapper( ClazzMapper.class );
Clazz clazz =clazzMapper.queryClazzByIdForLazy( 1 );
System.out.println(clazz.getName());
try {
//暂停一会儿
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(clazz.getStus().get(0).getName());
System.out.println(clazz.getStus().get(0).getClazz().getName());
} finally {
session.close();
}
}
14、动态SQL语句
准备工作:
publicclass User {
privateintid;
private String lastName;
privateintsex;
14.1、if 语句
说明: if语句,可以动态的根据你的值来决定,是否需要动态的添加查询条件。
UserMapper类中的方法
publicinterface UserMapper {
public List<User>queryUsersByNameAndSex(User user);
}
UserMapper配置文件中的配置
<!--
if语句
-->
<select id="queryUsersByNameAndSex" parameterType="com.xypuxing.bean.User"resultType="com.xypuxing.bean.User">
select id,last_name lastName,sex from t_user where
<!-- 我们希望动态的创建这个条件语句 -->
<iftest="lastName!= null">
last_name like concat('%',#{lastName },'%')
</if>
<iftest="sex == 0or sex == 1">
and sex = #{sex}
</if>
</select>
测试代码:
@Test
publicvoidtestQueryUsersByNameAndSex() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
List<User> users =userMapper.queryUsersByNameAndSex(new User(0, "dmi", 1));
System.out.println(users);
} finally {
session.close();
}
}
执行的结果:
14.2、where 语句
说明: where语句,可以帮我们在多个动态语句中,有效的去掉前面的多余的and 或 or 之类的多余关键字
UserMapper配置文件
<!--
where - if语句
-->
<select id="queryUsersByNameAndSex" parameterType="com.xypuxing.bean.User"resultType="com.xypuxing.bean.User">
select id,last_name lastName,sex from t_user
<where>
<!-- 我们希望动态的创建这个条件语句 -->
<if test="lastName != null">
last_name like concat('%',#{ lastName },'%')
</if>
<if test="sex == 0 or sex == 1">
and sex = #{sex}
</if>
</where>
</select>
测试的代码是:
@Test
publicvoidtestQueryUsersByNameAndSex() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
List<User> users =userMapper.queryUsersByNameAndSex(new User(0, null, 1));
System.out.println(users);
} finally {
session.close();
}
}
测试的结果:
14.3、trim语句
说明: trim 可以动态在包含的语句前面和后面添加内容。也可以去掉前面或者后面给定的内容
prefix 前面添加内容
suffix 后面添加内容
suffixOverrides 去掉的后面内容
prefixOverrides 去掉的前面内容
UserMapper配置文件中的内容
<!--
trim - if 语句
-->
<select id="queryUsersByNameAndSex" parameterType="com.xypuxing.bean.User"resultType="com.xypuxing.bean.User">
select id,last_name lastName,sex from t_user
<!--
trim 可以动态在包含的语句前面和后面添加内容。也可以去掉前面或者后面给定的内容
prefix 前面添加内容
suffix 后面添加内容
suffixOverrides 去掉的后面内容
prefixOverrides 去掉的前面内容
-->
<trimprefix="where"suffixOverrides="and"prefixOverrides="">
<!-- 我们希望动态的创建这个条件语句 -->
<if test="lastName != null">
last_name like concat('%',#{ lastName },'%') and
</if>
<if test="sex == 0 or sex == 1">
sex =#{sex}
</if>
</trim>
</select>
测试代码:
@Test
publicvoidtestQueryUsersByNameAndSex() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
List<User> users =userMapper.queryUsersByNameAndSex(new User(0, "dmi", 5));
System.out.println(users);
} finally {
session.close();
}
}
测试的结果:
14.4、choose( when , otherwise )语句
说明:choose when otherwise 可以执行多路选择判断,但是只会有一个分支会被执行。
类似switchcase 语句
UserMapper接口中添加的方法:
public List<User> queryUsersByNameAndSexForChoose(User user);
UserMapper配置文件的内容:
<!--
choose when otherwise 语句
有点类似于switch case 多路判断。只执行一路。
-->
<select id="queryUsersByNameAndSexForChoose" parameterType="com.xypuxing.bean.User"
resultType="com.xypuxing.bean.User">
select id,last_name lastName,sex from t_user
<where>
<choose>
<whentest="id >0">
id = #{ id }
</when>
<whentest="lastName!= null">
last_name = #{lastName}
</when>
<otherwise>
1 = 1
</otherwise>
</choose>
</where>
</select>
测试的代码:
@Test
publicvoidtestQueryUsersByNameAndSexForChoose() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
List<User> users =userMapper.queryUsersByNameAndSexForChoose(new User(1, "admin", 0));
System.out.println(users);
} finally {
session.close();
}
}
测试的结果:
14.4、set语句
说明: set语句可以去掉,更新时候,set更新的多个列,由于动态生成的sql语句,而导致多出来的逗号
UserMapper中添加的方法
publicintupdateUserForSet(Useruser);
UserMapper配置文件中的内容:
<!--
update语句
set标签,可以去掉,多个列中的逗号
-->
<update id="updateUserForSet" parameterType="com.xypuxing.bean.User">
update t_user
<set>
<if test="lastName != null">
last_name = #{lastName},
</if>
<if test="sex == 0 or sex == 1">
sex = #{sex}
</if>
</set>
where id = #{id}
</update>
测试代码:
@Test
publicvoid testUpdateUserForSet() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
userMapper.updateUserForSet(new User(3, "xxxx", 10));
session.commit();
} finally {
session.close();
}
}
测试结果:
14.5、foreach语句
说明: foreach语句,可以遍历输出一个集合的数据
在UserMapper中添加的方法
public List<User> queryUserByidsForIn(@Param("ids")List<Integer>ids);
UserMapper配置文件中的内容
<!--
foreach语句可以遍历输出数据
collection属性设置遍历的集合
open 属性设置遍历输出前的内容
close 属性设置遍历输出后的内容
separator 属性设置每输出一个元素中间的间隔内容
item 属性 当前正在遍历到的数据名
-->
<select id="queryUserByidsForIn" resultType="com.xypuxing.bean.User">
select id,last_name,sex from t_user
where
id in
<foreach collection="ids" open="(" close=")" separator="," item="item_id">
#{item_id}
</foreach>
</select>
测试代码:
@Test
publicvoid testQueryUserByidsForIn(){
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper =session.getMapper(UserMapper.class);
List<Integer> ids = new ArrayList<>();
ids.add(3);
ids.add(6);
ids.add(7);
List<User> users =userMapper.queryUserByidsForIn( ids );
System.out.println(users);
} finally {
session.close();
}
}
测试结果: