Mybatis介绍

MyBatis是一款优秀的持久层ORM框架,对JDBC繁琐操作进行封装。它采用简单的XML配置 + 接口方法的形式实现对数据库的增删改查,使得让程序员只关注sql本身

入门案例

目标

使用mybatis查询user表中的所有数据,并且将查询结果保存到List集合中

第一步:创建数据库表

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `user`(
uid INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(100) NOT NULL,
PASSWORD VARCHAR(50) NOT NULL,
email VARCHAR(50),
birthday DATE
);
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵四",'123456','nglszs@qq.com','1888-09-02');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵五",'123456','nglszw@qq.com','1889-09-03');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵六",'123456','nglszl@qq.com','1890-09-04');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵七",'123456','nglszq@qq.com','1891-09-05');

第二步:导入jar包

点击下载jar包

第三步:创建实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package cn.itcast.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer uid;
private String name;
private String password;
private String email;
private String birthday;//数据库中是Date类型,java中可以是Date,也可以是String类型
}

第四步:创建mybatis配置文件

在src或者resource目录创建映射文件,名字叫UserMapper.xml

1
2
3
4
5
6
7
8
<?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">
<!--namespace命名空间 可以认为是这个配置文件的标识-->
<mapper namespace="UserMapper">
<select id="selectAll" resultType="cn.itcast.domain.User">
SELECT * FROM `user`;
</select>
</mapper>

在src或者resources目录创建主配置文件,名字叫mybatis-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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>

<!--数据源环境-->
<environments default="developement">
<environment id="developement">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.254.128:3306/mysql03"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>


<!--加载映射文件-->
<mappers>
<mapper resource="UserMapper.xml"></mapper>
</mappers>
</configuration>

第五步:编写测试类

注意:

使用的是org.apache.ibatis包下的Resources类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package cn.itcast;

import cn.itcast.domain.User;
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.Test;

import java.text.SimpleDateFormat;

public class UserMapperTest {
@Test
public void selectAll() throws Exception{
/*1.读取配置文件并创建SqlSessionFactory*/
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));

/*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
SqlSession sqlSession = sqlSessionFactory.openSession();

/*
3.执行查询所有
第一参数:指的是sql语句的位置,使用namespace.statementId表示
*/

List<User> users =sqlSession.selectList("UserMapper.selectAll");
for (User user : users) {
System.out.println(user);
}

/*4.释放资源*/
sqlSession.close();
}
}

映射文件介绍

本案例中映射文件的名字叫UserMapper.xml

1
2
3
select 标签可以有id,parameterType,resultType属性
update,delete,insert标签只能有id和parameterType属性
如果SQL需要一个参数,parameterType可以是String,Integer,但是如果SQL中用到多个值,只能传入对象

img

主配置文件介绍

本案例中主配置文件的名字叫mybatis-config.xml

environments标签

数据库环境的配置,支持多环境配置

img

mapper标签

该标签的作用是加载映射的,加载方式有如下几种:

使用相对于类路径的资源引用,例如:

1
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>

使用映射器接口实现类的完全限定类名,例如:

1
<mapper class="org.mybatis.builder.AuthorMapper"/>

将包内的映射器接口实现全部注册为映射器,例如:

1
<package name="org.mybatis.builder"/>

properties标签

介绍

实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件

img

使用步骤

目的

把XML中的数据库配置抽取到properties配置文件中

第一步:在src或者resources目录添加配置文件,名字叫jdbc.properties

Properties

1
2
3
4
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.254.128:3306/mysql03
jdbc.username=root
jdbc.password=123456

第二步:在c3p0-config.xml配置文件中的configuration标签内引入jdbc.properties

1
<properties resource="jdbc.properties"></properties>

第三步:修改主配置文件中的数据库配置

1
2
3
4
5
6
7
8
9
10
11
12
<!--数据源环境-->
<environments default="developement">
<environment id="developement">
<transactionManager type="JDBC"></transactionManager>
<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>

typeAliases标签

效果展示

使用别名前

img

使用别名后

img

使用步骤

