1.Spring整合mybatis
1.在pom文件中配置需要的依赖jar
<!--Spring对JDBC的支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!--Spring对Mybatis的支持-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
2.jdbc.properties配置;
driver=com.mysql.cj.jdbc.Driver
user=root
psw=123456
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
3.spring-mybatis的配置
<!--加载配置文件-->
<util:properties id="db" location="classpath:DB.properties"/>
配置数据源
<!--配置C3p0数据源-->
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--驱动-->
<property name="driverClass" value="#{db.driver}"/>
<!--数据库用户-->
<property name="user" value="#{db.user}"/>
<!--数据库密码-->
<property name="password" value="#{db.psw}"/>
<!--数据库连接地址-->
<property name="jdbcUrl" value="#{db.url}"/>
<property name="maxPoolSize" value="10"/><!--最大连接数-->
<property name="minPoolSize" value="2"/><!--最小连接数-->
</bean>
配置模板
<!--配置模板-->
<bean id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sessionFactory"/>
</bean>
配置mapper
<!--配置接口扫描:把接口和Mybatis语句映射文件自动对应-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描包下的所有接口-->
<property name="basePackage" value="cn.gok.daos"/>
<!--指定注解接口有效:只扫描特定注解的接口-->
<!--<property name="annotationClass" value="org.springframework.stereotype.Repository"/>-->
</bean>
配置SqlsessionFactory
<!--配置SqlSessionFactory-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--使用C3p0数据源-->
<property name="dataSource" ref="c3p0"/>
<!--扫描配置文件-->
<property name="mapperLocations" value="classpath:mappers/*.xml"/>
</bean>
2.动态sql语句
if标签
这里的if标签主要是用来判断用户是否输入了某个条件,如果输入了再将该条件拼接到sql语句中,如下示例表示用户可以输入两个查询条件,name和age
<select id="selectIf" resultType="student">
SELECT id,name,age,score
FROM t_student
WHERE 1=1
<if test="name != null and name != ''">
AND name LIKE '%' #{name} '%'
</if>
<if test="age>=0">
AND age > #{age}
</if>
</select>
在上面的语句中,我们在where后面添加了一个1=1的条件,这样就不至于两个条件均未设定而出现只剩下一个where,这样sql语句就不正确了,所以在后面添加了1=1这个为true的条件。
在dao中添加方法
List<Student> selectIf(Student student);
在测试类中进行测试:
@Test
public void selectIf(){
Student student = new Student("富", 0, 0.0);
List<Student> students = studentDao.selectIf(student);
students.forEach((s)-> {
System.out.println(s);
});
}
where标签
在上面的if语句中,为了防止用户未设置条件而导致sql语句出现一个where,我们添加了1=1这个条件,但是这个条件没有什么意义,所以可以使用where标签来解决这个问题。
在mapper中添加下面sql
<select id="selectWhere" resultType="student">
SELECT id,name,age,score
FROM t_student
<where>
<if test="name != null and name != ''">
name LIKE '%' #{name} '%'
</if>
<if test="age>=0">
AND age > #{age}
</if>
</where>
</select>
使用where标签后,就无需再写1=1了,注意在第一个if标签中的sql可以不加and,但是其后面的if标签中必须要加and
在dao中添加方法
List<Student> selectWhere(Student student);
测试:
public void selectWhere(){
Student student = new Student("富", 0, 0.0);
List<Student> students = studentDao.selectWhere(student);
students.forEach((s)-> {
System.out.println(s);
});
}
trim标签
上面使用了where标签来完成了查询操作,如果where的元素与我们期望的不一样时,可以使用trim标签来定制where元素的功能,例如下面内容跟上面的where是等价的
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="name != null and name != ''">
name LIKE '%' #{name} '%'
</if>
<if test="age>=0">
AND age > #{age}
</if>
</trim>
choose标签
通过choose标签实现下面功能若姓名不空,则按照姓名查询;若姓名为空,则按照年龄查询;若没有查询条件,则没有查询结果。
<select id="selectChoose" resultType="student">
SELECT id,name,age,score
FROM t_student
<where>
<choose>
<when test="name != null and name != ''">
name LIKE '%' #{name} '%'
</when>
<when test="age>=0">
age > #{age}
</when>
<otherwise>
1 != 1
</otherwise>
</choose>
</where>
</select>
在choose标签中可以有多个when,但是只能有一个otherwise,这个有点类似java中的switch语句。
在dao接口中添加下面方法:
List<Student> selectChoose(Student student);
测试
public void selectChoose(){
Student student = new Student(null, -1, 0.0);
List<Student> students = studentDao.selectChoose(student);
students.forEach((s)-> {
System.out.println(s);
});
}
set标签
在做update操作的时候倘若某个实体bean的属性是null时,数据库中对应的字段也会变成null,这样就会出现问题,此时我们可以通过set标签解决,在mapper文件中添加下面内容
<update id="updateStudent">
UPDATE t_student
<set>
<if test="name != null">name=#{name},</if>
<if test="age >= 0">age=#{age},</if>
<if test="score > 30">score=#{score},</if>
</set>
WHERE id=#{id}
</update>
foreach标签遍历数组
有时候会有这样的操作,用户需要查询Student的id是5,6,10,15的数据,这些数据可能会被放到数组里面作为参数进行传递,以前我们可以在sql语句中使用in来实现,在mybatis中就可以使用foreach标签。
foreach标签的属性中
collection 表示要遍历的集合类型,这里是数组,即 array。
open、close、separator 为对遍历内容的 SQL 拼接。
<select id="selectForeachArray" resultType="student">
SELECT id,name,age,score
FROM t_student
<if test="array != null and array.length>0">
WHERE id IN
<foreach collection="array" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</select>
需要注意的是在if标签中的test属性里面,array是固定写法,表示数组。
在dao中添加方法:
List<Student> selectForeachArray(Object[] ids);
测试
public void selectForeachArray(){
Object[] ids = new Object[]{5,6,10,15};
List<Student> students = studentDao.selectForeachArray(ids);
students.forEach((s)-> {
System.out.println(s);
});
}
foreach标签遍历基本数据类型的集合
<select id="selectForeachList" resultType="student">
SELECT id,name,age,score
FROM t_student
<if test="list != null and list.size>0">
WHERE id IN
<foreach collection="list" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</select>
List<Student> selectForeachList(List<Integer> ids);
@Test
public void selectForeachList(){
List<Integer> list = new ArrayList<>();
list.add(5);
list.add(6);
list.add(10);
list.add(15);
List<Student> students = studentDao.selectForeachList(list);
students.forEach((s)-> {
System.out.println(s);
});
}
sql标签
sql标签可以用来定义一个可被复用的sql片段,在使用的时候写上include标签就可以将sql标签中的内容引入。当某段sql语句会被多次使用时,可以将这段sql语句放到sql标签中。
<!--定义sql片段-->
<sql id="select">
SELECT id,name,age,score
FROM t_student
</sql>
<select id="selectSQL" resultType="student">
<!--使用sql片段-->
<include refid="select"/>
<if test="list != null and list.size>0">
WHERE id IN
<foreach collection="list" open="(" close=")" item="stu" separator=",">
#{stu.id}
</foreach>
</if>
</select>