• MYBatis——业务功能,动态sql


    目录

    一,业务功能

    1,返回主键的业务

     2,UUID生成唯一的字符串

    二,动态sql的意义

    1,:用来定义代码片段,可以将所有的列名,或复杂的条件定义为代码片段,供使用时调用。

    2:用来引用定义的代码片段

    3,if 标签 : 条件判断

    4,where标签:多条件拼接使用

     5,标签:有选择的进行更新处理,至少更新一列,其余列如果为空,则保持原来的值

    6,标签:循环遍历,批量处理标签

    6.1  批量查询

    6.2批量删除

     6.3  批量增加

     6.4   批量更新

    7,指定参数位置 

    8,入参是map

    9,返回值是map

    9.1 返回值单行map

    9.2 返回值是多行map

    10,表的列名和实体属性值不一致的解决方案

    方案一:给列名取别名和成员变量保持一致

     方案二:通过resultMap手工完成映射,


    一,业务功能

    1,返回主键的业务

    1. public void testReturnKey() throws ParseException{
    2. User user = new User("kaka",format.parse("2002-20-02"),"1","上海");
    3. userMapper.insert(user);
    4. System.out.println("没有给新插入的数据的ID赋值,selectKey标签注入主键到user.id:"+user.getId());
    5. }
    1. <insert id="insert" parameterType="user" >
    2. <selectKey keyProperty="id" resultType="int" order="AFTER">
    3. select last_insert_id();
    4. selectKey>
    5. insert into user (username,birthday,sex,address) values (#{userName},#{birthday},#{sex},#{address});
    6. insert>

    selectKey参数解读

     2,UUID生成唯一的字符串

    生成全球唯一的字符串,有36个数字字母中划线组成

    Java生成UUID

    1. @Test
    2. public void testUUID(){
    3. UUID uuid = UUID.randomUUID();
    4. System.out.println(uuid);
    5. }

    SQL也存在UUID

    select uuid();

    二,动态sql的意义

    动态sql:

    可以定义代码片段,可以定义逻辑判断,可以进行循环处理(批量处理),是条件判断更为简单。

    1,:用来定义代码片段,可以将所有的列名,或复杂的条件定义为代码片段,供使用时调用。

    2:用来引用定义的代码片段

    将所有的列定义为代码片段,后面查询时直接使用id查询

    1. <sql id="allColumns">
    2. id,username,birthday,sex,address
    3. sql>

    查询使用include根据sql的id查询

    1. <select id="getAll" resultType="user">
    2. select <include refid="allColumns">include>
    3. from user;
    4. select>

    3,if 标签 : 条件判断

    4,where标签:多条件拼接使用

    1. //动态sql查询
    2. List getByCondition(User user);
    1. <select id="getByCondition" parameterType="user" resultType="user">
    2. select <include refid="allColumns">include>
    3. from user
    4. <where>
    5. <if test="userName != null and userName != ''">
    6. and username like concat('%',#{userName},'%')
    7. if>
    8. <if test="birthday != null">
    9. and birthday = #{birthday}
    10. if>
    11. <if test="sex != null and sex != ''">
    12. and sex = #{sex}
    13. if>
    14. <if test="address != null and address != ''">
    15. and address like connect ('%',#{address},'%')
    16. if>
    17. where>
    18. select>
    1. @Test
    2. public void testGetByCondition() throws ParseException {
    3. // User user = new User("",format.parse("2001-02-02"),"2","");
    4. User user = new User();
    5. user.setSex("2");
    6. List list = userMapper.getByCondition(user);
    7. list.forEach((user1 -> System.out.println(user1)));
    8. }

    查询成功,通过where和if通过多条件进行拼接查询。

     

     动态sql的底层是进行sql拼接

     5,标签:有选择的进行更新处理,至少更新一列,其余列如果为空,则保持原来的值

    如果一列都没有更改,Mybatis就会报错,所以一般在业务处理时,如果没有更改数据,是不允许尽心提交的。

    1. @Test
    2. public void testUpdateBySet(){
    3. User user = new User();
    4. user.setId(12);
    5. user.setUserName("yyds");
    6. userMapper.updateBySet(user);
    7. sqlSession.commit();
    8. }
    1. //有选择的更新
    2. int updateBySet(User user);
    1. <update id="updateBySet" parameterType="user">
    2. update user
    3. <set>
    4. <if test="userName != null and userName != ''">
    5. username = #{userName},
    6. if>
    7. <if test="birthday != null">
    8. birthday = #{birthday},
    9. if>
    10. <if test="sex != null and sex != ''">
    11. sex = #{sex},
    12. if>
    13. <if test="address != null and address != ''">
    14. address = #{address},
    15. if>
    16. set>
    17. where id = #{id}
    18. update>

    6,标签:循环遍历,批量处理标签

    6.1  批量查询

    1. //批量查询
    2. List getByForEach(Integer[] arr);
    1. <select id="getByForEach" resultType="user">
    2. select <include refid="allColumns">include>
    3. from user
    4. where id in
    5. <foreach collection="array" item="id" close=")" open="(" separator=",">
    6. #{id}
    7. foreach>
    8. select>
    1. @Test
    2. public void testGetByForEach(){
    3. Integer[] arr = {1,2,3,4};
    4. List byForEach = userMapper.getByForEach(arr);
    5. byForEach.forEach(user -> System.out.println(user));
    6. }

    6.2批量删除

    1. //批量删除
    2. int deleteByForEach(Integer[] arr);

     

    1. <delete id="deleteByForEach">
    2. delete from user
    3. where id in
    4. <foreach collection="array" open="(" close=")" separator="," item="id">
    5. #{id}
    6. foreach>
    7. delete>
    1. @Test
    2. public void testdeleteByForEach(){
    3. Integer[] arr = {1,2,3,4};
    4. System.out.println(userMapper.deleteByForEach(arr));
    5. sqlSession.commit();
    6. }

    删除后的结果:

     6.3  批量增加

    1. //批量插入
    2. int insertByForEach(List<User> list);
    1. <insert id="insertByForEach">
    2. insert into user(username, birthday, sex, address)
    3. values
    4. <foreach collection="list" item="user" separator=",">
    5. (#{user.userName},#{user.birthday},#{user.sex},#{user.address})
    6. foreach>
    7. insert>
    1. @Test
    2. public void testInsertByForEach() throws ParseException {
    3. List list = new ArrayList<>();
    4. User u1 = new User("kk",format.parse("2008-01-03"),"1","西安1");
    5. User u2 = new User("dd",format.parse("2008-01-03"),"1","西安2");
    6. User u3 = new User("gg",format.parse("2008-01-03"),"1","西安3");
    7. User u4 = new User("ll",format.parse("2008-01-03"),"1","西安4");
    8. list.add(u1);
    9. list.add(u2);
    10. list.add(u3);
    11. list.add(u4);
    12. userMapper.insertByForEach(list);
    13. sqlSession.commit();
    14. }

    结果:

     6.4   批量更新

    设置批量更新,这里批量在于批量执行update的sql语句,不能使用类似的where in 查询条件,否则会将不同id的行的属性值修改为完全一样的数据

    并且如果要进行批量的更新操作需要在jdbc.properties中添加允许批量操作的编码,否则批量插入会失败

    jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
    1. //批量更新
    2. int updateByForEach(List list);
    1. <update id="updateByForEach">
    2. <foreach collection="list" item="u" separator=";">
    3. update user
    4. <set>
    5. <if test="u.userName != null and u.userName != ''">
    6. username = #{u.userName},
    7. if>
    8. <if test="u.birthday != null">
    9. birthday = #{u.birthday},
    10. if>
    11. <if test="u.sex != null and u.sex != ''">
    12. sex = #{u.sex},
    13. if>
    14. <if test="u.address != null and u.address != ''">
    15. address = #{u.address},
    16. if>
    17. set>
    18. where id = #{u.id}
    19. foreach>
    20. update>
    1. //批量更新
    2. @Test
    3. public void testUpdateByForEach() throws ParseException {
    4. List list = new ArrayList<>();
    5. User u1 = new User(14,"kkkk",format.parse("2008-01-03"),"1","888");
    6. User u2 = new User(15,"ddkk",format.parse("2008-01-03"),"2","666");
    7. User u3 = new User(16,"gggg",format.parse("2008-01-03"),"2","777");
    8. User u4 = new User(17,"llgg",format.parse("2008-01-03"),"2","xianxianxianxian");
    9. list.add(u1);
    10. list.add(u2);
    11. list.add(u3);
    12. list.add(u4);
    13. userMapper.updateByForEach(list);
    14. sqlSession.commit();
    15. }

    编译后的sql语句:

    7,指定参数位置 

    如果入参数多个,可以通过指定参数位置,来进行参数传递。

    实体类只能封装住成员变量的条件,如果某个变量又区间范围内的判断或者有两个值要进行判断,那么一个实体类就包不住,就需要使用指定参数位置,来进行范围查询。

    查询生日在2000-01-01到2010-01-01之间的数据

    1. //指定日期范围内查询
    2. List getByBetween(Date begin,Date end);
    1. <select id="getByBetween" resultType="user">
    2. select <include refid="allColumns">include>
    3. from user
    4. where birthday
    5. between #{arg0} and #{arg1}
    6. select>
    1. @Test
    2. public void testGetBetween() throws ParseException {
    3. Date begin = format.parse("2000-01-01");
    4. Date end = format.parse("2010-01-01");
    5. List users = userMapper.getByBetween(begin, end);
    6. users.forEach(user -> System.out.println(user));
    7. }

    8,入参是map

    若传入的参数有多个,使用map方式,更省事,更明确,更具语义,在实体类封装不住的情况下

     

    1. //入参数map的查找
    2. List getByMap(Map map);
    1. <select id="getByMap" resultType="user">
    2. select <include refid="allColumns">include>
    3. from user
    4. where birthday
    5. between #{birthBegin} and #{birthEnd}
    6. select>
    1. @Test
    2. public void testGetByMap() throws ParseException {
    3. Date begin = format.parse("2000-01-01");
    4. Date end = format.parse("2010-01-01");
    5. Map map = new HashMap<>();
    6. map.put("birthBegin",begin);
    7. map.put("birthEnd",end);
    8. List users = userMapper.getByMap(map);
    9. users.forEach(user -> System.out.println(user));
    10. }

     

    9,返回值是map

     

    9.1 返回值单行map

    返回值保存在map中,通过map.get("列名")得到查询的值

    1. //返回值是单行map
    2. Map getSimpMap(Integer id);
    1. <select id="getSimpMap" parameterType="int" resultType="map">
    2. select username,address
    3. from user
    4. where id = #{id}
    5. select>
    1. @Test
    2. public void testGetSimpMap() throws ParseException {
    3. Map map = userMapper.getSimpMap(5);
    4. System.out.println(map.get("username"));//查询到的值保存在了对应的列名中,或者列名的别名中
    5. }

     

    9.2 返回值是多行map

    1. @Test
    2. public void testGetSimpMap() throws ParseException {
    3. Map map = userMapper.getSimpMap(5);
    4. System.out.println(map.get("username"));//查询到的值保存在了对应的列名中,或者列名的别名中
    5. }
    1. <select id="getMulMap" resultType="map">
    2. select username,address
    3. from user;
    4. select>
    1. @Test
    2. public void testGetMulMap() throws ParseException {
    3. List mulMap = userMapper.getMulMap();
    4. mulMap.forEach(map -> System.out.println(map));
    5. }

     

    10,表的列名和实体属性值不一致的解决方案

    方案一:给列名取别名和成员变量保持一致

     

     方案二:通过resultMap手工完成映射,

  • 相关阅读:
    C、指针基础1
    平均精度(AP)
    C语言:堆
    upload-labs靶场通关指南(16-17关)
    1159 Structure of a Binary Tree 甲级 xp_xht123
    前端培训丁鹿学堂:node使用http模块进行请求转发
    springboot+vue微信小程序的医院核酸检测预约挂号微信小程序#毕业设计
    系统渐渐沦为“屎山”,原因是..
    Spring In Action 5 学习笔记 chapter4 Spring Security部分关键点
    基于paddlehub 未戴口罩检测算法
  • 原文地址:https://blog.csdn.net/qq_52655865/article/details/126338699