第一步:配置别名,在mybatis-config.xml配置文件中添加如下代码

1
2
3
4
5
6
7
<typeAliases>
<!--给指定类起别名,别名一般首字母小写-->
<typeAlias type="cn.itcast.domain.User" alias="user"></typeAlias>

<!--如果类比较多,可以指定包,通过扫包的方式给包中的所有类起别名-->
<package name="cn.itcast.domain"/>
</typeAliases>

第二步:使用别名,比如之前mapper中的查询全部的resultType的值由之前的全类名改为user

1
2
3
<select id="selectAll" resultType="user">
SELECT * FROM `user`;
</select>

内置的别名

1589723643236

settings标签

目标

配置log4j,在控制台输出日志信息,查看SQL语句

注意事项

该标签紧跟properties标签,否则报错

使用步骤

第一步:在主文件中配置log4j

1
2
3
<settings>
<setting name="logImpl" value="log4j"/>
</settings>

第二步:导入log4j.properties到resources目录

Properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

API介绍

Resources

在 org.apache.ibatis 包中

功能:读取配置文件,获取输入流,等价于XX.class.getClassloader().getResourcesAsStream(“xx.xml”);

返回值 方法名 说明
Reader static getResourceAsReader() 通过类加载器返回指定资源的字节输入流
InputStream static getResourceAsStream()

示例

1
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactoryBuilder

功能:解析配置文件,创建SqlSessionFactory对象

返回值 方法名 说明
SqlSessionFactory build(InputStream is) 解析配置文件得到工厂类

示例

1
2
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); 
SqlSessionFactory factory = new SqlSessionFactoryBuilder().builder.build(inputStream);

SqlSessionFactory

功能:获取SqlSession

方法 解释
openSession() 会默认开启一个事物,但事物不会自动提交,也就意味着需要手动提交该事物,增删改操作数据才会持久化到数据库中【如果仅仅是查询,不需要提交事务,用无参的】
openSession(boolean autoCommit) 参数为是否自动提交,如果设置为true,那么不需要手动提交事务【如果是增删改,需要提交事务,用有参的】

SqlSession

功能:执行SQL,管理事物、接口代理

返回值 方法名 说明
List selectList(String statement,Object parameter) 执行查询,返回List集合
T selectOne(String statement,Object parameter) 执行查询,返回一个结果对象
int insert(String statement,Object parameter) 执行新增,返回影响行数
int update(String statement,Object parameter) 执行更新,返回影响行数
int delete(String statement,Object parameter) 执行删除,返回影响行数
void commit() 提交事务
void rollback() 回滚事物
T getMapper(Class clazz) 获取指定接口的代理实现类对象
void close() 释放资源

增删改查演示

查询多条记录

UserMapper.xml配置

1
2
3
<select id="selectAll" resultType="cn.itcast.domain.User">
SELECT * FROM `user`;
</select>

测试方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void selectAll() throws Exception {
/*1.读取配置文件并创建SqlSessionFactory*/
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

/*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
SqlSession sqlSession = sqlSessionFactory.openSession();

/*3.查询多条记录*/
List<User> users = sqlSession.selectList("UserMapper.selectAll");

/*4.释放资源*/
sqlSession.close();

/*测试查询结果*/
for (User user : users) {
System.out.println(user);
}
}

查询一条记录

UserMapper.xml

1
2
3
4
<!--#{} 中的名字可以随便写,但是为了可读性最好见名知意-->
<select id="selectOne" resultType="cn.itcast.domain.User" parameterType="int">
SELECT * FROM `user` WHERE uid = #{uid};
</select>

测试方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void selectOne() throws Exception {
/*1.读取配置文件并创建SqlSessionFactory*/
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

/*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
SqlSession sqlSession = sqlSessionFactory.openSession();

/*3.查询一条记录*/
User u = (User) sqlSession.selectOne("UserMapper.selectOne", 1);

/*4.释放资源*/
sqlSession.close();

/*测试查询结果*/
System.out.println(u);
}

新增一条记录

UserMapper.xml

