文章目录


第四章 动态SQL

什么是动态sql:同一个dao方法,根据不同的条件可以表示不同的sq语句,只要是where部分有变化。

使用mybatis提供的标签,实现动态sql的能力,主要讲if,where,foreach,sql。

使用动态sql的时候,dao方法的形参使用java对象。

动态sql的使用情景:多条件查询

1.if标签

语法:

<if test ="boolean判断结果">
sql代码
</if>

在mapper文件中
<select id = "selectStudent" resultType="com.sunny.domain.student">
select * from student
<if test = "条件1">
sql语句
</if>
<if test = "条件2">
sql语句
</if>
<if test = "条件3">
sql语句
</if>
</select>

例子

//    if dao接口
List<Student> selectIf(Student student);
测试类
@Test
public void testSelectIf(){
// 1.获取SqlSession
SqlSession session= MyBatisUtil.getSqlSession();
// 2.获取dao的代理
StudentDao dao = session.getMapper(StudentDao.class);
Student student = new Student();
student.setName("李四");
// 也可以只差一个数据,下面的20不查询也可以。但是如果不查第一数据sql语句就会报错
student.setAge(22);
List<Student> students = dao.selectIf(student);
students.forEach(stu-> System.out.println("stu==="+stu));
// 3.关闭SqlSession对象
session.close();
}

mapper文件

<!--    if
id =-1是为了符合sql语法 1=1也可以
-->
<select id="selectIf" resultType="com.sunny.domain.Student">
select * from student
where id =-1
<if test="name!=null and name!=''">
or name =#{name}
</if>

<if test="age >0">
or age < #{age}
</if>
</select>

2.where标签

使用if标签时,容易引起sql语句语法错误。使用where标签解决if产生的语法问题。

使用时where里面是一个或多个if标签,当有一个if标签判断条件为true,where标签会转为WHERE关键字附加到sql语句后面。如果if没有一个条件为true,忽略where和里面的if。

where标签会删除和他最近的or或者and

语法:

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

实例

//    where
List<Student> selectWhere(Student student);
<!--    where
where会帮你把多余的 or 去掉
-->
<select id="selectWhere" resultType="com.sunny.domain.Student">
select * from student
<where>
<if test="name!=null and name!=''">
or name =#{name}
</if>

<if test="age >0">
or age < #{age}
</if>
</where>
</select>

3 .foreach循环

手工实现循环。

@Test
public void testFor(){
List<Integer> idlist = new ArrayList<>();

idlist.add(1001);
idlist.add(1002);
idlist.add(1003);

// 查询id在idlist中的student
// select * from student where id in (1001,1002,1003)
StringBuffer sql=new StringBuffer("");
sql.append("select * from student where id in ");

//使用循环,把List数据追加到 sql 字符串 中。
// 循环之前加入
sql.append("(");

for(int i = 0;i<idlist.size();i++){
// item是集合成员
Integer item = idlist.get(i);
// 添加成员到sql字符串
sql.append(item);
sql.append(",");//集合成员之间的分隔符。
}
// 循环之后,加入)

sql.deleteCharAt(sql.length()-1);
sql.append(")");
System.out.println(sql);

}

使用foreach可以循环数组,list集合,一般使用在in语句中。

语法:

<foreach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" 
separator="集合成员之间的分隔符">
#{item的值}
</foreach>

标签属性:
collection: 表示循环的对象是数组还是list集合。
如果dao接口方法的形参是数组 collection="array"
如果dao接口形参是List collection="list"

open:循环开始时的字符。 sql.append("(");
close:循环结束时的字符。 sql.append(")");
item: 集合成员,自定义变量。 Integer item = idlist.get(i);
separator:集合成员之间的分隔符。 sql.append(",");//集合成员之间的分隔符。
#{item的值} : 获取集合成员的值。

3.1第一种方式

//    foreach-1 dao接口
List<Student> selectForeachOne(List<Integer> idlist);

//xml文件

<!-- foreach第一种方式,循环简单类型的List-->
<select id="selectForeachOne" resultType="com.sunny.domain.Student">
select * from student
<if test="list!=null and list.size > 0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="myid">
#{myid}
</foreach>
</if>

</select>
;

//测试类

@Test
public void testSelectForeachOne(){
// 1.获取SqlSession
SqlSession session= MyBatisUtil.getSqlSession();
// 2.获取dao的代理
StudentDao dao = session.getMapper(StudentDao.class);

List<Integer> idlist = new ArrayList<>();
idlist.add(1001);
idlist.add(1002);
idlist.add(1004);
idlist.add(1005);

List<Student> students = dao.selectForeachOne(idlist);
students.forEach(stu-> System.out.println("stu==="+stu));
// 3.关闭SqlSession对象
session.close();
}

