一、Mybatis
1. 搭建Mybatis开发环境
环境:
- idea
- maven构建工具
- mysql
- mybatis
1. 引入依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
</dependencies>
mysql版本注意:
- 驱动类driver-class-name
mysql5驱动类使用com.mysql.jdbc.Driver
mysql8驱动类使用com.mysql.cj.jdbc.Driver
- 连接url
mysql5版本: jdbc:mysql://localhost:3306/ssm
如果数据库没有设置编码,在尾部加上?useUnicode=true&characterEncoding=UTF-8
mysql8版本: jdbc:mysql://localhost:3306/ssm?serverTimeZone=UTC
maven注意:
打包方式为jar包
2. 创建数据库和实体类
数据库
实体类
package cn.chenmanman.pojo;
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private Character gender;
private String email;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + ''' +
", password='" + password + ''' +
", age=" + age +
", gender=" + gender +
", email='" + email + ''' +
'}';
}
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Character getGender() {
return gender;
}
public void setGender(Character gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User() {
}
public User(Integer id, String username, String password, Integer age, Character gender, String email) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
this.gender = gender;
this.email = email;
}
}
3. 创建核心配置文件
主要理解默认情况下核心配置文件中各标签的意义
核心配置文件的文件名一般为:mybatis-config.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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
- configuration: 配置标签,所有配置都会包含在这个标签内
- environments: 数据库连接环境,可以有多套环境在其内部,default设置的就是目前所使用的环境
- environment: 连接数据库的环境,可以有多个,id为每个环境的名字
- transactionManager: 事务管理器
- dataSource: 数据源,在这个标签内来设置driver, url, username, password属性
- mappers: 引入映射文件
- mapper: 映射文件路径
4. 创建mapper映射文件
需要知道mapper映射文件和mapper接口的两个一致、以及知道mapper映射文件的作用
(1)mapper映射文件的作用
用于编写对应mapper接口方法的sql
(2)mapper接口与映射文件的两个一致:
- mapper映射文件的namespace和mapper接口的全类名一致
- mapper接口中方法的名字和mapper映射文件的sql的id一致
mapper映射文件和接口的名字一般为: XxxMapper.xml / XxxMapper
(3)在核心配置文件中引入mapper接口
package cn.chenmanman.mapper;
import cn.chenmanman.pojo.User;
public interface UserMapper {
int insertUser();
}
<?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="cn.chenmanman.mapper.UserMapper">
<insert id="insertUser">
insert into user values(null, 'chenmanman', 'huanyuan', 18, '男', '1738352551@qq.com')
</insert>
</mapper>
5、测试添加用户功能
\
创建测试类
import cn.chenmanman.mapper.UserMapper;
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.io.IOException;
import java.io.InputStream;
public class UserMapperTest {
@Test
public void testInserUser() throws IOException {
// 获取核心配置文件的输入流
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder对象, 建造者模式,用于建造一个sqlSessionFactory工厂,来获取sqlSession对象来操作数据库.
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取SqlSessionFactory对象,工厂模式, 用于获取SqlSession对象来操作数据库
SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
// 用于获取SqlSession对象来操作数据库
SqlSession sqlSession = sessionFactory.openSession();
// 获取UserMapper的代理实现类对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用userMapper接口中的方法,实现添加用户信息的功能
int rows = userMapper.insertUser();
// 提交事务
sqlSession.commit();
// 关闭会话
sqlSession.close();
System.out.println("影响行数: " + rows);
}
}
6. 优化功能和加入日志库
优化功能:主要对会话进行设置自动提交事务
SqlSession sqlSession = sessionFactory.openSession(true);
使用的日志库: log4j
(1)引入依赖坐标
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
(2)创建log4j配置文件
log4j配置文件的名字必须为: log4j
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' >
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql"> <level value="debug" /></logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
(3)测试
执行之前的添加User功能
7. 源码验证以及日志级别
源码验证:
在调用mapper接口方法处设置断点,之后进入execute方法
它内部会将对应的映射文件中的sql封装为command对象
name为映射文件的namespace +sqlId
type为此sql的类型
通过获取它的类型来,执行相对于的方法。
这里是INSERT类型,因此会执行case INSERT的代码。
首先会获取它的参数
然后使用insert方法传递对应的namespace +sqlId和所具有的参数来得到结果。
日志级别
8. SqlSession工具类和添加修删用户功能
可以将SqlSession的获取封装到一个工具类中
package cn.chenmanman.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.IOException;
import java.io.InputStream;
public class SqlSessionUtil {
public static SqlSession getSqlSession() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder对象, 建造者模式,用于建造一个sqlSessionFactory工厂,来获取sqlSession对象来操作数据库.
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取SqlSessionFactory对象,工厂模式, 用于获取SqlSession对象来操作数据库
SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
return sessionFactory.openSession(true);
}
}
增加mapper接口和对应映射文件
package cn.chenmanman.mapper;
import cn.chenmanman.pojo.User;
public interface UserMapper {
int insertUser();
/**
* 修改用户信息
* */
int updateUser();
/**
* 删除用户
* */
int deleteUser();
}
<?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="cn.chenmanman.mapper.UserMapper">
<insert id="insertUser">
insert into user values(null, 'chenmanman', 'huanyuan', 18, '男', '1738352551@qq.com')
</insert>
<update id="updateUser">
update user set user.username = 'zhangsan', user.password = 'huanyuan1', user.age=22,user.gender='女',user.email='177777@qq.com' where user.id=2
</update>
<delete id="deleteUser">
delete from user where user.id = 3
</delete>
</mapper>
import cn.chenmanman.mapper.UserMapper;
import cn.chenmanman.utils.SqlSessionUtil;
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.io.IOException;
import java.io.InputStream;
public class UserMapperTest {
@Test
public void testInserUser() throws IOException {
// 获取核心配置文件的输入流
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder对象, 建造者模式,用于建造一个sqlSessionFactory工厂,来获取sqlSession对象来操作数据库.
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取SqlSessionFactory对象,工厂模式, 用于获取SqlSession对象来操作数据库
SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
// 用于获取SqlSession对象来操作数据库
SqlSession sqlSession = sessionFactory.openSession();
// 获取UserMapper的代理实现类对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用userMapper接口中的方法,实现添加用户信息的功能
int rows = userMapper.insertUser();
// 提交事务
sqlSession.commit();
// 关闭会话
sqlSession.close();
System.out.println("影响行数: " + rows);
}
@Test
public void testUpdateUser() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser();
}
@Test
public void testDeleteUser() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser();
}
}
9. 添加查询功能
需要注意:
- 查询的标签select,必须设置属性resultType或resultMap,用于设置实体类和数据库表的映射关系。
resultType: 自动映射,用于属性名和表中字段一致的情况
resultMap: 自定义映射,用于一对多或多对一或字段和属性不一致的情况
(1)查单条用户数据
package cn.chenmanman.mapper;
import cn.chenmanman.pojo.User;
import java.util.List;
public interface UserMapper {
int insertUser();
/**
* 修改用户信息
* */
int updateUser();
/**
* 删除用户
* */
int deleteUser();
User selectUserById();
}
<?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="cn.chenmanman.mapper.UserMapper">
<insert id="insertUser">
insert into user values(null, 'chenmanman', 'huanyuan', 18, '男', '1738352551@qq.com')
</insert>
<update id="updateUser">
update user set user.username = 'zhangsan', user.password = 'huanyuan1', user.age=22,user.gender='女',user.email='177777@qq.com' where user.id=2
</update>
<delete id="deleteUser">
delete from user where user.id = 3
</delete>
<select id="selectUserById" resultType="cn.chenmanman.pojo.User">
select * from user where id = 2
</select>
</mapper>
import cn.chenmanman.mapper.UserMapper;
import cn.chenmanman.pojo.User;
import cn.chenmanman.utils.SqlSessionUtil;
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.io.IOException;
import java.io.InputStream;
public class UserMapperTest {
@Test
public void testInserUser() throws IOException {
// 获取核心配置文件的输入流
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder对象, 建造者模式,用于建造一个sqlSessionFactory工厂,来获取sqlSession对象来操作数据库.
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取SqlSessionFactory对象,工厂模式, 用于获取SqlSession对象来操作数据库
SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
// 用于获取SqlSession对象来操作数据库
SqlSession sqlSession = sessionFactory.openSession();
// 获取UserMapper的代理实现类对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用userMapper接口中的方法,实现添加用户信息的功能
int rows = userMapper.insertUser();
// 提交事务
sqlSession.commit();
// 关闭会话
sqlSession.close();
System.out.println("影响行数: " + rows);
}
@Test
public void testUpdateUser() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser();
}
@Test
public void testDeleteUser() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser();
}
@Test
public void testSelectUserById() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectUserById();
System.out.println(user);
}
}
结果:
(2)查所有用户信息
package cn.chenmanman.mapper;
import cn.chenmanman.pojo.User;
import java.util.List;
public interface UserMapper {
int insertUser();
/**
* 修改用户信息
* */
int updateUser();
/**
* 删除用户
* */
int deleteUser();
User selectUserById();
List<User> selectAllUser();
}
<?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="cn.chenmanman.mapper.UserMapper">
<insert id="insertUser">
insert into user values(null, 'chenmanman', 'huanyuan', 18, '男', '1738352551@qq.com')
</insert>
<update id="updateUser">
update user set user.username = 'zhangsan', user.password = 'huanyuan1', user.age=22,user.gender='女',user.email='177777@qq.com' where user.id=2
</update>
<delete id="deleteUser">
delete from user where user.id = 3
</delete>
<select id="selectUserById" resultType="cn.chenmanman.pojo.User">
select * from user where id = 2
</select>
<select id="selectAllUser" resultType="cn.chenmanman.pojo.User">
select * from user
</select>
</mapper>
import cn.chenmanman.mapper.UserMapper;
import cn.chenmanman.pojo.User;
import cn.chenmanman.utils.SqlSessionUtil;
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.io.IOException;
import java.io.InputStream;
import java.util.List;
public class UserMapperTest {
@Test
public void testInserUser() throws IOException {
// 获取核心配置文件的输入流
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder对象, 建造者模式,用于建造一个sqlSessionFactory工厂,来获取sqlSession对象来操作数据库.
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取SqlSessionFactory对象,工厂模式, 用于获取SqlSession对象来操作数据库
SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
// 用于获取SqlSession对象来操作数据库
SqlSession sqlSession = sessionFactory.openSession();
// 获取UserMapper的代理实现类对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用userMapper接口中的方法,实现添加用户信息的功能
int rows = userMapper.insertUser();
// 提交事务
sqlSession.commit();
// 关闭会话
sqlSession.close();
System.out.println("影响行数: " + rows);
}
@Test
public void testUpdateUser() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser();
}
@Test
public void testDeleteUser() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser();
}
@Test
public void testSelectUserById() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectUserById();
System.out.println(user);
}
@Test
public void testSelectUserAll() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> user = mapper.selectAllUser();
System.out.println(user);
}
}
结果:
2.Mybatis核心配置文件
核心配置文件的标签顺序:
properties?,settings?,typeAliases?,typeHandlers?,
objectFactory?,objectWrapperFactory?,reflectorFactory?,
plugins?,environments?,databaseIdProvider?,mappers?\
- environments标签
作用: 用于设置多个连接数据库的环境
属性:
defalut: 默认使用的环境
- environment标签
作用: 用于设置某个具体的环境
属性:
id: 连接数据库环境的唯一标识,不能重复
- transactionManager标签
作用: 设置事务管理器
属性:
type:
作用: 设置事务的管理方式、
值: JDBC|MANAGED
JDBC: 表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事务的提交或回滚需要手动处理
MANAGED: 被管理
- dataSource标签
作用:设置数据源
属性:
type:
作用:设置数据源的类型
值有POOLED|UNPOOLED|JNDI
POOLED: 表示使用数据库连接池来缓存数据库连接
UNPOOLED: 表示不使用数据库连接池
JNDI: 表示使用上下文中的数据源
- properties标签
作用: 引入properties配置文件,引入之后可以使用${}来占位
- typeAliases标签
作用: 设置类型别名,里面可以设置很多类型的别名
- typeAlias标签
作用: 设置类型别名, 为具体的某个类型type, 设置别名alias
属性:
alias: 别名, 如果没填别名就是类名不分大小写
- package标签
作用: 设置类型的别名,以包为单位
属性:
name : 设置包
- mappers 标签
作用: 引入mapper映射文件,可以包含多个mapper标签和package标签
- mapper标签
作用: 引入mapper映射文件
属性:
class:使用映射器接口实现类的完全限定名
resource: 相对于类路径的资源引用
url: 使用完全限定资源占位符(url)
- package标签
作用: 指定包中的所有映射文件引入
属性:
name:
作用:mapper文件所在包
注意:
1、mapper接口所在的包要和映射文件所在的包一致
2、mapper接口要和映射文件的名字一致\