Mybatis_2
上一篇文章,我们主要讲了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();
测试代码:
@Testvoid 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();
测试代码:
@Testvoid 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();
运行昨天的测试代码:
@Testvoid select() {System.out.println(mapper.select());}
3、自动驼峰转换
在spring配置文件中,写上如下配置:
mybatis:configuration: map-underscore-to-camel-case: true #自动驼峰转换
mapper代码:
//驼峰自动转换@Select("select * from userinfo")List<Userinfo> selectAllList3();
测试代码:
@Testvoid 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=falseusername: rootpassword: 5028driver-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 {@Autowiredprivate UserInfoMapper mapper;@Testvoid 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>
测试代码:
@Testvoid 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>
测试:
@Testvoid 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>
测试:
@Testvoid 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>
测试:
@Testvoid 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 taright join userinfo tb on ta.id = tb.id where ta.id = 1</select>
测试:
@SpringBootTest
class ArticleinfoMapperTest {@Autowiredprivate ArticleinfoMapper mapper;@Testvoid getArticleinfoAndUserinfo() {System.out.println(mapper.getArticleinfoAndUserinfo());}
}
但是在实际开发中,我们不经常使用多表查询,因为使用多表查询会产生慢sql问题,查询一个sql肯能需要十几秒,如果是C端开发,每个用户都要等个十多秒,这样用户的体验会很差。如果是B端或者是性能要求比较低的项目就无所谓,但是也可以配备索引提高查询效率。