3.2第二种方式

//    foreach-2
List<Student> selectForeachTwo(List<Student> studentList);

xml文件

<!-- foreach-2第二种方式,循环List<Student>-->
<select id="selectForeachTwo" resultType="com.sunny.domain.Student">
select * from student
<if test="list != null and list.size>0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="stu">
#{stu.id}
</foreach>
</if>
</select>


测试类

@Test
public void testSelectForeachTwo(){
// 1.获取SqlSession
SqlSession session= MyBatisUtil.getSqlSession();
// 2.获取dao的代理
StudentDao dao = session.getMapper(StudentDao.class);

List<Student> list = new ArrayList<>();
Student s1 = new Student();
s1.setId(1001);
Student s2 = new Student();
s2.setId(1002);

list.add(s1);
list.add(s2);

List<Student> students = dao.selectForeachTwo(list);
students.forEach(stu-> System.out.println("stu==="+stu));
// 3.关闭SqlSession对象
session.close();
}

4.sql标签

sql标签表示一段sql代码,可以是表名,几个字段,where条件都可以,可以在其他地方复用sql标签的内容。

使用方式:

1)在mapper文件中定义 sql代码片段<sql id="唯一字符串"> 部分sql语句 </sql>
2)在其他的位置,使用include标签引用某个代码片段。

例子:

<!--    定义代码片段-->
<sql id="selectStudent">
select *from student
</sql>

<sql id="studentFieldList">
id,name,email
</sql>


<select id="selectIf" resultType="com.sunny.domain.Student">
<include refid="selectStudent"/>
where id =-1
<if test="name!=null and name!=''">
or name =#{name}
</if>

<if test="age >0">
or age < #{age}
</if>
</select>

<!-- where
where会帮你把多余的 or 去掉
-->
<select id="selectWhere" resultType="com.sunny.domain.Student">
select <include refid="studentFieldList"/> from student
<where>
<if test="name!=null and name!=''">
or name =#{name}
</if>

<if test="age >0">
or age < #{age}
</if>
</where>
</select>

第五章 MyBatis配置文件

mybatis配置文件两大类:1.mybatis主配置文件;2.mybatis的mapper文件

1.mybatis主配置文件,提供mybatis全局设置的。包含的内容日志,数据源,mapper文件位置。

2.mapper文件:写sql语句的。一个表一个mapper文件

1.settings部分

这部分一般不需要修改。

settings是mybatis的全局设置,影响整个mybatis的运行。这个设置一般使用默认值就可以了。

完整的setting元素

<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

2.typeAliase 别名

设置别名 (一般直接使用全限定名称)

<typeAliases>
<!-- 第一种语法格式
type:java类型的全限定名称(自定义类型)
alias:自定义别名

优点:别名可以自定义
缺点:每个类型单独定义
-->
<!-- <typeAlias type="com.sunny.domain.Student" alias="stu"></typeAlias>-->
<!-- <typeAlias type="com.sunny.vo.QueryParam" alias="qp"></typeAlias>-->

<!--
第二种方式
name:包名,mybatis会把这个包所有类名作为别名(不用区分大小写)

优点:使用方便,一次给多个类定义别名
缺点:别名不能自定义,必须是类名。
-->
<package name="com.sunny.domain"/>
<package name="com.sunny.vo"/>
</typeAliases>

3.配置环境

environments:环境标签,在他里面可以配置多个environment。
属性:default,必须是某个environment的id属性值。表示mybatis默认连接的数据库。

environment:表示一个数据库的连接信息。
属性:id自定义的环境的标识。唯一值。
transactionManager:事务管理器
属性:type 表示事务管理器的类型
属性值:1)JDBC:使用Connection对象,由mybatis自己完成事务的处理。
2)MANAGED:管理,表示把事务的处理交给容器实现(由其他软件完成事务的提交,回滚)
dataSource : 数据源,创建的Connection对象,连接数据库。
属性:type数据源的类型
属性值:1)POOLED,mybatis会在内存中创建PooledDataSource类,管理多个Connection连接对象,使用的连接池。
2)UNPOOLED,不使用连接池,mybatis创建一个UnPooledDataSource这个类,每次执行sql语句先创建Connection对象,在执行sql语句,最后关闭Connection。
3)JNDI:java的命名和服务目录。
<environments default="development"> <!--default="online" -->
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 配置数据源:创建Connection对象-->
<dataSource type="POOLED">
<!-- driver:驱动的内容-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 连接数据库的url-->
<property name="url" value="jdbc:mysql://localhost:3306/springdb?useUnicode=true&
characterEncoding=utf-8"/>
<!-- 用户名-->
<property name="username" value="root"/>
<!-- 密码-->
<property name="password" value="123456"/>
</dataSource>
</environment>


