SSM学习之路——Mybatis第二天_CRUD_实体类和字段不统一问题

一、使用实体类的包装对象作为查询条件

在实际开发中我们的查询条件并不一定像之前那样单一,可能会用到多个对象组装起来的查询条件,比如查找某个用户对应的某个商品对象的xx属性值,这个时候就要用到多个对象作为参数,但是我们在写dom的时候传入的parameterType只能是一个实体类,那么怎么做呢,我们可以将用到的对象包装到一个实体类中,传入这个包装后的实体类,实现多对象的条件查询。

1.新建一个QueryVo类

在这里插入图片描述

2. 在里面写用到的对象

为了方便起见,这里只写一个user对象。如果有需要的话可以再添加

public class QueryVo {
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

3. 编写xml

返回结果类型为User实体类 传入参数为包装类QueryVo

因为传入参数的是QueryVo类,而如果条件是: like #{username} 而在QueryVo中
并没有username这个字段,只有user,因此要获取username,则要使用user.username来取得

<!--通过实体类对象来封装查询条件-->
    <select id="findUserByQueryVo" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.QueryVo">
        select * from user where username like #{user.username}
    </select>

4.编写测试类

先在user类中setUsername,再vo.setUser(user)来与user建立联系

//通过实体类QueryVo封装条件查询
    @Test
    public void testFindUserByQueryVo(){
        QueryVo vo = new QueryVo();
        User user = new User();
        user.setUsername("%老1%");
        vo.setUser(user);
        List<User> users = userDao.findUserByQueryVo(vo);
        for (User u : users){
            System.out.println(u);
        }

    }

5.测试结果

在这里插入图片描述

二、解决实体类和数据库列名不对应的两种方法

前提:Mybatis的前提是传入的参数要和数据库类名一样,但是在实际开发中,数据库设计的字段往往和类中字段不好统一,这个时候我们就要找到一种能够统一的方法,这里有两种方法

准备工作:将类中的字段改成不和数据库统一
改前:对应相同
在这里插入图片描述
在这里插入图片描述
改后:
在这里插入图片描述
测试:testFindAll()
在这里插入图片描述
从中发现,我们除了username还可以找到之外,其他都没有映射到包装类中,为什么呢?
这里:在windows下 数据库是不区分大小写的,所以在执行sql语句的时候,数据库将userName当成了username,在数据库中可以找到相应的字段username字段
但是由于其他字段,都有字母的增加,在数据库中找不到对应的,没法完成映射到实体类中,因此取出来都为null。

方法一、修改sql语句(取别名)

通过修改sql语句,将字段与sql列名对应起来

<select id="findAll" resultType="com.itheima.domain.User">
        select id as userId,username as userName,birthday as UserBirthday,sex as UserSex,address as userAddress from user;
    </select>

你可以发现我上面UserBirthday和userBirthday并不对应…原因上面已经讲过了,windows下mysql的sql语句并不区分大小写,但是在Linux系统下是严格区分的

完美get
在这里插入图片描述

方法二、通过添加映射

resultMao的id为自己取的,type为映射的实体类
其中<id property="userId" column="id"></id>为主键字段的对应
其他字段都为<result>

在这里插入图片描述

<select id="findAll" resultType="com.itheima.domain.User">
        <!--select id as userId,username as userName,birthday as userBirthday,sex as userSex,address as userAddress from user;-->
        select * from user;
    </select>

接着 我们运行看看!
在这里插入图片描述

你咋骗人呢!

我们康康是什么问题

原因是 我们写了resultMap映射 但是咱没用它啊!还是用原来的select * from user
当然行不通了!此时
<select id="findAll" resultType="com.itheima.domain.User">
中的resultType="com.itheima.domain.User" 没用了 要将这个改成对上面resultMap的映射

改成resultMap value为上面resultMap指定的id

<select id="findAll" resultMap="userMap">
    <!--select id as userId,username as userName,birthday as userBirthday,sex as userSex,address as userAddress from user;-->
    select * from user;

在这里插入图片描述

总结优劣:

1、显然通过直接修改sql语句 执行效率会比较快,因为通过resultMap的话 select之后还要再执行resultMap这一步 无疑是增加了运行时间
2、使用resultMap的好处是,万一有很多个查询条件,如果一个一个修改sql语句,无疑是增加了时间成本,使用resultMap就可以将每个查询条件的resultType对应的实体类改成resultMap即可,只需要修改一个引用,无需对很多sql语句动刀,大大提高开发效率。
(比如有100个sql语句 每个语句都起个别名 而且每个语句需要用到的字段可能有所不同,就要看需求改动100个sql语句。
不然就直接把那一个resultMap改了就可以了,其他查询语句只需要把resultType 使用ctrl+c and v 统一改成同一个对resultMap = “userMap”的引用即可!!只需要cv 100次就好了,简单无脑)
3、在程序可读性上面来说,写一个<resultMap >将每个java字段对应的数据库的字段清楚明了的表现了出来,而且在程序维护上来说,万一修改了字段,动刀的地方就少了很多。

即:用resultMap映射的方式,更好!
发布了23 篇原创文章 · 获赞 0 · 访问量 608

猜你喜欢

转载自blog.csdn.net/SixthMagnitude/article/details/103907324
今日推荐