前言
Mybatis是一个以JDBC为基础封装的持久层框架文档主要目的: 熟悉常用的Mybatis使用方法
扩展阅读还是推荐在线文档: MyBatis3
导包
<!--替换JDBC技术的Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
编写配置文件
- 命名( 官方写法 ):
mybatis-config.xml
<settings>
详情见文档配置: mybatis-config.xml| 配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--属性可以在外部进行配置,使该文件中可以读取到外部properties中的数据,并在整个配置文件中用来替换需要动态配置的属性值-->
<properties resource="druid.properties"></properties>
<settings>
<!--指定 MyBatis 所用日志的具体实现-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启数据库名称和类名驼峰映射-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--类型别名配合注解开发:在实体类前加上@Alias("别名") 。name包名指向自己的实体类所在的包路径-->
<typeAliases>
<package name="top.itifrd.pojo"/>
</typeAliases>
<!--MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。还有许多类似的使用场景。-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--使用了Druid连接池整合Mybatis,在高级篇中讲,这里可以使用默认的方式:见: https://mybatis.org/mybatis-3/zh/getting-started.html ,XML的配置-->
<dataSource type="top.itifrd.config.DruidDataSourceFactory">
<!--url,username,password将会由druid.properties中设置的相应值来替换-->
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--将包内的映射器接口实现全部注册为映射器-->
<mappers>
<package name="top.itifrd.mapper"/>
</mappers>
</configuration>
Tips : 这里给出 db.propertis 文件内容, mybatis-config.xml中读取了该文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/chengyunlaidb?useSSL=false&Unicode=true&characterEncoding=utf8
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
制作工具类得到Session
graph TD
XML --> InputStream --> SqlSessionFactoryBuilder.build --> sqlSessionFactory.openSession --> Session
从XML配置文件中构造SqlSessionFactory,SqlSessionFactory可以得到Session,通过Session就可以操作sql语句
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。
而SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
Tips : 制作要求
- 1. SqlSessionFactoryBuilder : 这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。
- 2. SqlSessionFactory : 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。所以只需要该类的一个对象即可。
- 3. SqlSession : 每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
package top.itifrd.utils;
import jdk.nashorn.internal.objects.annotations.Getter;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
* @ClassName
* @Description 静态代码块只执行一次的特性,满足1条和2条
* @Author:chengyunlai
* @Date
* @Version 1.0
**/
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory = null;
static {
try {
InputStream instream = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(instream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 该类无法被手动new实例化
private MybatisUtils(){};
/**
* @Description: 该封装思想有一个问题,无法关闭sqlSession
* @Param: [clazz]
* @return: E
* @Author: chengyunlai
* @Date: 2022/5/18
*/
// public static <E> E getSqlSession(Class<E> clazz){
// SqlSession sqlSession = sqlSessionFactory.openSession();
// E mapper = sqlSession.getMapper(clazz);
// return mapper;
// }
/**
* @Description: 调用时暴露一个sqssion即可,用户手动关闭
* @Param: []
* @return: org.apache.ibatis.session.SqlSession
* @Author: chengyunlai
* @Date: 2022/5/18
*/
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
CURD -- 对应实体的Mapper接口和xml配置
安装插件
- 功能1:快速定位Mapper接口和对应XML配置文件
- 功能2:接口方法快速生成对应的xml Sql语句
接口
public interface UserMapper {
List<User> selectAll();
// 注解加xml混合开发方式,简单的语句使用注解,复杂的语句使用xml
@Select("select * from user where id = #{id}")
User getOneById(@Param("id") Integer id);
@Select("select count(*) from user where username = #{username}")
// @Param注解相当于给变量起个标签,在xml中#{},要和@Param("")中的内容一致
Integer selectUserByUsername(@Param("username") String username);
// xml用到接收的内容都要user打头
int updateUser(@Param("user")User user);
int addUser(@Param("user")User user);
int deleteUserById(@Param("id") Integer id);
}
映射文件
创建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="top.itifrd.mapper">
</mapper>
根据上面的模板创建
注意事项:
- 接口和配置文件包路径相同(方便在mybatis-config中做映射)
命名规则: 如图所示
使用插件创建模板和语句(推荐)
这个推荐当然是基于 你可以使用插件开发的情况
先给出一个单表CURD的内容,然后我们逐句的讲解
<?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="top.itifrd.mapper.UserMapper">
<insert id="addUser">
insert into user (username, password, description, age) VALUES (#{user.username},#{user.password},#{user.description},#{user.age})
</insert>
<update id="updateUser">
update user
<set>
<if test="user.username != null and user.username != ''">
username = #{user.username},
</if>
<if test="user.password != null and user.password != ''">
password = #{user.password},
</if>
<if test="user.description != null and user.description != ''">
description = #{user.description},
</if>
<if test="user.age != null and user.age != ''">
age = #{user.age}
</if>
</set>
<where>
<if test="user.id != null">
id = #{user.id};
</if>
</where>
</update>
<delete id="deleteUserById">
delete from user where id = #{id};
</delete>
<!-- 它在命名空间 “top.itifrd.mapper.UserMapper” 中定义了一个名为 “selectAll” 的映射语句-->
<!--相当于注入sql语句-->
<select id="selectAll" resultType="user">
select * from user;
</select>
</mapper>
命名空间 <mapper namespace="">
<mapper namespace="top.itifrd.mapper.UserMapper">
可以为每个映射文件起一个唯一的命名空间,保证它的唯一性。我们现在常使用全类路径,并且有对应的Mapper接口,所以指向配置文件对应的Mapper接口即可。
插入标签 <insert id=""></insert>
<insert id="addUser"> insert into user (username, password, description, age) VALUES (#{user.username},#{user.password},#{user.description},#{user.age}) </insert>
使用标签<insert></insert>
表示这是一个插入语句,id对应着接口中方法名,下面id作用雷同,标签内是正常的sql语句,#{}
用于接收参数,#{}
内容名称可以在接口中定义@params("")
指定名称。
Tips :
#{}
底层使用preparestatement可以防止sql注入${}
底层使用sql拼接,会有sql注入的风险
查询标签 <select id="" resultType=""></select>
<select id="selectAll" resultType="user">
select * from user;
</select>
Tips :
- resultType 中对应着对应封装的实体类,可以使用别名
- 还有resultMap 见高级篇更新
修改标签<update id=""></update>
<update id="updateUser">
update user
<set>
<if test="user.username != null and user.username != ''">
username = #{user.username},
</if>
<if test="user.password != null and user.password != ''">
password = #{user.password},
</if>
<if test="user.description != null and user.description != ''">
description = #{user.description},
</if>
<if test="user.age != null and user.age != ''">
age = #{user.age}
</if>
</set>
<where>
<if test="user.id != null">
id = #{user.id};
</if>
</where>
</update>
Tips :
- 这里的
<set>;<if>
使用了动态sql,就是一个逻辑的判断,当参数不为空的时候使用if包裹的语句,详细见高级篇
删除标签 <delete id=""></delete>
<delete id="deleteUserById">
delete from user where id = #{id};
</delete>
将映射文件在配置文件中注册
观察配置文件中的内容,这里使用:包映射的方式
<mappers>
<package name="top.itifrd.mapper"/>
</mappers>
Tips :这里有个小坑,一定要注意 resources 中的 映射文件xml 和 java 中的 Mapper接口 在同一个包下,这个同个包下是指编译后的全类路径: classes 中接口和对应的xml在同个文件夹下
- [x] 基础篇结束
- [ ] 下一阶段 : Mybatis高级篇