什么是Mybatis
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。Mybatis架构图
- mybatis-config.xml是Mybatis的核心配置文件,通过其中的配置可以生成SqlSessionFactory,也就是SqlSession工厂
- 基于SqlSessionFactory可以生成SqlSession对象
- SqlSession是一个既可以发送SQL去执行,并返回结果,类似于JDBC中的Connection对象,也是Mybatis中至关重要的一个对象。
- Executor是SqlSession底层的对象,用于执行SQL语句
- MapperStatement对象也是SqlSession底层的对象,用于接收输入映射(SQL语句中的参数),以及做输出映射(即将SQL查询的结果映射成相应的结果)
Mybatis入门
- 创建maven的java工程
2.在pom.xml文件中添加所需依赖
<dependencies>
<!-- junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!-- 整合log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>
3.在src/main/resource目录下创建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">
<!-- MyBatis的全局配置文件 -->
<configuration >
<!-- 1.配置环境,可配置多个环境(比如:develop开发、test测试) -->
<environments default="develop">
<environment id="develop">
<!-- 1.1.配置事务管理方式:JDBC/MANAGED
JDBC:将事务交给JDBC管理(推荐)
MANAGED:自己管理事务
-->
<transactionManager type="JDBC"></transactionManager>
<!-- 1.2.配置数据源,即连接池 JNDI/POOLED/UNPOOLED
JNDI:已过时
POOLED:使用连接池(推荐)
UNPOOLED:不使用连接池
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 2.导入Mapper配置文件,如果mapper文件有多个,可以通过多个mapper标签导入 -->
<mappers>
<mapper resource="EmpMapper.xml"/>
</mappers>
</configuration>
mybatis中的占位符
#{}占位符
相当于JDBC中的问号(?)占位符,是为SQL语句中的参数值进行占位,大部分情况下都是使用#{}占位符;并且当#{}占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行转义处理(在字符串或日期类型的值的两边加上单引号);${}占位符
- 是为SQL片段(字符串)进行占位,将传过来的SQL片段直接拼接在 ${} 占位符所在的位置,不会进行任何的转义处理。(由于是直接将参数拼接在SQL语句中,因此可能会引发SQL注入攻击问题)需要注意的是:使用 ${} 占位符为SQL语句中的片段占位时,即使只有一个占位符,需要传的也只有一个参数,也需要将参数先封装再传递!
4.在src/main/java目录下创建测试类和实体类
实体类
package com.pojo;
public class Emp {
private String name;
private Integer id;
private String job;
private Double salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Emp [name=" + name + ", id=" + id + ", iob=" + iob + ", salary=" + salary + "]";
}
}
在src/main/resources目录下,创建EmpMapper.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值应该保证唯一
在程序中通过[ namespace + id ]定位到要执行哪一条SQL语句
-->
<mapper namespace="EmpMapper">
<!-- 通过select、insert、update、delete标签声明要执行的SQL -->
<!-- 练习1: 查询emp表中的所有员工信息
resultType指定查询的结果将会封装到什么类型中
即使最终返回的结果是集合(List<Emp>),resultType也只需要指定集合中的泛型即可!
-->
<select id="findAll" resultType="com.pojo.Emp">
select * from emp
</select>
<!-- id为自增约束,所以设置为null -->
<insert id="insert">
insert into emp values(null,#{name},#{job},#{salary})
</insert>
<!-- 查询指定字段,可以为一个,也可以为多个
将需要查询的字段的名称放入map集合中,key为column,value为需要查询的字段名称。
在测试类中调用selectList方法,把map传递过来 -->
<select id="findByColumn" resultType="com.pojo.Emp">
select ${column} from emp
</select>
</mapper>
测试类
package com.mybatis;
import java.io.InputStream;
import java.util.List;
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 org.junit.Before;
import org.junit.Test;
import com.pojo.Emp;
public class TestMybatis {
SqlSession session=null;
@Before //在执行单元测试以前,获取session对象
public void requestSession() throws Exception {
// 1、读取配置文件信息
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
// 2、根据配置文件信息,创建SqlSessionFaction对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
// 3、创建SqlSession对象(事务默认不提交,提交需调用commit方法) 创建时,添加true的参数,将事务改为自动提交
session = factory.openSession(true);
}
@Test //查询表中所有信息
public void testFindAll() {
// 调用selectList方法,返回一个集合,将泛型指定为Emp类型
List<Emp> list = session.selectList("EmpMapper.findAll");
for (Emp emp : list) {
//因为Emp实体类重写了toString方法,直接打印即可
System.out.println(emp);
}
}
@Test //插入数据
public void testInsert() {
Emp emp = new Emp();
emp.setJob("Miss");
emp.setName("诸葛村夫");
emp.setSalary(4500.0);
int rows = session.insert("EmpMapper.insert", emp);
System.out.println("影响行数==="+rows);
}
@Test //查询指定字段
public void testFindByColumn() {
Map map = new HashMap();
map.put("column", "name,salary");
List<Emp> list = session.selectList("EmpMapper.findByColumn",map);
for (Emp emp : list) {
System.out.println(emp);
}
}
}
动态SQL标签
-
<if>
标签:是根据test属性
中的布尔表达式的值,从而决定是否执行包含在其中的SQL片段。如果判断结果为true,则执行其中的SQL片段;如果结果为false,则不执行其中的SQL片段 -
<where>
标签:用于对包含在其中的SQL片段进行检索,在需要时可以生成where关键字,并且在需要时会剔除多余的连接词(比如and或者or)
查询指定salary范围的信息
EmpMapper.xml
<select id="findBySal" resultType="com.pojo.Emp">
select *from emp
<where>
<if test="minSal != null">salary > #{minSal}</if>
<if test="maxSal != null">and salary < #{maxSal}</if>
</where>
</select>
测试类
@Test
public void testFindBySal() {
Map map = new HashMap();
map.put("maxSal", 5000);
map.put("minSal", 3500);
List<Emp> list = session.selectList("EmpMapper.findBySal",map);
for (Emp emp : list) {
System.out.println(emp);
}
}
foreach标签
foreach标签:可以对传过来的参数数组或集合进行遍历,以下是foreach标签上的各个属性介绍:
批量修改员工信息
EmpMapper.xml
<!-- 把id为2,4,6,8的员工的薪资加100 -->
<update id="updateByIds">
update emp set salary=salary+#{sal} where id in
<foreach collection="arr" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</update>
测试类
@Test
public void testUpdateByIds() {
Integer[] ids= {2,4,6,8};
Map map = new HashMap();
map.put("sal", 100);
map.put("arr", ids);
int rows = session.update("EmpMapper.updateByIds", map);
System.out.println("影响行数"+rows);
}