<!-- 项目上线后使用的数据库-->

<environment id="online">
<transactionManager type="JDBC"/>
<!-- 配置数据源:创建Connection对象-->
<dataSource type="POOLED">
<!-- driver:驱动的内容-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 连接数据库的url-->
<property name="url" value="jdbc:mysql://localhost:3306/springdb?useUnicode=true&
characterEncoding=utf-8"/>
<!-- 用户名-->
<property name="username" value="root"/>
<!-- 密码-->
<property name="password" value="123456"/>
</dataSource>
</environment>

</environments>

4.使用数据库属性配置文件(要求掌握)

需要把数据库的配置信息放到一个单独文件中,独立管理。这个文件拓展名是properties。在这个文件中,使用自定义的key=value的格式表示数据。

使用步骤:

1.在resources目录中,创建xxxx.properties

2.在文件中,使用key=value的格式定义数据。

例如:jdbc.url=jdbc:mysql://localhost:3306/springdb

3.在mybatis主配置文件,使用properties标签引用外部的属性配置文件。

4.在使用值的位置,使用${key}获取key对应的value(等号右侧的值)。

例子:

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456

mybatis主配置文件

<!--    使用外部属性配置文件
resource:指定类路径下的某个属性的配置文件
-->

<properties resource="jdbc.properties"/>

<!--
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>

<package name="com.sunny.domain"/>
<package name="com.sunny.vo"/>
</typeAliases>
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 配置数据源:创建Connection对象-->
<dataSource type="POOLED">
<!-- driver:驱动的内容-->

<property name="driver" value="${jdbc.driver}"/>

<!-- 连接数据库的url-->
<property name="url" value="${jdbc.url}"/>
<!-- 用户名-->
<property name="username" value="${jdbc.username}"/>
<!-- 密码-->
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>

5.mapper标签(掌握)

使用mapper指定其他mapper文件的位置。

mapper标签使用的格式

<mappers>
<!--
第一种方式,resources="mapper文件的路径"
优点:文件清晰。加载的文件是明确的。
文件的位置比较灵活。
缺点:文件比较多,代码量会比较大,管理难度大。
-->
<mapper resource="com/sunny/dao/StudentDao.xml"/>
<mapper resource="com/sunny/dao/OrderDao.xml"/>
<!--
第二种方式,使用<package>
name:包名,mapper文件所在的包名。
特点:把这个包中所有的mapper文件,一次加载。

使用要求:
1.mapper文件和dao接口在同一目录。
2.mapper文件和dao接口名称完全一样。 两种方式不要同时对一个文件使用
-->
<package name="com.sunny.dao"/>
<package name="com.sunny.dao1"/>

</mappers>

第六章 拓展 PageHelper

PageHelper做数据分页,在你的select语句后面加入分页的sql内容,如果你使用的是mysql数据库,它就是在

select * from student

后面加上limit语句。

1.加入PageHelper依赖

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.1</version>
</dependency>

2.在mybatis主配置文件加入plugin声明

在<environments>之前加入 

<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor" />
</plugins>

3.在select语句之前,调用PageHelper.startPage(页码,每页大小)

使用PageHelper

SELECT count(0) FROM student

select * from student order by id LIMIT ?

<select id="selectAllStudent" resultType="com.sunny.domain.Student">
select * from student order by id
</select>
List<Student> selectAllStudent();
@Test
public void testPageHelper(){
// 1.获取SqlSession
SqlSession session= MyBatisUtil.getSqlSession();
// 2.获取dao的代理
StudentDao dao = session.getMapper(StudentDao.class);

//调用PageHelper的方法 第2页 查3条记录
PageHelper.startPage(2,3);

List<Student> students = dao.selectAllStudent();
students.forEach(stu-> System.out.println("stu==="+stu));
// 3.关闭SqlSession对象
session.close();
}


但行好事,莫问前程。 浅浅的MyBatis学习结束。
tudent">
select * from student order by id


```java
List<Student> selectAllStudent();
@Test
public void testPageHelper(){
// 1.获取SqlSession
SqlSession session= MyBatisUtil.getSqlSession();
// 2.获取dao的代理
StudentDao dao = session.getMapper(StudentDao.class);

//调用PageHelper的方法 第2页 查3条记录
PageHelper.startPage(2,3);

List<Student> students = dao.selectAllStudent();
students.forEach(stu-> System.out.println("stu==="+stu));
// 3.关闭SqlSession对象
session.close();
}


但行好事,莫问前程。 浅浅的MyBatis学习结束。