mybatis

2020-07-14  本文已影响0人  小烧饼a

第四章 Mybatis输入类型和结果类型

第1章

1.1 parameterType****(输入类型)

1.1.1 传递简单类型

参考第一天内容。

使用#{}占位符,或者${}进行Sql拼接。

1.1.2 传递Pojo对象

参考第一天的内容。

{}或者${}括号中的值为Pojo属性名称。

1.1.3 传递Pojo包装对象

包装对象:Pojo类中的一个属性是另外一个Pojo。

为什么使用包装对象?

在平时的开发中,不一定就是单纯的对一个实体进行增删改查,例如完成用户信息的综合查询,有时需要传入查询条件很复杂,可能包括用户信息、关联表的其它信息等。针对这种需求,在Mybatis中我们可以使用自定义的包装类型的Pojo,在包装类型的Pojo中将复杂的查询条件包装进去。

功能需求:根据用户名模糊查询用户信息,查询条件放到QueryVo的user属性中。

1.1.3.1 编写QueryVo

|

public class QueryVo {

// 包含其他的pojo

privateUser user;

public User getUser() {

return user;

}

public voidsetUser(User user) {

this.user= user;

}

}

|

1.1.3.2 Sql语句

SELECT * FROM USER WHERE USERNAME LIKE '%王%'

1.1.3.3 Mapper.xml文件

在UserMapper.xml中配置Sql,如下图。

[图片上传失败...(image-da9f7e-1594741154724)]

1.1.3.4 Mapper接口

在UserMapper接口中添加方法,如下图:

[图片上传失败...(image-1b59f5-1594741154724)]

1.1.3.5 测试方法

在UserMapeprTest增加测试方法,如下:

|

@Test

public void testQueryUserByQueryVo() {

SqlSession sqlSession= this.sqlSessionFactory.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

// 使用userMapper执行查询,使用包装对象

QueryVo queryVo= new QueryVo();

// 设置user条件

User user= new User();

user.setUsername("%王%");

// 设置到包装对象中

queryVo.setUser(user);

// 执行查询

List<User> list= userMapper.queryUserByQueryVo(queryVo);

for(User u: list) {

System.out.println(u);

}

sqlSession.close();

}

|

1.1.3.6 效果

测试结果如下图:

[图片上传失败...(image-fce264-1594741154724)]

1.2 resultType(输出结果类型)

1.2.1 输出简单类型

功能需求:查询用户表数据条数

Sql语句:SELECT count(*) FROM user

1.2.1.1 M****apper.xml文件

在UserMapper.xml中配置Sql,如下图:

[图片上传失败...(image-5d5cba-1594741154724)]

1.2.1.2 M****apper接口

在UserMapper添加方法,如下图:

[图片上传失败...(image-e7f492-1594741154723)]

1.2.1.3 测试方法

在UserMapeprTest增加测试方法,如下:

|

@Test

public void testQueryUserCount() {

SqlSession sqlSession= this.sqlSessionFactory.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

int count= userMapper.queryUserCount();

System.out.println(count);

sqlSession.close();

}

|

1.2.1.4 效果

测试结果如下图:

[图片上传失败...(image-8a347b-1594741154723)]

注意:输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型

1.2.2 输出Pojo对象

参考第一天内容

1.2.3 输出Pojo列表

参考第一天内容

1.3 resultMap

resultType可以指定将查询结果映射为Pojo,但需要Pojo的属性名和Sql查询的列名一致方可映射成功。

如果Sql查询字段名和Pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到Pojo对象中。

功能需求:查询订单表orders的所有数据

Sql语句:SELECT id, user_id, number, createtime, note FROM orders

1.3.1 创建数据表、初始化测试数据、****声明****P****ojo对象

创建订单表并查询订单表的全部数据,Sql语句如下:

|


-- Table structure for orders


DROP TABLE IF EXISTS orders;

