MyBatis动态SQL
Posted nuist__NJUPT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis动态SQL相关的知识,希望对你有一定的参考价值。
MyBatis动态SQL
MyBatis提供了对SQL语句的动态组装,不再需要开发人员手动拼接SQL语句,MyBatis的动态SQL元素与JSTL或XML文本处理器相似,常用if,choose,when,otherwise,trim,where,set,foreach和bind等元素。
准备工作:
1-使用mysql创建名为spring的数据库,在该数据库中创建用户表user,并录入相关数据,如下所示。
2-用IDEA创建名为DynamicSQL的web应用,并在web目录下的WEB-INF文件夹下导入相关jar包,并将jar包添加为库项目。
3-在src目录下创建日志文件log4j.properties
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4-在src目录下创建spring配置文件applicationContext.xml,在该文件中配置数据源,需要扫描的包,是注解生效等
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--指定需要扫描的包,是注解生效-->
<context:component-scan base-package="com.dao"/>
<context:component-scan base-package="com.controller"/>
<!--配置数据源-->
<bean id = "dataSource" class = "org.apache.commons.dbcp2.BasicDataSource">
<!--配置数据库驱动-->
<property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
<!--配置连接数据库的url-->
<property name = "url" value = "jdbc:mysql://localhost:3306/spring?characterEncoding=utf8"/>
<!--连接数据库的用户名-->
<property name = "username" value = "root"/>
<!--连接数据库的密码-->
<property name = "password" value = "123456"/>
<!--最大连接数-->
<property name = "maxTotal" value = "30"/>
<!--最大空闲连接数-->
<property name = "maxIdle" value = "10"/>
<!--初始化最大连接数-->
<property name = "initialSize" value = "5"/>
</bean>
<!--添加事务支持-->
<bean id = "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name = "dataSource" ref = "dataSource"/>
</bean>
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="txManager"/>
<!--配置MyBatis工厂,同时指定数据源,并与MyBatis完美整合-->
<bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean">
<property name = "dataSource" ref = "dataSource"/>
<!--configLocation的属性值为MyBatis的核心配置文件-->
<property name = "configLocation" value = "classpath:com/mybatis/mybatis-config.xml"/>
</bean>
<!--Mapper代理开发,使用Spring自动扫描MyBatis接口并装配,Spring将指定包中的所有被@Mapper注解过的接口自动装配为MyBatis的映射接口-->
<bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--mybatis-spring的组件扫描器-->
<property name = "basePackage" value = "com.dao"/>
<property name = "sqlSessionFactoryBeanName" value = "sqlSessionFactory"/>
</bean>
</beans>
5-在src目录下创建com.po包,在该包中创建user表的可持久化类MyUser。
public class MyUser {
public Integer uid ; //主键
public String uname ;
public String usex ;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUsex() {
return usex;
}
public void setUsex(String usex) {
this.usex = usex;
}
@Override
public String toString(){
return "User [uid = " + uid + " uname = " + uname + " usex = " + usex + "]" ;
}
}
6-在src目录下创建com.mybatis包,在该包中创建user表的SQL映射文件UserMapper.xml和MyBatis的核心配置文件mybatis-comfig.xml
UserMapper.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "com.dao.UserDao">
<!--使用if元素根据条件动态查询用户信息-->
<select id = "selectUserByIf" parameterType = "com.po.MyUser" resultType = "com.po.MyUser">
select * from user where 1=1
<if test = "uname != null and uname != ''">
and uname like concat('%', #{uname}, '%')
</if>
<if test = "usex != null and usex != ''">
and usex = #{usex}
</if>
</select>
<!--choose,when,otherwise类似于switch,case,default,选择语句-->
<!--使用choose,when,otherwise,根据条件动态查询用户信息,当满足第一个when的时候,其它不执行,第一个不满足,而第二个满足,则执行第二个when,否则执行otherwise-->
<select id = "selectUserByChoose" parameterType = "com.po.MyUser" resultType = "com.po.MyUser">
select * from user where 1=1
<choose>
<when test = "uname != null and uname != ''">
and uname like concat('%', #{uname}, '%')
</when>
<when test = "usex != null and usex != ''">
and usex = #{usex}
</when>
<otherwise>
and uid > 10
</otherwise>
</choose>
</select>
<!--trim的主要功能是在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix,
也可以把内容的某些首部覆盖,也可以把尾部的某些内容覆盖,对应的属性为prifixOverrides和suffixOverrides,可以使用trim来代替where元素的功能-->
<!--使用trim元素根据条件动态查询用户信息-->
<select id = "selectUserByTrim" parameterType = "com.po.MyUser" resultType = "com.po.MyUser">
select * from user
<trim prefix = "where" prefixOverrides = "and | or">
<if test = "uname != null and uname != ''">
and uname like concat('%', #{uname}, '%')
</if>
<if test = "usex != null and usex !=''">
and usex = #{usex}
</if>
</trim>
</select>
<!--where元素的作用是会在写入where元素的地方输出一个where语句,另外一个好处是不需要考虑where里面的条件的输出是什么样子,
MyBatis将智能处理-->
<!--使用where元素根据条件动态查询用户信息-->
<select id = "selectUserByWhere" parameterType = "com.po.MyUser" resultType = "com.po.MyUser">
select * from user
<where>
<if test = "uname != null and uname != ''">
and uname like concat('%', #{uname}, '%')
</if>
<if test = "usex != null and usex != ''">
and usex = #{usex}
</if>
</where>
</select>
<!--使用set元素动态修改一个元素-->
<update id = "updateUserBySet" parameterType = "com.po.MyUser" >
update user
<set>
<if test = "uname != null"> uname = #{uname},</if>
<if test = "usex != null"> usex = #{usex}</if>
</set>
where uid = #{uid}
</update>
<!--foreach元素主要用在构建in条件中,它可以在SQL语句中迭代一个集合,foreach元素的属性主要有item,index,collection,open,separator,close
item表示集合中每一个元素进行迭代的别名;index表示指定一个名字,用于表示每次迭代到达的位置;open表示该语句以什么开始;separator表示每次以什么符号作为分隔符;;
close表示以什么结束;在使用foreach元素时,最关键,最容易出错的是collection属性,该属性是必选的,但在不同的情况下,该属性的值不一样,主要有以下三种情况:、
第一,如果传入的是单参数且参数类型是一个List,collection属性值为list;第二,如果传入的是单参数且参数类型是一个array数组,collection的属性是值是array;
第三,如果传入的参数是多个,需要把它封装成一个Map,当然单参数也可以封装成Map,Map的key是参数名,collection属性值是传入的List或array对象在自己封装的Map中的key
-->
<!--使用foreach语句查询用户信息-->
<select id = "selectUserByForeach" parameterType = "List" resultType = "com.po.MyUser">
select * from user where uid in
<foreach item = "item" index = "index" collection = "list" open = "(" separator = "," close = ")">
#{item}
</foreach>
</select>
<!--bind元素,当进行模糊查询,使用符号拼接字符串,则无法防止SQL注入,如果使用字符串拼接函数或者连接符号,但在不同的数据库拼接函数和连接符号不同
例如MySQL的concat和Oracle的连接符号||,这样SQL映射文件就需要根据不同的数据库提供不同的实现,显然比较麻烦,不利于代码的移植,MyBatis提供bind元素来解决这一问题-->
<!--使用bind元素进行模糊查询-->
<select id = "selectUserByBind" resultType = "com.po.MyUser" parameterType = "com.po.MyUser">
<bind name = "param_uname" value = "'%' + uname + '%'"/>
select * from user where uname like #{param_uname}
</select>
</mapper>
mybatis-comfig.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org/= /DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--在使用MyBatis嵌套查询方式进行关联查询时,使用MyBatis延时加载可以在一定程度上提高查询效率-->
<settings>
<!--打开延时加载开关-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--将积极加载改成按需加载-->
<setting name = "aggressiveLazyLoading" value = "false"/>
</settings>
<!--告诉MyBatis映射文件的位置-->
<mappers>
<mapper resource = "com/mybatis/UserMapper.xml"/>
</mappers>
</configuration>
7-在src目录下创建com.dao包,在该包中创建接口UserDao,该接口和SQL映射文件组成映射器,完成SQL映射,spring将指定包中被@Mapper注解的接口自动装配为MyBatis的映射接口
import com.po.MyUser;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
@Mapper
public interface UserDao {
public List<MyUser> selectUserByIf(MyUser user) ;
public List<MyUser> selectUserByChoose(MyUser user) ;
public List<MyUser> selectUserByTrim(MyUser user) ;
public List<MyUser> selectUserByWhere(MyUser user) ;
public int updateUserBySet(MyUser user) ;
public List<MyUser> selectUserByForeach(List<Integer> listId) ;
public List<MyUser> selectUserByBind(MyUser myuser) ;
}
8-在src目录下创建包com.controller,在该包中创建UserController类,在该类中注入接口对象,并调用接口方法
import com.dao.UserDao;
import com.po.MyUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import java.util.ArrayList;
import java.util.List;
@Controller
public class UserController {
@Autowired
public UserDao userDao ;
public void test(){
MyUser ifmu = new MyUser() ;
ifmu.setUname("张") ;
ifmu.setUsex("女") ;
List<MyUser> list = userDao.selectUserByIf(ifmu) ;
for(MyUser myUser : list){
System.out.println(myUser) ;
}
System.out.println("=========================") ;
MyUser choosemu = new MyUser() ;
choosemu.setUsex("") ;
choosemu.setUname("") ;
List<MyUser> list1 = userDao.selectUserByChoose(choosemu) ;
for(MyUser myUser : list1){
System.out.println(myUser + " ") ;
}
System.out.println("=========================") ;
MyUser trimmu = new MyUser() ;
trimmu.setUname("胡") ;
trimmu.setUsex("男") ;
List<MyUser> list2 = userDao.selectUserByTrim(trimmu) ;
for(MyUser myUser1 : list2){
System.out.println(myUser1) ;
}
System.out.println("=========================") ;
MyUser wheremu = new MyUser(mybatis动态sql片段与分页,排序,传参的使用
Mybatis -- 动态Sql概述动态Sql之<if>(包含<where>)动态Sql之<foreach>sql片段抽取
mybatis动态sql之利用sql标签抽取可重用的sql片段
MYBATIS05_ifwherechoosewhentrimsetforEach标签sql片段