Java 持久层框架之 MyBatis
MyBatis 简介
MyBatis是一个基于
Java的持久层框架,它内部封装了
JDBC,使开发者只需关注
SQL语句本身,而不用再花费精力去处理诸如注册驱动、创建
Connection、配置
Statement等繁杂过程。
Mybatis通过
xml或注解的方式将要执行的各种
Statement、
PreparedStatement等配置起来,并通过
Java对象和
Statement中
SQL的动态参数进行映射生成最终执行的
SQL语句,最后由
MyBatis框架执行
SQL并将结果映射成
Java对象并返回。
MyBatis 与 Hibernate
Hibernate 框架是提供了全面的数据库封装机制的 全自动 ORM,即实现了 POJO 和数据库表之间的映射,以及 SQL 的自动生成和执行。
相对于此,MyBatis 只能算作是 半自动 ORM。其着力点,是在 POJO 类与 SQL 语句之间的映射关系。也就是说,MyBatis 并不会为程序员自动生成 SQL 语句。具体的 SQL 需要程序员自己编写,然后通过 SQL 语句映射文件,将 SQL 所需的参数,以及返回的结果字段映射到指定 POJO。
MyBatis 特点
- 在
XML
文件中配置SQL
语句,实现了SQL
语句与代码的分离,给程序的维护带来了很大便利。 - 可以结合数据库自身的特点灵活控制
SQL
语句,因此能够实现比Hibernate
等全自动ORM
框架更高的查询效率,能够完成复杂查询。
Spring 整合 Mybatis
引入依赖
在
pom.xml引入 Mybatis 相关依赖。
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.17.RELEASE</version> </dependency>
创建 Mybatis 配置文件
在
resource目录下创建
mybatis-config配置文件。
<?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> <!-- 全局参数 --> <settings> <!-- 打印 SQL 语句 --> <setting name="logImpl" value="STDOUT_LOGGING" /> <!-- 使全局的映射器启用或禁用缓存。 --> <setting name="cacheEnabled" value="false"/> <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 --> <setting name="aggressiveLazyLoading" value="true"/> <!-- 是否允许单条 SQL 返回多个数据集 (取决于驱动的兼容性) default:true --> <setting name="multipleResultSetsEnabled" value="true"/> <!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true --> <setting name="useColumnLabel" value="true"/> <!-- 允许 JDBC 生成主键。需要驱动器支持。如果设为了 true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以 ad8 执行。 default:false --> <setting name="useGeneratedKeys" value="false"/> <!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不映射 PARTIAL:部分 FULL:全部 --> <setting name="autoMappingBehavior" value="PARTIAL"/> <!-- 这是默认的执行类型 (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新) --> <setting name="defaultExecutorType" value="SIMPLE"/> <!-- 使用驼峰命名法转换字段。 --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session --> <setting name="localCacheScope" value="SESSION"/> <!-- 设置 JDBC 类型为空时,某些驱动程序 要指定值, default:OTHER,插入空值时不需要指定类型 --> <setting name="jdbcTypeForNull" value="NULL"/> </settings> </configuration>
创建集成配置文件
在
resource目录下创建一个
spring-context-mybatis.xml的集成配置文件。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置 SqlSession --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 用于配置对应实体类所在的包,多个 package 之间可以用 ',' 号分割 --> <property name="typeAliasesPackage" value="com.antoniopeng.ssm.domain"/> <!-- 用于配置对象关系映射--> <property name="mapperLocations" value="classpath:/mapper/**/*.xml"/> <!-- -用于配置文件所在目录-> <property name="configLocation" value="classpath:/mybatis-config.xml"></property> </bean> <!-- 扫描 Mapper --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.antoniopeng.ssm.dao" /> </bean> </beans>
CRUD 案例
新增
<insert id="insert"> INSERT INTO tb_user ( id, username, password, phone, email, created, updated ) VALUES ( #{id}, #{username}, #{password}, #{phone}, #{email}, #{created}, #{update} ) </insert>
删除
<delete id="delete"> DELETE FROM tb_user WHERE id = #{id} </delete>
查询
<select id="getById" resultType="TbUser"> SELECT a.id, a.username, a.password, a.phone, a.email, a.created, a.updated AS "update" FROM tb_user AS a WHERE a.id = #{id} </select>
更新
<update id="update"> UPDATE tb_user SET username = #{username}, password = #{password}, phone = #{phone}, email = #{email}, created = #{created}, updated = #{update} WHERE id = #{id} </update>
MyBatis 动态 SQL
动态 SQL 主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行排列组合,将会出现大量的 SQL 语句。此时,可使用动态 SQL 来解决这样的问题。这里的条件判断使用的表达式为
OGNL表达式。常用的动态 SQL 标签有
<if>、
<where>、
<choose>、
<foreach>等。
注意:在 mapper 的动态 SQL 中若出现
>、
<、
>=,
<=等符号,最好将其转换为实体符号。否则,XML 可能会出现解析出错问题,特别是
<在 XML 中是绝对不能出现的。
if 标签
对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。
案例
为了解决两个条件均未做设定的情况,在 where 后添加了一个“1=1”的条件。这样就不至于两个条件均未设定而出现只剩下一个 where,而没有任何可拼接的条件的不完整 SQL 语句。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper ad0 .dtd"> <mapper namespace="com.antoniopeng.ssm.dao.StudentDao"> <!-- if --> <select id="selectByIf" resultType="com.antoniopeng.ssm.entity.Student"> SELECT * FROM student WHERE 1 = 1 <if test="name != null and name != ''"> AND name LIKE concat('%', #{name}, '%') </if> <if test="age != null and age > 0"> AND age > #{age} </if> </select> </mapper>
where 标签
标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1 的子句。因为,若 where 后的所有 条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL 出错。所以,在 where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。
案例
<select id="selectByWhere" resultType="com.antoniopeng.ssm.entity.Student"> SELECT * FROM student <where> <if test="name != null and name != ''"> AND name LIKE concat('%', #{name}, '%') </if> <if test="age != null and age > 0"> AND age > #{age} </if> </where> </select>
choose 标签
该标签中只可以包含
<when/>、
<otherwise/>,可以包含多个
<when/>与一个
<otherwise/>。它们联合使用,完成 Java 中的开关语句 switch case 功能。
案例
本例要完成的需求是,若姓名不空,则按照姓名查询;若姓名为空,则按照年龄查询;若没有查询条件,则没有查询结果。
<!-- choose --> <select id="selectByChoose" resultType="com.antoniopeng.ssm.entity.Student"> SELECT * FROM student <where> <choose> <when test="name != null and name != ''"> AND name LIKE concat('%', #{name}, '%') </when> <when test="age != null and age > 0"> AND age > #{age} </when> <otherwise> AND 1 != 1 </otherwise> </choose> </where> </select>
foreach 标签
该标签用于实现对于数组与集合的遍历。对其使用,需要注意:
co 1c5c llection表示要遍历的集合类型,这里是数组,即 array。
open、
close、
separator为对遍历内容的 SQL 拼接。
遍历数组案例
<!-- foreach --> <select id="selectByForeach" resultType="com.antoniopeng.ssm.entity.Student"> SELECT * FROM student <if test="array != null and array.length > 0"> WHERE id IN <foreach collection="array" open="(" close=")" item="id" separator=","> #{id} </foreach> </if> </select>
遍历泛型为基本类型的集合案例
/** * 使用 foreach 标签以 list 基本类型的形式查询 * @param ids * @return */ public List<Student> selectByForeachWithListBase(List<Long> ids);
<!-- foreach --> <select id="selectByForeachWithListBase" resultType="com.antoniopeng.ssm.entity.Student"> SELECT * FROM student <if test="list != null and list.size > 0"> WHERE id IN <foreach collection="list" open="(" close=")" item="id" separator=","> #{id} </foreach> </if> </select>
遍历泛型为自定义类型的集合案例
/** * 使用 foreach 标签以 list 自定义类型的形式查询 * @param students * @return */ public List<Student> selectByForeachWithListCustom(List<Student> students);
<!-- foreach --> <select id="selectByForeachWithListCustom" resultType="com.antoniopeng.ssm.entity.Student"> SELECT * FROM student <if test="list != null and list.size > 0"> WHERE id IN <foreach collection="list" open="(" close=")" item="student" separator=","> #{student.id} </foreach> </if> </select>
sql 标签
该标签用于定义 SQL 片断,以便其它 SQL 标签复用。而其它标签使用该 SQL 片断, 需要使用
<include/>子标签。该标签可以定义 SQL 语句中的任何部分,所以
<include/>子标签可以放在动态 SQL 的任何位置。
案例
<sql id="select"> SELECT id, name, age, score FROM student </sql>
使用 sql 标签
<!-- foreach --> <select id="selectByForeachWithListCustom" resultType="com.antoniopeng.ssm.entity.Student"> <include refid="select" /> </select>
- 文章作者:彭超
- 本文首发于个人博客:https://antoniopeng.com
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 彭超的博客!
- java持久层框架mybatis如何防止sql注入
- Mybatis 基于Java的持久层框架(一)
- java持久层框架mybatis如何防止sql注入
- java持久层框架mybatis防止sql注入的方法
- java持久层框架mybatis如何防止sql注入
- java持久层框架mybatis如何防止sql注入
- JAVA持久层框架的概述(ibatis>>mybatis)
- java持久层框架mybatis如何防止sql注入
- Mybatis 基于Java的持久层框架(二)
- java持久层框架mybatis如何防止sql注入
- java持久层框架mybatis如何防止sql注入
- MyBatis-Plus--快速入门Mysql Java持久层框架 Mybatis SpringBoot SpringMVC 配置文件
- java持久层框架mybatis如何防止sql注入
- java持久层框架mybatis如何防止sql注入
- java持久层框架mybatis如何防止sql注入
- java持久层框架-mybatis的工作原理
- Java持久层框架MyBatis简单实例
- Java 持久层框架之 MyBatis
- Java持久层框架mybatis初步搭建
- 【速学java】 java后台框架 springmvc整合mybatis框架源码