MyBatis
MyBatis是一款优秀的持久层框架,用于简化jdbc开发
持久层
负责将数据保存到数据库的那一层代码
JavaEE三层架构:表现层、业务层、持久层
框架
框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
在框架基础之上构建软件编写更加高效、规范、通用、可扩展
创建实体类快捷键:Alt + 鼠标左键(按住不放,鼠标往下滑) 可以实现整列编辑
mybatis官网:
https://mybatis.org/mybatis-3/zh/index.html
MyBatis的基本使用
MyBatis类中编写:
//1、加载mybatis的核心配置文件,获取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2、使用 SqlSessionFactory 获取 SqlSession 对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//3、执行sql
List<User> user = sqlSession.selectList("test.selectAll");
System.out.println(user);
//4、释放资源
sqlSession.close();
Mapper代理开发
优势;
首先它不依赖于字符串字面值,会更安全一点;其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择到映射好的 SQL 语句。
Mapper代理方式
1、定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下 注意:在resources配置文件下创建相同的文件结构时,需使用【 /】 分割,不可使用 【 . 】 如:com/song/mapper
2、设置SQL映射文件的namespace属性为Mapper接口全限定名
3、在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
4、编码
1、通过SqlSession的getMapper方法获取Mapper接口的代理对象
2、调用对应方法完成sql的执行
注:如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载
MyBatis核心文件配置:
mybatis-config.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
注意:顺序不能弄错 顺序查看 https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases
类型别名(typeAliases) 可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写 。在此加上之后,mybatis会扫描这个包下的实体类,并起别名
每一个在包 com.song.pojo 中的实体类,在没有注解的情况下,会使用实体类的首字母小写的非限定类名来作为它的别名。
-->
<typeAliases>
<package name="com.song.pojo"/>
</typeAliases>
<!-- environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///ssm?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<mapper resource="com/song/mapper/UserMapper.xml"/>
</mappers>
</configuration>
SQL映射文件配置:
如查询User表
UserMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:名称空间-->
<mapper namespace="com.song.mapper.UserMapper">
<!--查User全部-->
<select id="selectAll" resultType="user"> <!--别名不区分大小写 若不使用别名,此处则需填写 com.song.pojo.User 否则报错-->
select * from user
</select>
</mapper>
处理数据库中表字段名称与实体类名称不一致的情况,使它自动封装数据
注意:下面代码放在mapper标签中
<!--数据库表的字段名称 和 实体类的属性名称 不一致,不能自动封装数据
处理方式
1、起别名:对不一样的列名起别名,让别名和实体类的属性名一样
缺点:每次查询都要定义一次别名
2、sql片段
缺点:不灵活
3、resultMap:
定义<result Map>标签
在<select>标签中,使用resultMap属性替换 resultType属性-->
<!-- id:唯一标识 type:映射的类型,支持别名 -->
<resultMap id="userResultMap" type="com.song.pojo.User">
<!--
id:完成主键字段的映射
column:表的列名
property:实体类的属性名
result:完成一般字段的映射
column:表的列名
property:实体类的属性名
-->
<result column="user_name" property="username"/>
</resultMap>
查询详情,根据id进行查询:
*参数占位符
1.#{}:会将其替换为 ?,为了防止SQL注入
2.${}:拼sql,会存在sql注入问题
3.使用时机:
*参数传递的时候使用:#{}
*表名或列名不固定的情况下使用:${} 会存在sql注入问题
*参数类型:parameterType:可以省略不写
*特殊字符处理:
1.转义字符 : 如:< 代表小于符号
2.CDATA区 : 如: <![CDATA[ < ]]> 代表小于符号 输入CD即可提示
多条件查询 三种方式传值
* *参数接收
* 1.散装参数:如果方法中有多个参数,需使用@Param(“SQL参数占位符名称”)
* 2.对象参数:只需保证对象的属性名称要和参数占位符名称一致
* 3.map集合参数:只需保证SQL中的参数名和map集合的键的名称对应上,即可设置成功
多条件查询之动态条件查询
动态SQL
if用于判断参数是否有值,使用test属性进行条件判断
*存在的问题:第一个条件不需要逻辑运算符
*解决方案:
(1)使用恒等式让所有条件格式都一样 例:1=1
(2)<where>标签替换where关键字
MyBatis事务:
openSession():默认开启事务,进行增删改查操作后需要使用sqlSession.commit();手动提交事务
openSession(true):可以设置为自动提交事务(关闭事务)
<insert id="add" useGeneratedKeys="true" keyProperty="id"> 返回添加数据的主键
mybatis 会将数组参数,封装为一个Map集合。
*(1)默认:array = 数组
*(2)使用@Param注解改变map集合的默认key的名称 如接口中@Param("ids") foreach中的collection="ids"
MyBatis参数封装:
*单个参数:
1.POJO类型:直接使用, 属性名 和 参数占位符名称 一致
2.Map集合:直接使用, 键名 和 参数占位符名称 一致
3.Collection:封装为Map集合 可以使用@Param注解,替换Map集合中默认的arg键名
map.,put(“arg0”,collection集合)
map.,put(“collection”,collection集合)
4.List:封装为Map集合 可以使用@Param注解,替换Map集合中默认的arg键名
map.,put(“arg0”,list集合)
map.,put(“collection”,list集合)
map.,put(“list”,list集合)
5.Array:封装为Map集合 可以使用@Param注解,替换Map集合中默认的arg键名
map.,put(“arg0”,数组)
map.,put(“collection”,数组)
6.其他类型:直接使用
*多个参数:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put( "arg0",参数值1)
map.put( "param1",参数值1)
map . put( "param2",参数值2)
map .put( "agr1",参数值2)
-------------—-@Param( "username" )
map .put( "username",参数值1)
map .put( "param1",参数值1)
map.put("param2",参数值2)
map.put( "agr1",参数值2)
建议:将来都使用@Param注解来修改Map集合中默认的键名,并使用修改后的名称来获取值,这样可读性更高!!!
注解开发:
简单sql使用注解,复杂语句使用xml文件
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。
选择何种方式来配置映射,以及是否应该要统一映射语句定义的形式,完全取决于你和你的团队。 换句话说,永远不要拘泥于一种方式,你可以很轻松地在基于注解和 XML 的语句映射方式间自由移植和切换。