CREATE TABLE orders (

id int(11) NOT NULL AUTO_INCREMENT,

user_id int(11) NOT NULL COMMENT '下单用户id',

number varchar(32) NOT NULL COMMENT '订单号',

createtime datetime NOT NULL COMMENT '创建订单时间',

note varchar(100) DEFAULT NULL COMMENT '备注',

PRIMARY KEY (id),

KEY FK_orders_1 (user_id),

CONSTRAINT FK_orders_id FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;


-- Records of orders


INSERT INTO orders VALUES ('3', '3', '1000010', '2015-02-04 13:22:35', null);

INSERT INTO orders VALUES ('4', '3', '1000011', '2015-02-03 13:22:41', null);

INSERT INTO orders VALUES ('5', '4', '1000012', '2015-02-12 16:13:23', null);

|

Orders对象:

|

public class Orders {

// 订单id

private int id;

// 用户id

privateInteger userId;

// 订单号

privateString number;

// 订单创建时间

privateDate createtime;

// 备注

privateString note;

get/set…

}

|

1.3.2 M****apper.xml文件

创建OrdersMapper.xml配置文件,如下:

|

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itheima.mybatis.mapper.OrdersMapper">

<select id="queryOrdersAll" resultType="orders">

SELECT id, user_id,

number,

createtime, note FROM orders

</select>

</mapper>

|

1.3.3 Mapper接口

编写接口如下:

|

public interface OrdersMapper {

/**

*/

List<Orders> queryOrdersAll();

}

|

1.3.4 测试方法

编写测试方法OrdersMapperTest如下:

|

public class OrdersMapperTest {

privateSqlSessionFactory sqlSessionFactory;

@Before

public voidinit() throws Exception {

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

this.sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);

}

@Test

public void testQueryAll() {

// 获取sqlSession

SqlSession sqlSession= this.sqlSessionFactory.openSession();

// 获取OrderMapper

OrdersMapper orderMapper= sqlSession.getMapper(OrdersMapper.class);

// 执行查询

List<Orders> list= orderMapper.queryOrdersAll();

for(Orders order: list) {

System.out.println(order);

}

sqlSession.close();

}

}

|

1.3.5 效果

测试效果如下图:

[图片上传失败...(image-325f71-1594741154720)]

发现userId为null

解决方案:使用resultMap

1.3.6 使用resultMap

由于上边的mapper.xml中Sql查询列(user_id)和Order类属性(userId)不一致,所以查询结果不能映射到Pojo中。

需要定义resultMap,把orderResultMap将Sql查询列(user_id)和Order类属性(userId)对应起来

改造OrderMapper.xml,如下:

|

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itheima.mybatis.mapper.OrdersMapper">

<resultMap type="orders" id="orderResultMap">

<id property="id" column="id" />

<result property="userId" column="user_id" />

<result property="number" column="number" />

<result property="createtime" column="createtime" />

<result property="note" column="note" />

</resultMap>

<select id="queryOrdersAll" resultMap="orderResultMap">

SELECT id, user_id,

number,

createtime, note FROM orders

</select>

</mapper>

|

1.3.7 效果

只需要修改Mapper.xml就可以了,再次测试结果如下:

[图片上传失败...(image-7df7e5-1594741154719)]

第1章 Mybatis映射文件的SQL深入

Mybatis的映射文件中,前面我们的SQL都是比较简单的,有些时候业务逻辑复杂时,我们的SQL是动态变化的,此时在前面的学习中我们的SQL就不能满足要求了。

参考的官方文档,描述如下:

[图片上传失败...(image-c85a0f-1594741219533)]

通过Mybatis提供的各种标签方法实现动态拼接Sql。

功能需求:根据性别和名字查询用户

Sql语句:

SELECT id, username, birthday, sex, address FROM user WHERE sex = 1 AND username LIKE '%张%'

1.1 If****标签

1.1.1 Mapper.xml文件

UserMapper.xml配置Sql,如下:

|

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT id, username, birthday, sex, address FROM user

WHERE sex = #{sex} AND username LIKE #{username}

