视频教程:https://www.bilibili.com/video/BV1Qf4y1T7Hx?p=47
什么是MyBatis
Mybatis是一款优秀的持久层框架,用于简化JDBC开发。
快速使用
MyBatis中文文档
- resources下创建mybatis配置文件mybatis-config.xml
- 编写Mapper代理接口,resources下创建同名Mapper.xml文件编写sql语句,路径要和代理接口相同,这样编译后才能在同一个文件夹。
- 代码中使用
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--类型别名 可以扫描指定报名下的Bean,这样resultType就可以不用写全路径Bean了--><typeAliases><package name="com.example.pojo"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--加载数据库连接信息--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///db1?useSSL=false"/><property name="username" value="root"/><property name="password" value="1234"/></dataSource></environment></environments><mappers><!--Mapper代理方式,包扫描--><package name="com.example.mapper"/></mappers>
</configuration>
UserMapper.java
public interface UserMapper {List<User> selectAgeLess();}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper"><select id="selectAgeLess" resultType="User">select * from stu where age < 30;</select></mapper>
代码中使用:
String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> users = mapper.selectAgeLess();System.out.println(users);//释放资源sqlSession.close();
常用
resultMap
实体类的变量名和数据表中的属性名不一致时,就需要resultMap来映射。
id:完成主键字段的映射
result:完成一般字段的映射
- column:表的列名
- property:实体类的属性名
<resultMap id="brandResultMap" type="brand"><result column="brand_name" property="brandName"/><result column="company_name" property="companyName"/></resultMap><select id="selectById" resultMap="brandResultMap">select * from tb_brand where id = #{id};</select>
Mybatis–resultMap类型详解
参数占位符
${}
:拼接SQL,会存在SQL注入问题。
#{}
:会将 #{} 占位符替换为?,将来自动设置参数值,可以防止SQL注入。
使用场景:
- 参数传递时使用
#{}
- 表名或列名不固定的情况时使用
${}
SQL语句中的特殊字符处理:
- 转义字符:
<
小于号<
,>
大于号>
<![CDATA[
内容]]>
sql语句设置多个参数
- 散装参数:需要使用
@Param(参数名称)
- 实体类封装参数:要保证参数名和实体类属性名对应上
- map集合:参数名和map的键值要对应上
示例1:
List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
<select id="selectByCondition" resultMap="brandResultMap">select *from tb_brandwhere status = #{status}and company_name like #{companyName}and brand_name like #{brandName}</select>
动态sql
当查询条件可能为null时就需要动态sql来判断
<select id="selectByCondition" resultMap="brandResultMap">select *from tb_brand<where><if test="status != null">and status = #{status}</if><if test="companyName != null and companyName != '' ">and company_name like #{companyName}</if><if test="brandName != null and brandName != '' ">and brand_name like #{brandName}</if></where></select>
where
标签可以处理条件中的语法错误,比如自动去除第一个条件的前的and
添加-主键返回
执行添加操作成功后,有时需要获取主键值,这时就需要设置主键返回,添加的实体类中就可以获取到主键值了。
在 insert 标签上添加如下属性:
- useGeneratedKeys:是够获取自动增长的主键值。true表示获取
- keyProperty :指定将获取到的主键值封装到哪个属性里
<insert id="add" useGeneratedKeys="true" keyProperty="id">insert into tb_brand (brand_name, company_name, ordered, description, status)values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
</insert>
批量删除
void deleteByIds(@Param("ids") int[] ids);
<delete id="deleteByIds">delete from tb_brand where idin<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>;
</delete>
foreach 标签
用来迭代任何可迭代的对象(如数组,集合)。
collection 属性:
- mybatis会将数组参数,封装为一个Map集合。
- 默认:array = 数组
- 使用@Param注解改变map集合的默认key的名称
- item 属性:本次迭代获取到的元素。
- separator 属性:集合项迭代之间的分隔符。foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。
- open 属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一次
- close 属性:该属性值是在拼接SQL语句拼接后拼接的语句,只会拼接一次
注解sql
@Select("select * from tb_brand where status = #{status} and ordered > #{ordered}")List<Brand> selectByStatus(@Param("status") int status, @Param("ordered") int ordered);
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。