1
2
3
4
5
6
7
8
9
<!--#{}中的值和cn.itcast.domain.User对象的属性名保持一致-->
<insert id="save" parameterType="cn.itcast.domain.User">
insert into `user` (name,password,email,birthday) values(
#{name},
#{password},
#{email},
#{birthday}
);
</insert>

测试方法

如果openSession(true)传入true表示自动提交事务,则不需要手动调用commit()方法提交事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Test
public void save() throws Exception {
/*1.读取配置文件并创建SqlSessionFactory*/
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

/*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
SqlSession sqlSession = sqlSessionFactory.openSession();

/*3.创建对象,并插入到数据库*/
User u = new User(null, "tom", "123456", "123@qq.com", "2016-09-08");
int count = sqlSession.insert("UserMapper.save", u);

/*4.提交事务*/
sqlSession.commit();

/*5.释放资源*/
sqlSession.close();

/*测试查询结果*/
System.out.println("共"+count+"行收到影响");
}

更新一条记录

UserMapper.xml

1
2
3
4
5
<!--#{}中的值和cn.itcast.domain.User对象的属性名保持一致-->
<update id="update" parameterType="cn.itcast.domain.User">
update `user` set name = #{name}, email = #{email}, birthday = #{birthday}
where uid = #{uid}
</update>

测试方法

如果openSession(true)传入true表示自动提交事务,则不需要手动调用commit()方法提交事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Test
public void update() throws Exception {
/*1.读取配置文件并创建SqlSessionFactory*/
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

/*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
SqlSession sqlSession = sqlSessionFactory.openSession();

/*3.创建对象,并更新到数据库*/
User u = new User(2, "TomCat", "123456", "123@qq.com", "2016-09-08");
int count = sqlSession.update("UserMapper.update", u);

/*4.提交事务*/
sqlSession.commit();

/*5.释放资源*/
sqlSession.close();

/*测试查询结果*/
System.out.println("共"+count+"行收到影响");
}

删除一条记录

UserMapper.xml

1
2
3
4
<!--#{} 中的名字可以随便写,但是为了可读性最好见名知意-->
<delete id="deleteByUid" parameterType="int">
delete from `user` where uid = #{uid}
</delete>

测试方法

如果openSession(true)传入true表示自动提交事务,则不需要手动调用commit()方法提交事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Test
public void delete() throws Exception {
/*1.读取配置文件并创建SqlSessionFactory*/
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

/*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
SqlSession sqlSession = sqlSessionFactory.openSession();

/*3.删除*/
int count = sqlSession.delete("UserMapper.deleteByUid", 3);

/*4.提交事务*/
sqlSession.commit();

/*5.释放资源*/
sqlSession.close();

/*测试查询结果*/
System.out.println("共"+count+"行收到影响");
}

基于传统方式实现dao层

第一步:在dao包创建接口

1
2
3
4
5
6
7
package cn.itcast.dao;

import cn.itcast.domain.User;

public interface UserDao {
void save(User u);
}

第二步:在dao.impl包创建实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package cn.itcast.dao.impl;

import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class UserDaoImpl implements UserDao {
public void save(User u) {
try {
/*1.读取配置文件并创建SqlSessionFactory*/
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));

/*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
SqlSession sqlSession = sqlSessionFactory.openSession();

/*
3.执行保存操作
第一参数:指的是sql语句的位置,使用namespace.statementId表示
第二参数:指的是sql语句需要的参数
*/

sqlSession.insert("save",u);

/*4.提交事务*/
sqlSession.commit();

/*5.释放资源*/
sqlSession.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

第三步:创建测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package cn.itcast;

import cn.itcast.dao.impl.UserDaoImpl;
import cn.itcast.domain.User;
import org.junit.Test;

import java.text.SimpleDateFormat;

public class UserMapperTest {
@Test
public void testSave()throws Exception{
//创建User对象
User user = new User(null, "jack", "123456", "110@qq.com", new SimpleDateFormat("yyyy-MM-dd").parse("2002-02-23"));
//调用dao保存数据
new UserDaoImpl().save(user);
}
}