</select>

|

1.1.2 Mapper接口

编写Mapper接口,如下图:

[图片上传失败...(image-c94ff7-1594741219533)]

1.1.3 测试方法

在UserMapperTest添加测试方法,如下:

|

@Test

public void testQueryUserByWhere() {

SqlSession sqlSession= this.sqlSessionFactory.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

// 使用userMapper执行根据条件查询用户

User user= new User();

user.setSex("1");

user.setUsername("%王%");

List<User> list= userMapper.queryUserByWhere(user);

for(User u: list) {

System.out.println(u);

}

sqlSession.close();

}

|

1.1.4 效果

测试效果如下图:

[图片上传失败...(image-99183d-1594741219533)]

如果注释掉 user.setSex("1"),测试结果如下图:

[图片上传失败...(image-f6a548-1594741219533)]

测试结果二很显然不合理。

按照之前所学的,要解决这个问题,需要编写多个Sql,查询条件越多,需要编写的Sql就更多了,显然这样是不靠谱的。

解决方案,使用动态Sql的if标签

1.1.5 使用if标签

改造UserMapper.xml,如下:

|

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT id, username, birthday, sex, address FROM user

WHERE 1=1

<if test="sex != null and sex != ''">

AND sex = #{sex}

</if>

<if test="username != null and username != ''">

AND username LIKE

{username}

</if>

</select>

|

注意字符串类型的数据需要做不等于空字符串校验。

1.1.6 效果

[图片上传失败...(image-ae7b8a-1594741219533)]

如上图所示,测试OK

1.2 W****here标签

上面的Sql还有where 1=1 这样的语句,很麻烦

可以使用where标签进行改造

改造UserMapper.xml,如下

|

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT id, username, birthday, sex, address FROM user

<where>

<if test="sex != null">

AND sex = #{sex}

</if>

<if test="username != null and username != ''">

AND username LIKE #{username}

</if>

</where>

</select>

|

1.2.1 效果

测试效果如下图:

[图片上传失败...(image-66c06-1594741219533)]

1.3 S****ql片段

Sql中可将重复的Sql提取出来,使用时用include引用即可,最终达到Sql重用的目的。

把上面例子中的id, username, birthday, sex, address提取出来,作为Sql片段,如下:

|

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT <include refid="userFields" /> FROM user

<where>

<if test="sex != null">

AND sex = #{sex}

</if>

<if test="username != null and username != ''">

AND username LIKE #{username}

</if>

</where>

</select>

<sql id="userFields">

id, username, birthday, sex, address

</sql>

|

如果要使用别的Mapper.xml配置的Sql片段,可以在refid前面加上对应的Mapper.xml的namespace,如下

|

SELECT <include refid="com.itheima.mybatis.mapper.OrdersMapper.userFields" /> FROM user

|

1.4 foreach标签

向Sql传递List,Mybatis使用foreach解析。

功能需求:根据多个id查询用户信息

查询Sql语句:

SELECT * FROM user WHERE id IN (1,10,24)

1.4.1 Mapper.xml文件

UserMapper.xml添加Sql,如下:

|

<select id="queryUserByIds" parameterType="list" resultType="user">

SELECT * FROM user

<where>

<foreach collection="list" item="item" open="id IN (" close=")"

separator=",">

{item}

</foreach>

</where>

</select>

|

测试方法如下图:

|

@Test

public void testQueryUserByIds() {

SqlSession sqlSession= this.sqlSessionFactory.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

// 使用userMapper执行根据条件查询用户

List<Integer> ids= new ArrayList<Integer>();

ids.add(2);

ids.add(3);

ids.add(4);

List<User> list= userMapper.queryUserByIds(ids);

for(User u: list) {

System.out.println(u);

}

sqlSession.close();

}

|

1.4.2 效果

测试效果如下图:

[图片上传失败...(image-a5840a-1594741219532)]

上一篇下一篇

猜你喜欢

热点阅读