上一篇文章,我们主要讲了Mybatis的增、删、改操作,本篇文章我们来学习Mybatis的查询操作以及使用XML来实现Mybatis的开发。
查(select)
上篇文章我们已经使用过查询字段,但是仔细观察就会发现此时查询到的字段是有问题的:
我们发现当数据库的字段名和我们在实体类中的属性名一致时,就自动赋值了,而因为数据库的变量命名规范和Java中的不同,所以这三个名称不同的变量就没有赋值成功,显示为null。
如何解决呢?==》一共有三种解决方法
1、起别名
接口代码
@Select("select id,username,age,phone,gender, " +
"delete_flag as deleteFlag,create_time as createTime" +
",update_time as updateTime from userinfo")
List<Userinfo> selectAllList();
测试代码:
@Test
void selectAllList() {
System.out.println(mapper.selectAllList());
}
测试结果:
2、结果映射
要进行结果映射,我们需要使用@Results注解。
代码如下:
//结果映射
@Results({@Result(column = "delete_flag" ,property = "deleteFlag"),
@Result(column = "create_time" ,property = "createTime"),
@Result(column = "update_time" ,property = "updateTime")
})
@Select("select * from userinfo")
List<Userinfo> selectAllList2();
测试代码:
@Test
void selectAllList2() {
System.out.println(mapper.selectAllList2());
}
测试结果:
此外,我们可以对结果映射进行复用,上文中的查询结果是有问题的:我们先给刚才的@Result注解添加上id属性
@Results(id = "resultMap",value = {@Result(column = "delete_flag" ,property = "deleteFlag"),
@Result(column = "create_time" ,property = "createTime"),
@Result(column = "update_time" ,property = "updateTime")
})
然后在昨天查找的方法上添加上@ResultMap注解:
//查询所有用户
@ResultMap("resultMap")
@Select("select * from userinfo")
List<Userinfo> select();
运行昨天的测试代码:
@Test
void select() {
System.out.println(mapper.select());
}
3、自动驼峰转换
在spring配置文件中,写上如下配置:
mybatis:
configuration:
map-underscore-to-camel-case: true #自动驼峰转换
mapper代码:
//驼峰自动转换
@Select("select * from userinfo")
List<Userinfo> selectAllList3();
测试代码:
@Test
void selectAllList3() {
System.out.println(mapper.selectAllList3());
}
注意:实际开发中尽量不要使用select * 这样的查询方式,要查询什么字段名直接查就好,这里是为了方便学习使用select *。
Mybatis XML开发
上面我们学习了使用注解的方式对Mybatis进行开发,接下来我们学习使用XML方式开发MyBatis。
MyBatis XML方式需要以下两步:
1、配置数据库连接字符串和MyBatis
2、写持久层代码
配置MyBatis和数据库连接字符串
yml配置文件:
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
username: root
password: 5028
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
# 设置 Mybatis 的 xml 保存路径
mapper-locations: classpath:mapper/*Mapper.xml
添加Mapper接口
添加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.example.mybatis.mapper.UserInfoMapper">
</mapper>
配置后面会讲,这里先复制粘贴即可。
增(insert)
mapper代码:
@Mapper
public interface UserInfoMapper {
Integer insert(Userinfo userinfo);
}
这里博主给大家推荐一个MyBatis插件:
当我们还没写XML代码时它会自动爆红:
Alt+Insert这个插件就会自动生成一些XML代码,我们仅需补充sql语句即可:
XML代码
<insert id="insert">insert into userinfo (id, username, password, age, gender, phone)
values(#{id},#{username},#{password},#{age},#{gender},#{phone})</insert>
测试代码:
@SpringBootTest
class UserInfoMapperTest {
@Autowired
private UserInfoMapper mapper;
@Test
void insert() {
Userinfo userInfo = new Userinfo();
userInfo.setUsername("java");
userInfo.setGender(1);
userInfo.setAge(18);
userInfo.setPassword("java666");
userInfo.setPhone("java123456");
Integer insert = mapper.insert(userInfo);
System.out.println("新增"+insert+"条数据");
}
}
测试结果:
Mapper方法和XML文件连接示意图:
常见问题:
删(delete)
mapper:
Integer delete(Integer id);
XML代码:
<delete id="delete">
delete from userinfo where id = #{id}
</delete>
测试代码:
@Test
void delete() {
System.out.println("删除"+mapper.delete(14)+"条数据");
}
测试结果:
改(update)
mapper:
Integer update(Userinfo userinfo);
XML代码:
<update id="update">
update userinfo set username = #{username},
password = #{password},age = #{age},gender = #{gender} where id = #{id}
</update>
测试代码:
@Test
void update() {
Userinfo userinfo = new Userinfo();
userinfo.setId(1);
userinfo.setUsername("xmy");
userinfo.setAge(18);
userinfo.setPassword("5566");
userinfo.setGender(1);
Integer update = mapper.update(userinfo);
System.out.println("更新了"+update+"条数据");
}
测试结果:
查(select)
查询不管XML方式还是注解的方式,都会出现我们上面讲过的赋值失败的问题。
解决方式:
1、起别名
2、结果映射
3、自动驼峰转换
1、起别名
Mapper:
List<Userinfo> get();
此时我们Alt+Insert,我们发现查的XML代码和增、删、改的代码不同,多了一个returnType。
这是因为:增、删、改的返回值都是Integer或者返回void类型,但是select可能返回各种不同的类型,如:各种不同的对象、Integer等,上面返回的是对象的类的绝对路径。
返回Integer实例(返回表的总列数):
mapper:
Integer getCount();
XML:
<select id="getCount" resultType="java.lang.Integer"> select count(1) from userinfo </select>
测试:
@Test void getCount() { System.out.println("表的总列数:"+mapper.getCount()); }
XML代码:
<select id="get" resultType="com.example.mybatis.model.Userinfo">
select id,username,age,gender,phone,delete_flag as deleteFlag,create_time as createTime,update_time as updateTime from userinfo;
</select>
测试:
@Test
void get() {
System.out.println(mapper.get());
}
2、结果映射
与注释的方法不同,我们这里是将resultMap写在XML文件中的(一般在XML配置的下面):
<resultMap id="BaseMap" type="com.example.mybatis.model.Userinfo">
<id column="id" property="id"></id>
<result column="delete_flag" property="deleteFlag"></result>
<result column="create_time" property="createTime"></result>
<result column="update_time" property="updateTime"></result>
</resultMap>
mapper:
List<Userinfo> get2();
XML:
<select id="get2" resultType="com.example.mybatis.model.Userinfo" resultMap="BaseMap">
select * from userinfo
</select>
测试:
resultMap与XML语句的关系:
3、驼峰自动转换
依然是刚才的yml配置:
mybatis:
configuration:
map-underscore-to-camel-case: true #自动驼峰转换
Mapper:
List<Userinfo> get3();
XML:
<select id="get3" resultType="com.example.mybatis.model.Userinfo">
select * from userinfo
</select>
测试:
@Test
void get3() {
System.out.println(mapper.get3());
}
多表查询
准备工作
上面已经创建了一张用户表,我们在来建一个文章表。
-- 创建文章表
DROP TABLE IF EXISTS articleinfo;
CREATE TABLE articleinfo (
id INT PRIMARY KEY auto_increment,
title VARCHAR ( 100 ) NOT NULL,
content TEXT NOT NULL,
uid INT NOT NULL,
delete_flag TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
create_time DATETIME DEFAULT now(),
update_time DATETIME DEFAULT now()
) DEFAULT charset 'utf8mb4';
-- 插入测试数据
INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'Java', 'Java正文', 1 );
再将文章表中的字段转变为java中的属性(包括在用户表中要查询的属性——方便使用toString方法打印):
@Data
public class Articleinfo {
private Integer id;
private String title;
private String content;
private Integer uid;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
//要查询的userinfo表中的属性
private String username;
private Integer gender;
}
创建新的mapper类并且与xml文件连接:
进行多表查询
mapper:
@Mapper
public interface ArticleinfoMapper {
List<Articleinfo> getArticleinfoAndUserinfo();
}
XML:
<select id="getArticleinfoAndUserinfo" resultType="com.example.mybatis.model.Articleinfo">
select ta.*,tb.username,tb.gender from articleinfo ta
right join userinfo tb on ta.id = tb.id where ta.id = 1
</select>
测试:
@SpringBootTest
class ArticleinfoMapperTest {
@Autowired
private ArticleinfoMapper mapper;
@Test
void getArticleinfoAndUserinfo() {
System.out.println(mapper.getArticleinfoAndUserinfo());
}
}
但是在实际开发中,我们不经常使用多表查询,因为使用多表查询会产生慢sql问题,查询一个sql肯能需要十几秒,如果是C端开发,每个用户都要等个十多秒,这样用户的体验会很差。如果是B端或者是性能要求比较低的项目就无所谓,但是也可以配备索引提高查询效率。