前言

原来跟着做博客的时候持久层就用的jpa,虽然后面那个铸币企业开发也得考jpa,但还是得学MyBatis,但好像这个也在被淘汰了,麻了。


开始

作用

持久层框架,用于简化jdbc开发。

1
2
3
4
javaEE三层框架:表现层,业务层,持久层
表现层:用于业务展示
业务层:用于逻辑处理
持久层:负责将数据保存到数据库的代码层

使用

项目添加

先在xml文件中导入mybatis依赖,然后在resources中添加mybatis-config.xml文件以及mapper查询语句文件。对应内容上官网查询


mapper文件

mapper文件

图中namespace为名称空间,可自定义,作用为区分不同空间中的操作id,类似于接口

下面每个标签为一个查询语句。id为语句唯一表示符,resultType为查询返回对象,中间部分为sql操作语句。

对应对象类应该放到pojo软件包中作为pojo类


主类中使用

使用时百度,不会有人能记住这些玩意吧

1
2
3
4
5
6
7
8
9
10
11
12
13
//1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//2. 获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();

//3. 执行sql
List<User> users = sqlSession.selectList("test.selectAll");//()内为sql语句标识,为空间加上id

//4. 释放资源
sqlSession.close();

相关语法

参数占位符

在sql语句中使用#{var}表示传入变量,var依据方法内变量名填写,会将其其替换为?防止sql注入

用${}会拼接sql语句,存在sql注入问题

参数传递用#{},动态查询时使用${}(相对较少)

在方法里若需要传入多个变量,需添加@Param注解表示对应变量;若属于一个对象可直接传入一个对象或者一个map。

1
2
List<var> selectById(@Param("id")int id,@Param("name")String name);
//param()内文本为sql语句中对应参数名

参数类型

可使用parameterType确定,但可省略


特殊字符处理

例如“<”等,可使用转义字符或者CDATA区

1
<![CDATA[文本]]>

动态查询

if

作用为条件判断,test为固定表达

1
2
3
<if test="条件语句">
sql语句
</if>

若进行空字符串判断,不能使用.equals()方法,也不能使用&&连接

1
2
3
<if test="var ! = null and var != '' ">
sql语句
</if>

可使用”<where></where>”包裹所有条件并在if的sql语句中均加上and避免where后的and语法错误


choose(when,otherwide)

作用为多个条件中选择查询,类似于switch语句

1
2
3
4
5
6
7
8
9
<choose>
<when test="条件语句">
sql语句
</when>
···
<otherwise>
sql语句
</otherwise>
</choose>

Mapper代理开发

步骤

1.定义与sql映射同名的Mapper接口,并且放在sql映射文件同一目录

但不能将mapper文件直接移出resource文件夹,会导致文件结构混乱。

解决方法:在resource文件夹内创建同样目录文件夹,但快捷创建时需要使用/作为分隔符,否则起不到多级目录的效果。

2.设置namespace为Mapper接口的全限定名

3.在Mapper接口中定义方法,方法名为sql语句id,保持参数类型和返回类型一致(注意返回为单个对象还是list对象)

1
2
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();

4.编码:改变对应路径等(此时可直接使用包扫描方式)