mybatis

简介

什么是 MyBatis?

MyBatis 是一款优秀的==持久层框架==,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。


准备工作

  • 新建maven项目

  • pom.xml文件中导入相关依赖,数据库依赖导入需要的就行

<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!--sqlserver-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.2.0.jre8</version>
</dependency>
<!--测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.3</version>
</dependency>
</dependencies>

核心配置

核心配置文件

配置标签顺序(核心配置文件中的==标签顺序必须符合下面顺序==)

图片没了

核心配置文件mybatis-config.xml示例

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心配置文件-->
<configuration>
<!--1.加载配置文件,从配置文件中读取数据使用${},见下面的数据源配置-->
<properties resource="db.properties"/>

<!--2.配置日志-->
<settings>
<!--标准日志工厂配置-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--配置log4j日志-->
<!--<setting name="logImpl" value="LOG4J"/>-->
</settings>

<!--
3.可以给实体类取别名,之后使用类名不需要写全限定类名
3.1 typeAlias标签页实现
3.2 package 扫描包下所有类并起一个默认别名为类名(小写也可以)或
如果想自定义别名,需要在类名上面加@Alias注解
-->
<typeAliases>
<!--<typeAlias type="com.clb.pojo.User" alias="User"/>-->
<package name="com.clb.pojo"/>
</typeAliases>

<!--4.配置多环境,default指定使用哪个环境-->
<!--<environments default="mysql">-->
<environments default="sqlserver">
<!--mysql数据源-->
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
<!--sql server数据源-->
<environment id="sqlserver">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${ms.driver}"/>
<property name="url" value="${ms.url}"/>
<property name="username" value="${ms.username}"/>
<property name="password" value="${ms.password}"/>
</dataSource>
</environment>
</environments>

<!--
每一个Mapper.xml配置文件都需要在mybatis核心配置文件中注册
1.mapper标签 使用resource指定mapper配置文件注册(无条件!)
2.mapper标签 使用class指定mapper类注册
3.package标签扫描包
总结:第 2,3中方法都需要满足:
条件:1.接口名和它的mapper配置文件名相同
2.接口文件和它的mapper配置文件在同一个包下
1.所以建议使用第一种方法,指定配置文件路径(使用配置文件时)
2.使用注解开发时,使用方法2,3
-->
<mappers>
<mapper resource="com/clb/dao/EmpMapper.xml"/>
<!--<mapper class="com.clb.dao.EmpMapper"/>-->
<!--<package name="com.clb.dao"/>-->
</mappers>

</configuration>

数据源配置文件示例

# mysql
mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/clb
mysql.username=root
mysql.password=123456
# sql server
ms.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
#ms.url=jdbc:sqlserver://localhost:1433;trustServerCertificate=true
ms.url=jdbc:sqlserver://192.168.0.88:1433;trustServerCertificate=true
ms.username=sa
ms.password=123456

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">

<!--把原来的UserDaoImpl类转换成一个xml配置文件-->

<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.clb.dao.UserMapper">
<!--结果集映射 type -> 需要将数据库数据映射成user类型 数据库字段名和属性名一致则会自动映射,无需额外配置-->
<resultMap id="UserMap" type="user">
<!--colum 数据库中的列 -> property 实体类中的属性-->
<!--<result column="id" property="id"/>-->
<!--<result column="name" property="name"/>-->
<result column="pwd" property="password"/>
</resultMap>

<!--
查询语句
id: 对应namespace中的接口的方法名
resultType: sql语句执行的返回类型
-->
<select id="getUserList" resultType="com.clb.pojo.User">
select * from mybatis.user
</select>


<!--根据id查询用户,这里#{id}中的id就是方法中的id变量-->
<select id="selectById" resultType="com.clb.pojo.User" parameterType="int">
select * from user where id = #{id}
</select>

