前言
Mybatis的使用主要分三个版本
- 基于原生接口的xml版本
- 基于mapper接口的xml版本
- 基于Java注解的版本
在实际开发中主要使用基于mapper接口的版本,本章学习主要记录基于原生接口的版本
创建数据库
DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of t_student
-- ----------------------------
INSERT INTO `t_student` VALUES (1, '马保国', '男', 44);
INSERT INTO `t_student` VALUES (2, '张三', '男', 20);
INSERT INTO `t_student` VALUES (3, '李四', '男', 30);
INSERT INTO `t_student` VALUES (4, '王五', '男', 40);
INSERT INTO `t_student` VALUES (5, '赵六', '男', 10);
INSERT INTO `t_student` VALUES (6, '孙七', '女', 35);
INSERT INTO `t_student` VALUES (7, '周八', '女', 20);
创建maven项目
导入pom依赖:
<dependencies>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--MySQL驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!--日志处理-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
编写实体类
/**
* @author: lxk
* @date: 2021/7/24 22:56
* @description: 学生实体类
* @modified By:
*/
public class Student {
private Integer id;
private String name;
private String sex;
private Integer age;
// get set 方法省略
}
创建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">
<?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">
<!-- id属性必须和上面的default一致 -->
<environment id="development">
<!--配置事务的类型-->
<transactionManager type="JDBC"/>
<!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 -->
<dataSource type="POOLED">
<!--配置连接数据库的4个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="mysql"/>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置,这个映射配置文件指的是每个业务独立的配置文件-->
<mappers>
<mapper resource="mapper/StudentMapper.xml"/>
</mappers>
</configuration>
- environments:配置当前环境,default属性有development(开发模式 默认)和work(工作模式)两种选择
- environment:配置environment定义的环境,可以配置多个运行环境,但每个SqlSessionFactory实例只能选择一个运行环境
- transactionManager:配置事务管理器类型,type属性有JDBC和MANAGED两种
JDBC使用JdbcTransactionFactory工厂生成的JdbcTranaction对象实现,以JDBC的方式进行数据库的提交回滚等操作,它依赖于从数据源得到的连接来管理事务范围
MANAGED使用ManagedTransactionFactory工厂生成的ManagedTransaction对象实现,它的提交和回滚不需要任何操作,而是把事务交给容器进行处理,默认情况下会关闭连接,可以修改closeConnection属性为false不默认关闭 - dataSource:配置数据源属性,type有UNPOOLED、POOLED和JNDI三种选择
UNPOOLED:采用非数据库池的管理方式,每次请求都会新建一个连接,并且用完后会关闭,所以性能并不高
POOLED:采用连接池的概念将数据库链接对象Connection起来,可以在初始化的时候创建多个连接,使用时直接从连接池获取,避免重复创建连接的时间,效率较高
JNDI:数据源JNDI的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI的上下文引用,生产环境优先考虑 - property:dataSource中的property元素就是数据库相关的配置信息
- mappers:用来存放mapper的标签
- mapper:映射文件资源位置,如下代码所示
<mappers>
<mapper resource="mapper/StudentMapper.xml">
</mappers>
SQL映射文件
- 命名空间用来设定当前配置文件的唯一标识,在Java程序中将通过namespace定位该配置文件,名字可以随便取,但是推荐用mapper的全类名
- id:sql映射语句的唯一标识,称为statement的id,将sql语句封装到mappedStatement对象中,所以将id称为statement的id
- parameterType: 指定输入参数类型
- resultType: 指定输出结果类型。Mybatis将sql查询结果的一行记录映射为resultType指定对象,如果有多条则分别映射最后放入Lise容器
- #{value}表示sql语句的占位符,相当于jdbc的?会自动进行jdbc类型和Java类型转换,不可以为空
- ${value}表示拼接字符串,会导致sql注入
<?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属性:表示命名空间,用来设定当前Mapper配置文件的唯一标识,将来在Java程序中通过namespace属性的值来定位到这个配置文件 -->
<mapper namespace="com.th.entity.Student">
<!-- 查询所有学生 -->
<select id="selectAllStudent" resultType="com.th.entity.Student">
select * from t_student;
</select>
<!-- 通过Id查询一个学生 -->
<select id="selectStudentById" parameterType="int" resultType="com.th.entity.Student">
select * from t_student where id = #{id};
</select>
<!-- 模糊查询,根据name字段查询学生-->
<select id="selectStudentByName" parameterType="int" resultType="com.th.entity.Student">
select * from t_student where s_name like '%${value}%';
</select>
<!-- 添加学生-->
<insert id="insertStudent" parameterType="com.th.entity.Student">
insert into t_student(s_name, age, sex)
values (#{s_name}, #{age}, #{sex});
</insert>
<!-- 根据Id更新学生 -->
<update id="updateStudent" parameterType="com.th.entity.Student">
update t_student set s_name = #{s_name},
age = #{age},sex = #{sex} where id = #{id};
</update>
<!-- 根据Id删除学生 -->
<delete id="deleteStudent" parameterType="int">
delete from t_student where id = #{id};
</delete>
</mapper>
加载映射文件
<!--指定映射配置文件的位置,这个映射配置文件指的是每个业务独立的配置文件-->
<mappers>
<mapper resource="mapper/StudentMapper.xml"/>
</mappers>
日志与测试类
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=F:/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
package com.th.test;
/**
* @author: lxk
* @date: 2021/7/24 22:57
* @description: Mybatis测试类
* @modified By:
*/
import com.th.entity.Student;
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 java.io.InputStream;
import java.util.List;
/**
* Mybatis的测试
*/
/**
* Mybatis的测试
*/
public class MybatisTest {
//定义 SqlSession
SqlSession sqlSession = null;
@Before
public void getSqlSession() {
//加载 mybatis 全局配置文件
InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
//创建 SqlSessionFactory 对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//根据 sqlSessionFactory 产生 session
sqlSession = sqlSessionFactory.openSession();
}
//查询所有用户数据
@Test
public void testSelectAllStudent() {
/**
* 注意:这个字符串由 UserMapper.xml 文件中的两个部分构成(namespace + id)
* <mapper namespace="com.thr.mapper.UserMapper">中 namespace 的值
* <select id="selectAllUser" > 中的 id 值
* 这样Mybatis才能找到需要的SQL
*/
String statement = "com.th.entity.Student.selectAllStudent";
List<Student> listStudent = sqlSession.selectList(statement);
for (Student student : listStudent) {
System.out.println(student.toString());
}
sqlSession.close();
}
//根据Id查询一个用户数据
@Test
public void testSelectStudentById() {
String statement = "com.th.entity.Student.selectStudentById";
Student student = sqlSession.selectOne(statement, 1);
System.out.println(student.toString());
sqlSession.close();
}
//模糊查询:根据 user 表的username字段
@Test
public void testSelectStudentByName() {
String statement = "com.th.entity.Student.selectStudentByName";
List<Student> listStudent = sqlSession.selectList(statement, "三");
for (Student student : listStudent) {
System.out.println(student.toString());
}
sqlSession.close();
}
//添加一个用户数据
@Test
public void testInsertStudent() {
String statement = "com.th.entity.Student.insertStudent";
Student user = new Student();
user.setS_name("张三丰");
user.setAge(34);
user.setSex("男");
int i = sqlSession.insert(statement, user);
System.out.println( (i>0)? "添加成功!":"添加失败!");
//提交插入的数据
sqlSession.commit();
sqlSession.close();
}
//根据Id修改用户数据
@Test
public void testUpdateStudent(){
//如果设置的 id不存在,那么数据库没有数据更改
String statement = "com.th.entity.Student.updateStudent";
Student user = new Student();
user.setId(3);
user.setS_name("王红");
user.setAge(26);
user.setSex("女");
int i = sqlSession.update(statement, user);
System.out.println( (i>0)? "修改成功!":"修改失败!");
//提交数据
sqlSession.commit();
sqlSession.close();
}
//根据Id删除用户数据
@Test
public void testDeleteStudent(){
String statement = "com.th.entity.Student.deleteStudent";
int i = sqlSession.delete(statement, 4);
System.out.println( (i>0)? "删除成功!":"删除失败!");
sqlSession.commit();
sqlSession.close();
}
}