Spring整合mybatis和动态Sql语句

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>

猜你喜欢

转载自blog.csdn.net/AD20171/article/details/106794487