- 什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
文章目录
mybatis
mybatis的历史
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对iBatis进行一些改进。
注解版:查询所有SearchAll
mybatis所需的jar包和配置文件(链接:https://pan.baidu.com/s/1e_vWUodbaCXGl_qdFDNTOQ 提取码:zr3p);
数据库和表:User
# 创建数据库
CREATE DATABASE ssm_db1;
# 使用数据库
USE ssm_db1;
# 1.1 创建用户表
CREATE TABLE `user` (
`uid` VARCHAR(32) NOT NULL,
`username` VARCHAR(20) DEFAULT NULL, #用户名
`password` VARCHAR(32) DEFAULT NULL, #密码
`name` VARCHAR(20) DEFAULT NULL, #昵称
`email` VARCHAR(30) DEFAULT NULL, #电子邮箱
`telephone` VARCHAR(20) DEFAULT NULL, #电话
`birthday` DATE DEFAULT NULL, #生日
`sex` VARCHAR(10) DEFAULT NULL, #性别
`state` INT(11) DEFAULT 0, #状态:0=未激活,1=已激活
`code` VARCHAR(64) DEFAULT NULL, #激活码
PRIMARY KEY (`uid`)
) ;
# 1.2 初始化用户默认数据
INSERT INTO `user` VALUES ('u001','jack','1234','杰克','jack@czxy.com','13612345678','2015-11-04','男',0,NULL);
INSERT INTO `user` VALUES ('u002','rose','1234','肉丝','rose@czxy.com','13612345679','2015-11-05','女',0,NULL);
一. JavaBean
public class User {
private String uid;
private String userName;
private String password;
private String name;
private String email;
private Date birthday;
private String sex;
private Integer state;
private String code;
...get/set/toString
}
二. 编写Dao:UserMapper
public interface UserMapper {
/**
* 查询所有
* @return
*/
@Select("select * from user")
public List<User> selectAll();
}
三.修改:SqlMapConfig.xml
<mappers>
<!-- 表示加载此包下的所有dao接口-->
<package name="com.czxy.dao"/>
</mappers>
四.编写测试类
public static void main(String[] args) throws IOException {
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
List<User> list = userMapper.selectAll();
list.forEach(System.out::println);
MyBatisUtils.close();
}
结果集映射Result
实际开发中,如果数据库字段和Java对象字段不能对应,就需要我们编写对应关系。
注解 | 描述 |
---|---|
@Results | 对象和表的映射关系。 |
@Result | 一个对象属性和一个表的字段的映射关系。 |
@ResultMap | 映射关系,使用@Results声明的映射关系。 |
语法:
/**
@Results(value = 一组Result )
*/
@Results(value = {
@Result(property = "属性名", column = "字段名", id = true),
@Result(property = "属性名2", column = "字段名2"),
@Result(property = "属性名3", column = "字段名3")
})
注解版注解总结
注解名称 | 描述 |
---|---|
@Insert | 添加sql |
@Update | 更新sql |
@Delete | 删除sql |
@Select | 查询sql |
@Param | 形参命名 |
@Results | 对象和表的映射关系。 |
@Result | 一个对象属性和一个表的字段的映射关系。 |
分页查询
语法:
1) 设置分页数据
PageHelper.startPage(int pageNum, int pageSize)
参数1:pageNum 第几页
参数2:pageSize 页面显示个数
2) 封装分页结果 PageInfo
new PageInfo(查询结果) //创建分页对象
pageInfo.getTotal(), //自动查询总条数
pageInfo.getPages(), //总分页数
//TODO: 实际操作
public static void main(String[] args) {
StudentMapper studentMapper = MyBatisUtils.getMapper(StudentMapper.class);
//设置分页参数
PageHelper.startPage(1,2);
//分页数据
List<Student> list = studentMapper.searchAllStudent();
//分页封装
PageInfo<Student> pageInfo = new PageInfo<>(list);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("每页个数:"+pageInfo.getPageSize());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("分页数:"+pageInfo.getPages());
System.out.println("是否上一页:"+pageInfo.isHasPreviousPage());
System.out.println("是否下一页:"+pageInfo.isHasNextPage());
MyBatisUtils.commitAndclose();
}
通用Mapper
概述
-
通用Mapper对MyBatis进行简化的第三方工具包。
-
通用Mapper提供了一个名为
Mapper<T>
的接口,用于自动完成单表的增删改查操作。 -
如果通用Mapper中的方法不足以满足你的需求,直接添加自定义方法即可。
public interface UserMapper extends Mapper<User> {
}
API
-
查询方法
方法名 描述 T selectOne(T t) 根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号 List select(T t) 根据实体中的属性值进行查询,查询条件使用等号 List selectAll() 查询全部结果 int selectCount(T t) 根据实体中的属性查询总数,查询条件,使用等号 T selectByPrimaryKey(Object key) 根据主键字段进行查询 boolean existsWhithPrimaryKey(Object key) 根据主键字段查询记录是否存在 List selectByExample(Object example) 根据Example条件进行查询 T selectOneByExample(Object example) 根据Example条件进行查询,只能有一个返回值 int selectCountByExample(Object example) 根据Example条件进行查询记录数 -
插入方法
方法名 描述 int insert(T t) 保存一个实体,null的属性也会保存,不会使用数据库默认值 int intsertSelective(T t) 保存一个实体,null的属性不会保存,使用数据库默认值 -
更新方法
方法名 描述 int updateByPrimaryKey(T t) 根据主键更新实体全部字段,null值会被更新 int updateByPrimaryKeySelective(T t) 根据主键更新实体中不为null值的字段 -
删除方法
方法名 描述 int delete(T t) 根据实体属性作为条件进行删除,查询条件使用等号 int deletePrimaryKey(Object key) 根据主键字段进行删除 int deleteByExample(Object example) 根据Example条件删除数据
mybatis的XML方式
入门案例:查询指定用户
一. 修改核心配置文件
<mappers>
<!-- 表示加载此包下的所有dao接口-->
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
二. UserMapper接口
public interface UserMapper {
/**
* 查询用户
* @return
*/
public List<User> searchUser(String userName);
}
三. UserMapper.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.czxy.dao.UserMapper">
<select id="searchUser" parameterType="string" resultType="user">
select * from `user` where user_name=#{userName}
</select>
</mapper>
四. 测试类
/**
* 查询用户信息
*/
@Test
public void searchUser(){
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
List<User> list = userMapper.searchUser("张三");
list.forEach(System.out::println);
MyBatisUtils.commitAndclose();
}
Mapper基本结构
<?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="Mapper类">
<!-- 查询 -->
<select id="方法名">SQL语句</select>
<!-- 添加 -->
<insert id="方法名">SQL语句</insert>
<!-- 更新 -->
<update id="方法名">SQL语句</update>
<!-- 删除 -->
<delete id="方法名">SQL语句</delete>
</mapper>
Mapper 参数类型:parameterType
- 在映射文件mapper中,我们使用parameterType设置请求参数的类型
<?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="mapper类">
<select id="方法名" parameterType="参数类型">SQL语句</select>
</mapper>
-
简单类型:
<!-- 通过id查询 --> <select id="findUserById" parameterType="int" resultType="com.czxy.domain.User"> select * from user where uid = #{id} </select>
-
POJO类型:
<!-- 添加用户 --> <insert id="insertUser" parameterType="com.czxy.domain.User"> insert into user(uid, username, password, name, email, birthday, sex, state) values(#{uid},#{username},#{password},#{name},#{email},#{birthday},#{sex},#{state}) </insert>
Mapper 结果类型:resultType
- 在映射文件mapper中,我们使用resultType设置查询结果类型
<?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="mapper类">
<select id="方法名" resultType="结果类型">SQL语句</select>
</mapper>
-
简单类型
<!-- 总记录数 --> <select id="findUserCount" resultType="int"> select count(*) from user </select>
-
POJO类型
<!-- 通过id查询 --> <select id="findUserById" parameterType="int" resultType="com.czxy.domain.User"> select * from user where uid = #{id} </select>
Mapper 映射关系:ResultMap
-
resultType可以指定pojo将查询结果封装到该pojo中,但需要pojo的属性名和sql查询的列名保持一致。
-
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系。
-
语法:
<!--声明映射--> <resultMap type="JavaBean类型" id="resultMap名称"> <id column="表列名" property="JavaBean属性名"/> <!--用于配置主键的映射--> <result column="表列名" property="JavaBean属性名"/> <!--用于配置普通结果集映射--> </resultMap> <!--使用映射--> <select resultMap="resultMap名称"> </select>
自定义别名
-
声明别名,在 SqlMapConfig.xml 配置文件中声明
-
方式1:一次定义一个类
<typeAliases> <typeAlias type="类型" alias="别名"/> </typeAliases>
-
方式2:一次定义一个包下的所有类
<typeAliases> <package name="包名"/> </typeAliases>
-
动态SQL
什么是动态SQL
动态SQL就是Mybatis允许在映射文件中通过标签控制SQL语句最后的拼凑结果。
if 标签
-
语法:在mapper映射文件中,<if>标签就相当于Java中if语句,如果条件成立,标签体内的SQL语句有效。
<select> <if test="条件"> //有效的SQL语句片段 </if> <select>
-
多条件查询,拼凑恒等条件 where 1=1
<select id="condition" parameterType="userVo" resultType="user" > select * from user where 1=1 <if test="name != null and name != ''"> and name like '%${name}%' </if> </select>
where 标签
-
多条件查询时,我们使用了一个小技巧“where 1=1”,mybatis提供了一个
<where>
进行取代。 -
修改映射文件
<select id="condition" parameterType="userVo" resultType="user" > select * from user <where> <if test="name != null and name != ''"> and name like '%${name}%' </if> </where> </select>
foreach 标签
-
语法:
<!-- <foreach> 就是遍历一组数据,根据指定的内容拼凑成SQL语句片段 collection ,需要遍历的数据,如果实际参数就是数组本身,此处需要使用array item ,每一次循环时存放数据的变量,在标签体中可以通过 ${item值}获得遍历数据 open ,SQL语句片段的开发位置 separator,分隔符号 close ,SQL语句片段的结束位置 --> <!-- 例如:uid in (1,2,4,6) 片段的拼凑 开始 (变量 分隔符)*4 结束 --> <foreach collection="数组" open="uid in (" item="变量" separator="," close=")"> </foreach>
-
多条件查询
<select id="condition" parameterType="userVo" resultType="user" > select * from user <where> <!-- uid in (1,2,4,6) --> <foreach collection="ids" open="uid in (" item="id" separator="," close=")"> '${id}' </foreach> </where> </select>
choose 标签:多条件
- 语法
类似java中的switch,满足when中的条件退出判断,如果都不满足就进入otherwise
<select id="">
<choose>
<when test=""></when>
<when test=""></when>
<otherwise></otherwise>
</choose>
</select>
sql 标签
- MyBatis为我们提供了代码片段,使用
<sql>
定义公共SQL语句,使用<include>
将需要的SQL片段拼凑到指定的位置。
<!-- 所有字段名称SQL片段 -->
<sql id="user_all_column">uid, username, password, name, email, birthday, sex, state</sql>
<select id="selectAll" parameterType="string" resultMap="userResultMap">
select <include refid="user_all_column" /> from user
</select>
自动匹配规范驼峰规则
数据库中我们习惯使用全大写,多个单词用下划线隔开,而po对象中,习惯使用java驼峰规则。那一个一个手工写resultMap字段,浪费开发时间,直接配置一下就可以了。
如:
数据库字段: user_name
Javabean属性: private String userName
mapper配置不需要写字段与属性的配置,会自动映射
- 在SqlMapConfig.xml中进行配置
<settings>
<!--驼峰映射-->
<!--java对象树形驼峰 例如userName,对应数据的下划线 例如:user_name-->
<setting name="mapUnderscoreToCamelCase" value="false"/>
</settings>
- resultMap配置autoMapping=“true”
<resultMap type="String" id="user" autoMapping="true">
</resultMap>