1 返回主键
应用场景
我们很多时候有这种需求,向数据库插入一条记录后,希望能立即拿到这条记录在数据库中的主键 值。
1.1 方式一
UserMapper接口
/*
添加用户:获取返回主键:方式一
*/
public void saveUser(User user);
UserMapper.xml
<!--添加用户:获取返回主键:方式一-->
<!--
useGeneratedKeys: 声明返回主键
keyProperty:把返回主键的值,封装到实体中的那个属性上
-->
<insert id="saveUser" parameterType="user" useGeneratedKeys="true" keyProperty="id">
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
测试
/*
添加用户:返回主键方式一
*/
@Test
public void test8() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
// 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("某冰冰");
user.setBirthday(new Date());
user.setAddress("北京昌平");
user.setSex("女");
System.out.println(user);
mapper.saveUser(user);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
1.2 方式二
UserMapper接口
/*
添加用户:获取返回主键:方式二
*/
public void saveUser2(User user);
UserMapper.xml
<!--添加用户:获取返回主键:方式二-->
<insert id="saveUser2" parameterType="user" >
<!--
selectKey : 适用范围更广,支持所有类型的数据库
order="AFTER" : 设置在sql语句执行前(后),执行此语句
keyColumn="id" : 指定主键对应列名
keyProperty="id":把返回主键的值,封装到实体中的那个属性上
resultType="int":指定主键类型
-->
<selectKey order="AFTER" keyColumn="id" keyProperty="id" resultType="int">
SELECT LAST_INSERT_ID();
</selectKey>
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
测试
/*
添加用户:返回主键方式二
*/
@Test
public void test9() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
// 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("汤唯");
user.setBirthday(new Date());
user.setAddress("北京昌平");
user.setSex("女");
System.out.println(user);
mapper.saveUser2(user);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
2. 动态SQL
应用场景
当我们要根据不同的条件,来执行不同的sql语句的时候,需要用到动态sql。
2.1 动态 SQL 之<if>
需求
根据id和username查询,但是不确定两个都有值。
a)UserMapper接口
/*
动态sql的if标签:多条件查询
*/
public List<User> findByIdAndUsernameIf(User user);
b)UserMapper.xml映射
<!-- 动态sql之if : 多条件查询-->
<select id="findByIdAndUsernameIf" parameterType="user" resultType="com.lagou.domain.User">
select * from user
<!-- test里面写的就是表达式
<where>: 相当于where 1= 1,但是如果没有条件的话,不会拼接上where关键字
-->
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="username !=null">
and username = #{username}
</if>
</where>
</select>
c)测试代码
/*
动态sql之if: 多条件查询
*/
@Test
public void test10() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
// 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(11);
user.setUsername("汤唯");
List<User> users = mapper.findByIdAndUsernameIf(user);
for (User user1 : users) {
System.out.println(user1);
}
sqlSession.close();
}
2.2 动态 SQL 之<set>
需求
动态更新user表数据,如果该属性有值就更新,没有值不做处理。
a)UserMapper接口
/*
动态sql的set标签:动态更新
*/
public void updateIf(User user);
b)UserMapper.xml映射
<!--动态sql之set : 动态更新-->
<update id="updateIf" parameterType="user">
update user
<!--<set> : 在更新的时候,会自动添加set关键字,还会去掉最后一个条件的逗号 -->
<set>
<if test="username != null">
username = #{username},
</if>
<if test="birthday != null">
birthday = #{birthday},
</if>
<if test="sex != null">
sex = #{sex},
</if>
<if test="address != null">
address = #{address},
</if>
</set>
where id = #{id}
</update>
<sql id="selectUser">
select * from user
</sql>
c)测试代码
/*
动态sql之set: 动态更新
*/
@Test
public void test11() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
// 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
user.setUsername("子慕最帅");
user.setAddress("北京海淀区拉勾网");
mapper.updateIf(user);
sqlSession.commit();
sqlSession.close();
}
2.3 动态 SQL 之<foreach>
foreach主要是用来做数据的循环遍历
例如: select * from user where id in (1,2,3) 在这样的语句中,传入的参数部分必须依靠 foreach遍历才能实现。
<foreach>标签用于遍历集合,它的属性:
• collection:代表要遍历的集合元素
• open:代表语句的开始部分
• close:代表结束部分
• item:代表遍历集合的每个元素,生成的变量名
• sperator:代表分隔符
2.3.1 集合
UserMapper接口
/*
动态sql的foreach标签:多值查询:集合
*/
public List<User> findByList(List<Integer> ids);
UserMaper.xml映射
<!--动态sql的foreach标签:多值查询:根据多个id值查询用户-->
<select id="findByList" parameterType="list" resultType="user">
<include refid="selectUser"/>
<where>
<!--
collection : 代表要遍历的集合元素,通常写collection或者list
open : 代表语句的开始部分
close : 代表语句的结束部分
item : 代表遍历结合中的每个元素,生成的变量名
separator: 分隔符
-->
<foreach collection="collection" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
测试代码
/*
动态sql之foreach: 多值查询
*/
@Test
public void test12() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
// 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(6);
ids.add(2);
List<User> users = mapper.findByList(ids);
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
2.3.2 数组
UserMapper接口
/*
动态sql的foreach标签:多值查询:数组
*/
public List<User> findByArray(Integer[] ids);
UserMaper.xml映射
<!--动态sql的foreach标签:多值查询:根据多个id值查询用户-->
<select id="findByArray" parameterType="int" resultType="user">
<include refid="selectUser"/>
<where>
<!--
collection : 代表要遍历的集合元素,通常写collection或者list
open : 代表语句的开始部分
close : 代表语句的结束部分
item : 代表遍历结合中的每个元素,生成的变量名
separator: 分隔符
-->
<foreach collection="array" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
测试代码
/*
动态sql之foreach: 多值查询 :数组
*/
@Test
public void test13() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
// 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Integer[] ids = {2,6,9};
List<User> byArray = mapper.findByArray(ids);
for (User user : byArray) {
System.out.println(user);
}
sqlSession.close();
}
3. SQL片段
应用场景
映射文件中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

4 知识小结
MyBatis映射文件配置
<select>:查询<insert>:插入<update>:修改<delete>:删除<selectKey>:返回主键<where>:where条件<if>:if判断<foreach>:for循环<set>:set设置<sql>:sql片段抽取
节选自拉钩教育JAVA集训营系列课程
861

被折叠的 条评论
为什么被折叠?



