1 概述
1.1 简介
开源免费框架,原名叫iBatis,2010年google code,2013年迁移到github,其是数据层访问框架,本质上是对JDBC的封装;
其优点是不需要写实现类,只需要写需要执行的sql命令即可。
1.2 环境搭建
1.2.1 Jar包
需要的Jar包:
1.2.2 全局配置文件
没有名称和地址要求;
在全局配置文件中引入DTD或者Schema
如果导入dtd后没有提示:
Window-->preference-->XML-->XML catalog-->add 按钮
- 全局属性
(1) 事务管理 transactionManager
事务Type的取值有:
JDBC: 事务管理使用JDBC原生事务管理模式
MANAGED: 事务管理转交给其他容器
(2)数据源 database
数据源Type的属性为:
POOLED: 使用数据库连接池
UNPOOLED: 不使用数据库连接池,和直接使用JDBC一样
JNDI: Java命名目录接口技术
在高频率访问数据库时,使用数据库连接池可以降低服务器系统压力,提升程序运行效率。
1.2.3 测试数据
create database ssm default character set utf8;
use ssm;
create table flower (
id int(10) primary key auto_increment comment 'ID',
name varchar(30) not null comment '花名',
price float not null comment '价格',
production varchar(30) not null comment '产地'
);
insert into flower values(default, '矮牵牛', 2.5, '南美阿根廷');
insert into flower values(default, '百日草', 5.0, '墨西哥');
insert into flower values(default, '半枝莲', 4.3, '巴西');
1.3 路径
1.3.1 路径分类
相对路径:从当前资源出发找到其他资源的过程;
绝对路径:从根目录(服务器根目录或项目根目录)出发找其他资源的过程,只要是/开头的都是绝对路径;
1.3.2 绝对路径
- 请求转发
/表示项目根目录(WebContent)
- 请求重定向
/表示的是服务器根目录(tomcat/webapps文件夹),故请求转发转为重定向时,需要加上项目前缀。
2 初探
2.1 pojo类
package com.ruanshubin.pojo;
public class Flower {
private int id;
private String name;
private double price;
private String production;
public Flower(int id, String name, double price, String production) {
super();
this.id = id;
this.name = name;
this.price = price;
this.production = production;
}
public Flower() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getProduction() {
return production;
}
public void setProduction(String production) {
this.production = production;
}
@Override
public String toString() {
return "Flower [id=" + id + ", name=" + name + ", price=" + price + ", production=" + production + "]";
}
}
2.2 mapper类
2.3 test类
package com.ruanshubin.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
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 com.ruanshubin.pojo.Flower;
public class Test {
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
// 使用工厂设计模式
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// 创建Session
SqlSession session = factory.openSession();
// 查询所有
List list = session.selectList("a.b.selAll");
for(Flower flower: list) {
System.out.println(flower);
}
// 查询数据条数
int total = session.selectOne("a.b.selCount");
System.out.println(total);
// 根据ID选择
Flower flower = session.selectOne("a.b.selById", 1);
System.out.println(flower);
// Map
Map
2.4 3种查询方式
- selectList()
适用于查询结果都需要遍历的需求。
- selectOne()
适用于返回结果只是变量或单行数据。
- selectMap
适用于需要在查询结果中通过某列的值取到这行数据的需求。
3 进阶
use ssm;
create table people(
id int(10) primary key auto_increment comment '编号',
name varchar(20) comment '姓名',
age int(3) comment '年龄'
) comment '人员信息表';
insert into people values(default, '张三', 21);
insert into people values(default, '李四', 22);
3.1 全局配置
3.1.1 在mybatis.xml中开启log4j
(1) 必须保证有log4j.jar;
(2) 在src下有log4j.properties
log4j.rootCategory=ERROR, CONSOLE ,LOGFILE
log4j.logger.a.b=DEBUG
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%C %p %m %n
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=E:/my.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%C %m %L %n
在MyBatis配置文件中添加:
3.1.2 类别名
typeAliases:
系统内置别名:把类型全小写
某个类别名
alias="自定义":
- 直接给某个包下所有类起别名,不区分大小写
3.2 实现增(insert)、删(delete)、改(update)、查(select)
- PeopleMapper.xml
insert into people values(default, #{name}, #{age})
update people set name = #{name} where id = #{id}
delete from people where id = #{0}
- PeopleTest.java
public class PeopleTest {
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
// 使用工厂设计模式
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// 创建Session
SqlSession session = factory.openSession();
/*HashMap map = new HashMap<>();
map.put("id", 1);
map.put("name", "张三");
People people = session.selectOne("a.j.selById", map);
System.out.println(people);
List list = session.selectList("a.j.test", 3);
for(People people1:list) {
System.out.println(people1);
}*/
/*HashMap map1 = new HashMap<>();
map1.put("pageStart", 1);
map1.put("pageSize", 5);
List list = session.selectList("a.j.page", map1);
for(People people:list) {
System.out.println(people);
}*/
// 插入数据
/*People people = new People();
people.setName("郭靖");
people.setAge(26);
try {
int index = session.insert("a.j.ins", people);
if(index>0) {
System.out.println("插入数据成功");
}else {
System.out.println("插入数据失败");
}
} catch (Exception e) {
e.printStackTrace();
session.rollback();
}
session.commit();*/
// 更新数据
/*People people = new People();
people.setId(8);
people.setName("黄蓉");
int index = session.update("a.j.upd", people);
if(index>0) {
System.out.println("更新数据成功");
}else {
System.out.println("更新数据失败");
}
session.commit();*/
// 删除数据
/*int index = session.delete("a.j.del", 8);
if(index>0) {
System.out.println("删除数据成功");
}else {
System.out.println("删除数据失败");
}
session.commit();*/
}
}
- 自动提交
MyBatis默认是关闭了JDBC的自动提交事务的功能,需要主动调用:
session.commit()
或者:
openSession(True);
- 增、删、改
(1)JDBC中executeUpdate()执行新增、删除、修改的SQL,其返回值为int,表示受影响的行数;
(2)mybatis中insert、delete、update标签没有resultType属性,认为返回值均是int。
- 事务回滚
在openSession()时MyBatis会创建SqlSession时同时创建一个Transaction(事务对象),同时autoCommit均为false,如果出现异常,执行session.rollback()回滚事务。
3.2 接口绑定方案及多参数传递
3.2.1 作用
(1)实现创建接口后把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获取mapper.xml中编写的sql;
(2)MyBatis和Spring整合时使用的是这个方案。
3.2.2 实现步骤
- 创建接口
接口包名和接口名与mapper.xml中的namespace相同;
接口中方法名和mapper.xml标签的id属性相同。
- 扫描接口
在MyBatis.xml中使用package进行扫描接口和mapper.xml
3.2.3 代码实现
- 在mybatis.xml中使用package
- 编写接口类
public interface PeopleMapper {
List selAll();
}
- 在com.ruanshubin.mapper下新建PeopleMapper.xml
(1) namespace必须和接口全限定路径一致;
(2) id值必须和接口中方法名相同;
(3) 如果接口中方法为多个参数,可以省略parameterType。
- 接口绑定
PeopleMapper mapper = session.getMapper(PeopleMapper.class);
List list = mapper.selAll();
3.2.4 多参数
- PeopleMapper.xml
- PeopleMapper.java
// 多参数查询
List selById(Integer id, String name);
- PeopleTest.java
// 多参数查询
List list = mapper.selById(1, "李四");
for(People people:list) {
System.out.println(people);
}
3.2.5 多参数(注解)
- PeopleMapper.xml
- PeopleMapper.java
// 多参数查询
List selById(@Param("id") int id, @Param("name") String name);
3.3 动态SQL
根据不同的条件需要执行不同的SQL命令,称为动态SQL。
3.3.1 if语句
3.3.2 where语句
比直接使用if少写where 1=1
3.3.3 choose语句
只要有一个成立,其他就不执行。
choose-->when otherwise
and id=#{id}
and name=#{name}
3.3.4 set语句
update people
id=#{id},
name=#{name},
where id=#{id}
防止set中没有内容,引起语法错误。
3.3.5 trim语句
- prefix 在前面添加内容
- prefixOverrides 去掉前面内容
- suffix 在后面添加内容
- suffixOverrides 去掉后面内容
3.3.6 foreach语句
3.3.7 sql和include
(1) 某些Sql片段如果希望服用,可以使用sql定义片段;
(2) 在select、delete、update、insert中使用include引用。
name, age
3.3.8 bind语句
给参数重新赋值,适用的场景为:
- 模糊查询
- 在原内容前或后添加内容
欢迎您扫一扫上面的二维码,关注我的微信公众号!
更多内容请访问http://ruanshubin.top.