<!--模糊查询,concat用于拼接字符串-->
<select id="getUserLike" resultType="com.clb.pojo.User">
select * from user where name like concat('', #{name}, '');
</select>

<!--添加一个用户,对象中的属性可以直接取出来,不需要加类名user.-->
<insert id="addUser" parameterType="com.clb.pojo.User">
insert into user(id, name, pwd) value (#{id}, #{name}, #{pwd})
</insert>
</mapper>

MybatisUtils

要使用mybatis执行sql语句,要使用SqlSession对象,可以直接在测试类中获取

@Test
public void test() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
try (SqlSession session = sqlSessionFactory.openSession()) {
//获取Mapper对象,执行xml映射文件中的方法
EmpMapper mapper = session.getMapper(EmpMapper.class);
List<Emp> emps = mapper.selectBySalary(5000);
emps.forEach(System.out::println);
}
}

但是每次使用都要写这一串代码,有点麻烦,前面获取SqlSession对象的代码是固定代码,将这段固定代码提取到工具类MybatisUtils,使用工具类的静态方法获取SqlSession对象

MybatisUtils工具类示例

//sqlSessionFactory --> sqlSession
public class MybatisUtils {
private MybatisUtils() {}
//定义一个SqlSessionFactory对象并使用静态初始化块初始化对象
private static final SqlSessionFactory sqlSessionFactory;
static {
try {
//使用mybatis第一步,获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

//既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
@Test
public void testMybatisUtils() {
//使用工具类直接获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();

EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> emps = mapper.selectBySalary(1000);
emps.forEach(System.out::println);

sqlSession.close();
}

注解开发

使用注解直接写sql语句代替xml映射文件

public interface UserMapper {
@Select("select id, name, pwd password from user")
List<User> selectAll();
/*
* @Param()注解:
* 1.基本类型或者String类型需要加上
* 2.引用类型可以不加
* 3.如果只有一个基本类型的话,可以不加,但是建议加上
* 4.在注解中的sql语句中{}中的参数就是@Param注解中的属性名
* */
@Select("select id, name, pwd password " +
"from user " +
"where id = #{id} and name=#{name} and pwd=#{password}")
User selectById(@Param("id") int i, @Param("name")String n, @Param("password") String p);

//#{id},#{name},#{password}中的三个属性均来自参数中对象的属性
@Insert("insert into user(id, name, pwd) VALUE (#{id},#{name},#{password})")
int addUser(User user);

@Update("update user set name=#{name},pwd=#{password} where id=#{id}")
int updateUser(User user);

@Delete("delete from user where id = #{id}")
int deleteUserById(@Param("id") int id);
}

使用@Result注解可以定义结果映射,使用@ResultMap可以引用xml文件中定义的ResultMap结果映射

@Select("select * from emp where first_name = #{name};")
@Results({
@Result(column = "first_name", property = "firstName")
})
Emp getByFirstNameEmp(String name);
//更推荐使用
@Select("select * from emp where first_name = #{name};")
@ResultMap("EmpMap")
Emp getByFirstNameEmp(String name);

总结:简单的sql语句使用注解比配置文件来的更方便且更快,但是复杂的sql语句使用注解反而不方便或难以实现,所以==简单的sql使用注解,复杂的使用xml,搭配使用==


动态 SQL

==动态查询==

<!--where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。
而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。-->

<!--动态sql if标签 如果参数不为空就加上条件,否则不加-->
<select id="pageQuery" resultType="com.sky.entity.Category">
select * from category
<where>
<if test="name != null and name != ''">
and name like concat('%',#{name},'%')
</if>
<if test="type != null">
and type = #{type}
</if>
</where>
order by sort asc , create_time desc
</select>

==动态更新==

<update id="update" parameterType="Category">
update category
<set>
<if test="type != null">
type = #{type},
</if>
<if test="name != null">
name = #{name},
</if>
<if test="sort != null">
sort = #{sort},
</if>
<if test="status != null">
status = #{status},
</if>
<if test="updateTime != null">
update_time = #{updateTime},
</if>
<if test="updateUser != null">
update_user = #{updateUser}
</if>
</set>
where id = #{id}
</update>

==批量插入,传入参数是一个集合类型,删除同理==

<insert id="insertBatch">
insert into dish_flavor (dish_id, name, value)values
<foreach collection="flavors" item="f" separator=",">
(#{f.dishId},#{f.name},#{f.value})
</foreach>
</insert>

更多动态SQL用法见官网

接下来,了解进阶框架==mybatis-plus==