工作流程图
特性及优点
1.mybatis是一种持久层框架,也属于ORM映射。前身是ibatis。
相比于hibernatehibernate为全自动化,配置文件书写之后不需要书写sql语句,但是欠缺灵活,很多时候需要优化;
2.mybatis为半自动化,需要自己书写sql语句,需要自己定义映射。增加了程序员的一些操作,但是带来了设计上的灵活,并且也是支持hibernate的一些特性,如延迟加载,缓存和映射等;对数据库的兼容性比hibernate差。移植性不好,但是可编写灵活和高性能的sql语句。
3.简单易学、解除sql与程序代码的耦合
Mybatis.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>
<!-- 为 实体映射 文件 创建别名映射 -->
<typeAliases>
<package name="com.qpy"/><!--这个 包下面的 所有 实体类 别名 自动 创建 -->
</typeAliases>
<environments default="development"><!-- 环境池 配置 :default 属性值 默认环境名称 -->
<environment id="development"> <!--标签是有先后顺序的:鼠标停留在configuration标签会有显示 下面顺序的信息 properties, settings, typeAliases, typeHandlers, objectFactory, objectWrapperFactory, reflectorFactory, plugins, environments, databaseIdProvider, mappers -->
<properties Resource="db.properties" />
<transactionManager type="JDBC" /><!-- JDBC事务 MANAGED没有事务 基本不用 -->
<!-- 配置数据库连接信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///test?serverTimezone=GMT" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/qpy/test/Usersmapper.xml"/> <!-- 映射domain的文件 -->
</mappers>
</configuration>
三大核心对象
SqlSessionFactoryBuilder:建造者模式 只需要创建一次
SqlSessionFactory:一旦被创建,则整个项目周期都会存在。
SqlSession:线程不安全,及时关闭 该对象 进行事务提交 回滚
简单的Uitle工具:
public class MyBatisUtil {
private MyBatisUtil() {
}
private static SqlSessionFactory sessionFactory;
static {
try {
InputStream is = Resources.getResourceAsStream("MyBatis.xml");
sessionFactory = new SqlSessionFactoryBuilder().build(is);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSession getSession() {
return sessionFactory.openSession();
}
}
映射文件.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.qpy.test.Usersmapper"><!-- 映射接口类的 路径!!! -->
<select id="getUsers4" resultType="java.util.Map">
select * from users
</select>
<select id="getUsers4" resultMap="Users">
select * from users
</select>
</mapper>
注意
1 . <insert id="" useGeneratedKeys="true" keyColumn="id"></insert>
useGeneratedKeys keyColumn可以在插入操作时返回主键id值
2.dao调用sql是由 namespace + id 组合来确定唯一的
3.resultMap=“Users” 是使用的别名 MyBatis.xml中 typeAliases标签来自动生成的 不区分大小写
4.数据库字段 与 domain属性不配问题:使用resultMap来解决
<resultMap type="users" id="userMap">
<id column="id" property="id"/>
<result column="name" property="username"/>
</resultMap>
5.#和$的区别和使用场景
${}哪边都能使用,只是存在sql注入风险,相当于直接拼接字符串,不对参数做任何处理。
#{}会进行预编译,对参数进行处理,防止注入 性能更好,会重复使用
多对一查询
private Dept dept;例如查询员工对应的部门名称
三种方法实现
方式一:
<!-- 实体类 中 与表名字 不同 使用 resultMap 来创建 别名映射!-->
<resultMap type="users" id="userMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="address" property="address"/>
<association property="dept" javaType="dept">
<id column="did" property="id"/>
<result column="dept_name" property="dept_name"/>
</association>
</resultMap>
<!-- 查询 所有 数据 测试! -->
<select id="getUsers" resultMap="userMap">
select u.id id, u.name name, u.address address, d.id did, d.dept_name dept_name from users u join dept d on u.dept_id = d.id
</select>
方式二:
<resultMap type="users" id="userMap2">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="address" property="address"/>
<association property="dept" column="dept_id" select="deptById"/>
</resultMap>
<select id="deptById" parameterType="Long" resultType="dept">
select * from dept where id = #{id}
</select>
<select id="getUsers1" resultMap="userMap2">
select * from users
</select>
方式三
<resultMap type="users" id="userMap3">
<result column="did" property="dept.id"/>
<result column="dept_name" property="dept.dept_name"/>
</resultMap>
<select id="getUsers3" resultMap="userMap3">
select u.id id, u.name name, u.address address, d.id did, d.dept_name dept_name from users u join dept d on u.dept_id = d.id
</select>
一对多查询
private List users = new ArrayList();例如查询部门对应的员工
方式一
<resultMap type="dept1" id="deptMap">
<result column="id" property="id"/>
<result column="dept_name" property="dept_name"/>
<collection property="users" javaType="users1">
<id column="uid" property="id"/>
<result column="name" property="name"/>
<result column="address" property="address"/>
</collection>
</resultMap>
<select id="getDept" resultMap="deptMap">
select d.id, d.dept_name, u.id uid, u.name, u.address from dept d join users u on d.id = u.dept_id
</select>
方式二
<resultMap type="dept1" id="deptMap1">
<result column="id" property="id"/>
<result column="dept_name" property="dept_name"/>
<collection property="users" column="id" ofType="users1" select="findUserById"/>
</resultMap>
<select id="findUserById" parameterType="Long" resultType="Users1">
select * from users where dept_id = #{id}
</select>
<select id="getDept1" resultMap="deptMap1">
select * from dept
</select>
Mapper的使用
缓存
一级缓存 默认存在一级缓存
二级缓存 在映射文件中开启 domain对象实现序列化
https://ke.qq.com/course/313182?taid=2225647758133086