中文文档
https://mybatis.org/mybatis-3/zh/index.html
ORM是什么
ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数 据与简单Java对象(POJO)的映射关系的技术。简单的说,ORM是通过使用描述对象和 数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。
Mybatis优缺点
优点
与传统的数据库访问技术相比,ORM有以下优点:
基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态 SQL语句,并可重用。
与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接
很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数 据库MyBatis都支持)。
不同点
能够与Spring很好的集成
缺点
SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底 有一定要求。
SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
MyBatis中#{}和${}的区别
#{}是预编译处理,${}是字符替换。在使用#{}时,MyBatis会将SQL中的#{}替换成?配合PreparedStatement的set方法赋值,这样可以有效的防止SQL注入,保证程序的运行安全。
Mybatis的foreach支持的数据类型
foreach一共有三种类型,分别为List,[](array),Map三种
参数传递方式
匿名传递
List<Employee> selectByGenderAndAge(Short gender,String age );
匿名参数只能使用arg1,arg0,param1,param2类似的形式这种传参方式的缺点是不够灵活,必须严格按照参数顺序来引用
<select id="selectByGenderAndAge" resultMap="BaseResultMap" >
select * from employee where gender = #{param1} and age = #{param2}
</select>
@Param注解
List<Employee> selectByGenderAndAge( @Param("gender") Short gender,@Param("age") String age );
<select id="selectByGenderAndAge" resultMap="BaseResultMap" > select * from employee where gender = #{gender} and age = #{age} </select>
Map传递参数
List<Employee> selectByMapParams(Map params);
<select id="selectByMapParams" resultMap="BaseResultMap" parameterType="map">
select * from employee where gender = #{gender} and age = #{age}
</select>
java bean传递多个参数
List <Employee> selectByBeans(Employee employee);
<select id="selectByBeans" resultMap="BaseResultMap" parameterType="com.wg.demo.po.Employee">
select
*
from employee where gender = #{gender} and age = #{age}
</select>
使用JSON传递参数
List <Employee> findByJSONObject(JSONObject params);
<select id="findByJSONObject" resultMap="BaseResultMap" parameterType="com.alibaba.fastjson.JSONObject">
select
*
from employee where gender = #{gender} and age = #{age}
</select>
传递集合类型参数List、Set、Array
List <Employee> findByList(List list);
<select id="findByList" resultMap="BaseResultMap" >
SELECT * from employee where age in
<foreach collection="list" open="(" separator="," close=")" item="age">
#{age}
</foreach>
</select>
参数类型为对象+集合
@Data
public class Department {
private Long id;private String deptName;
private String descr;
private Date createTime;
List<Employee> employees;
}
List <Employee> findByDepartment(@Param("department")Department department);
<select id="findByDepartment" resultMap="BaseResultMap" parameterType="com.wg.demo.po.Department">
SELECT * from employee where dept_id =#{department.id} and age in
<foreach collection="department.employees" open="(" separator="," close=")" item="employee">
#{employee.age}
</foreach>
</select>
核心对象的生命周期
SqlSessionFactoryBuilder:方法作用域
SqlSessionFactory:应用作用域
SqlSession:请求或方法作用域
Mapper:方法
什么是Mybatis
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO为数据库中的记录。
动态标签以及执行原理
其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。
if、choose(when/otherwise)、trim(where/set)、foreach
mappers指定路径方式,优先级是什么
resource/url/class/package,package是在第一个
mybatis的执行器
SimpleExecutor:每次都会重新创建Statement对象
ReuseExecutor:重复使用Statement对象
BatchExecutor:批量处理
Mybatis分页
分页方式:逻辑分页和物理分页
逻辑分页:使用MyBatis自带的RowBounds进行分页,它是一次性查询很多数据,然后在数据中再进行检索
物理分页:自己手写SQL分页或使用分页插件PageHelper,去数据库查询指定条数的分页数据的形式
MyBatis是否支持延迟加载和延迟加载的原理
1.MyBatis支持延迟加载,设置lazyLoadingEnabled=true即可
2.延迟加载的原理的是调用的时候触发加载,而不是在初始化的时候就加载信息
注:Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。
它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。
简述Mybatis的插件运行原理,以及如何编写一个插件
1)Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,Mybatis 通过动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
2)实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。
一级缓存和二级缓存
https://blog.csdn.net/xiaowanzi_zj/article/details/127490689
1.一级缓存也叫本地缓存,一级缓存是在会话(SqlSession)层面进行缓存的。MyBatis的一级缓存是默认开启的,不需要任何的配置。如果要在同一个会话里面共享一级缓存,这个对象肯定是在SqlSession里面创建的,作为SqlSession的一个属性。DefaultSqlSession里面只有两个属性,Configuration是全局的,所以缓存只可能放在Executor里面维护——SimpleExecutor/ReuseExecutor/BatchExecutor的父类BaseExecutor的构造函数中持有了PerpetualCache。2.二级缓存是用来解决一级缓存不能跨会话共享的问题的,范围是namespace级别的,可以被多个SqlSession共享生命周期和应用同步,二级缓存是CachingExecutor持有的PerpetualCache。
mybatis用到那些设计模式
https://blog.csdn.net/xiaowanzi_zj/article/details/119523658
代理模式、责任链模式、工厂模式、建造者模式、单例模式、适配器模式、模板模式、装饰器模式
association和collection的区别
association用于一对一和多对一的关系,collection用于一对多的关系
实体类中的属性名和表中的字段名不一样,怎么办
第1种:在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致
<select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”>
select order_id id, order_no orderno ,order_price price form orders where
order_id=#{id};
</select>
第2种:通过<resultMap>来映射字段名和实体类属性名的一一对应的关系
<select id="getOrder" parameterType="int" resultMap="orderresultmap">
select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!–用id属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用result属性来映射非主键字段,property为实体类属性名,column为数据表中的属性–>
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>
模糊查询like语句该怎么写
List<User> selectUser(@Param("name") String name);
<select id="selectUser" parameterType="string" resultType="com.entity.User">
SELECT
*
FROM
t_user
WHERE
name LIKE CONCAT('%',#{name},'%')
</select>
如何获取自动生成的(主)键值
insert 方法总是返回一个int值 - 这个值代表的是插入的行数。
而自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。
示例:
<insert id=”insertname” usegeneratedkeys=”true” keyproperty=”id”>
insert into names (name) values (#{name})
</insert>
name name = new name();
name.setname(“fred”);
int rows = mapper.insertname(name);
// 完成后,id已经被设置到对象中
system.out.println(“rows inserted = ” + rows);
system.out.println(“generated key value = ” + name.getid());
JDBC
https://blog.csdn.net/xiaowanzi_zj/article/details/117049085