目录
一、动态SQL的元素
元素 | 作用 |
<if> | 是判断语句,当满足了条件就会执行标签里面的动态SQL |
<choose><when> <otherwise> | <when>会进行多层判断,最后如果都没匹配到<when>就会执行<otherwise> |
<where> <trim> | 只有<where>元素里面的条件成立的时候,<where>里面的拼接SQL才会被执行,即使后面还有and,or这些。也会被祛除。 |
<set> | 在执行动态SQL前,输出一个set关键字,并将最后一个多余的逗号祛除。 |
<foreach> | 查多个数据的时候 |
<bind> | 解决注入,解决不同数据库拼接的问题。到达不使用原本数据库的方式。 |
二、实例
1、项目结构
2、建包建类
a.实体类:Customer
package com.stx.po;
public class Customer {
private Integer id;//主键
private String username;//客户名称
private String jobs;//职业
private String phone;//电话
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getJobs() {
return jobs;
}
public void setJobs(String jobs) {
this.jobs = jobs;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", username='" + username + '\'' +
", jobs='" + jobs + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
b.测试类:MyBatisTest
package com.stx.test;
import com.stx.po.Customer;
import com.stx.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class MyBatisTest {
/*
* 根据客户姓名和职业组合条件查询客户信息表
* */
@Test
public void findCustomerByIdTest() throws Exception{
SqlSession sqlSession = MybatisUtils.getSession();
Customer customer = new Customer();
// customer.setUsername("jack");
// customer.setJobs("teacher");
List<Customer> customers = sqlSession.selectList("com.stx.mapper.CustomerMapper.findCustomerByNameAndJobs",customer);
for (Customer customer1 : customers){
System.out.println(customer1);
}
// 关闭SqlSession
sqlSession.close();
}
@Test
public void findCustomerByIdTests() throws Exception{
SqlSession sqlSession = MybatisUtils.getSession();
Customer customer = new Customer();
// customer.setUsername("jack");
// customer.setJobs("teacher");
List<Customer> customers = sqlSession.selectList("com.stx.mapper.CustomerMapper.findCustomerByNameAndJobs1",customer);
for (Customer customer1 : customers){
System.out.println(customer1);
}
// 关闭SqlSession
sqlSession.close();
}
@Test
public void updateCustomerByIdTests() throws Exception{
SqlSession sqlSession = MybatisUtils.getSession();
Customer customer = new Customer();
customer.setId(4);
customer.setPhone("13311111114");
int rows = sqlSession.update("com.stx.mapper.CustomerMapper.updateCustomer",customer);
if (rows>0){
System.out.println("您成功修改了"+rows+"条数据!");
}else {
System.out.println("值修改操作失败!");
}
// 提交事务
sqlSession.commit();
// 关闭SqlSession
sqlSession.close();
}
/*
* 使用了类似与JAVA里面for循环的查询结构:<foreach>查询结果。
* */
@Test
public void findCustomerByIdOneTest(){
SqlSession sqlSession = MybatisUtils.getSession();
// 创建List集合,封装查询ID。
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
// 把查询的数据封装到customers这个集合里面。然后遍历出来。
List<Customer> customers = sqlSession.selectList("com.stx.mapper.CustomerMapper.findCustomer",ids);
for (Customer customer:customers){
System.out.println(customer);
}
// 关闭事务。
sqlSession.close();
}
/*
* <bind>元素的使用:根据客户名模糊查询客户信息
* */
@Test
public void findCustomerByNameTwoTest(){
SqlSession sqlSession = MybatisUtils.getSession();
Customer customer = new Customer();
customer.setUsername("j");
// 执行SqlSession的查询方法,返回结果集。
List<Customer> customers = sqlSession.selectList("com.stx.mapper.CustomerMapper.findCustomerByName",customer);
for (Customer customer1:customers){
// 打印输出结果
System.out.println(customer1);
}
// 关闭SqlSession
sqlSession.close();
}
}
c.工具类:MybatisUtils
package com.stx.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.Reader;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory =null;
// 初始化SqlSessionFactory对象
static {
try {
// 使用MyBatis提供的Resources类加载MyBatis是配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// 构建SqlSessionFactory工厂
sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取SqlSession对象的静态方法。
public static SqlSession getSession() {
return sqlSessionFactory.openSession();
}
}
3、配置文件
a.数据外部引入文件:db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456
b.日志配置文件:log4j.properties
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.stx=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
#这个日志文件的主要目的是为了在:控制台输出Sql语句。作用是:输出日志信息。
c.配置文件:mybatis框架配置文件
<?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>
<!-- <!– 3.外部引入方法–>-->
<properties resource="db.properties"></properties>
<!-- 1.配置环境,默认的环境id为mysql-->
<environments default="mysql">
<!-- 1.2.配置id为mysql的数据库环境-->
<environment id="mysql">
<!-- 使用JDBC的事务管理器。-->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据库连接池-->
<!-- <dataSource type="POOLED">-->
<!-- <property name="driver" value="com.mysql.jdbc.Driver"/>-->
<!-- <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>-->
<!-- <property name="username" value="root"/>-->
<!-- <property name="password" value="123456"/>-->
<!-- </dataSource>-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 2.配置Mapper的位置。-->
<mappers>
<mapper resource="com/stx/mapper/CustomerMapper.xml"></mapper>
</mappers>
</configuration>
d.具体的SQL语句配置文件,即mapper,名为:CustomerMapper.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">
<!--!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"
1、这一段是MyBatis的约束配置。
-->
<!--2、以下是映射信息-->
<!--
动态SQL的元素。如果写了动态SQL传递了参数就会进行判断。否则就会只执行SQL语句,不会执行动态SQL。
-->
<mapper namespace="com.stx.mapper.CustomerMapper">
<select id="findCustomerByNameAndJobs" parameterType="com.stx.po.Customer" resultType="com.stx.po.Customer">
select * from t_customer where 1=1
<if test="username !=null and username !=''" >
and username like concat('%',#{username},'%')
</if>
<if test="jobs !=null and jobs!=''">
and jobs= #{jobs}
</if>
</select>
<!-- 使用了<choose>元素进行SQL拼接,当第一个<when>元素条件为真时,则只动态组装第一个<when>否则继续向下一个继续判断。都没有则执行<otherwise>-->
<select id="findCustomerByNameAndJobs1" parameterType="com.stx.po.Customer" resultType="com.stx.po.Customer">
select * from t_customer where 1=1
<choose>
<when test="username !=null and username !=''">
and username like concat('%',#{username},'%')
</when>
<when test="jobs !=null and jobs !=''">
and jobs=#{jobs}
</when>
<otherwise>
and phone is not null
</otherwise>
</choose>
</select>
<!-- 利用<set>标签进行更行数据,最后一个逗号会被自行省略。-->
<select id="updateCustomer" parameterType="com.stx.po.Customer">
update t_customer
<set>
<if test="username !=null and username !=''">
username=#{username},
</if>
<if test="jobs !=null and jobs !=''">
jobs=#{jobs},
</if>
<if test="phone !=null and phone !=''">
phone=#{phone},
</if>
</set>
where id=#{id}
</select>
<!-- <foreach> 进行遍历数据-->
<!-- item:配置的是当前循环中是当前的元素
index:配置的是当前元素在集合的位置下标。
collection:配置的是list是传递过来的参数类型(首字母小写),
它可以是一个array,list(或collection),Map集合的键,pojo包装类中的数组或者集合类型的属性名等。
open和close:配置的是以什么符号将这些集合元素包装起来。
separator:配置的是各个元素间隔符。-->
<select id="findCustomer" parameterType="List" resultType="com.stx.po.Customer">
select * from t_customer where id in
<foreach collection="list" index="index" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- <bind>元素:解决${}SQL注入,MySql函数与Oracle的||不同数据库的拼接方式。-->
<select id="findCustomerByName" parameterType="com.stx.po.Customer" resultType="com.stx.po.Customer">
-- _parameter.getUsername()也可以直接写成传入的字段属性么名,即username
<bind name="pattern_username" value="'%'+_parameter.getUsername()+'%' "/>
select * from t_customer where username like #{pattern_username}
</select>
</mapper>