Mybatis 学习总结(一)
1.什么是Mybatis
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
2.Mybatis下载使用
1.下载
https://github.com/mybatis/mybatis-3/releases
2.使用
- lib目录是Mybatis所依赖的第三方jar包
- mybatis-XXXX.jar是Mybatis是jar包
- 使用时, 导入所需的jar包即可, mybatis-XXXX.jar为必导
3.一个简单的入门例子
- 首先创建一个数据库
DROP DATABASE IF EXISTS mybatis;
CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8;
use mybatis;
CREATE TABLE student(
id int(11) NOT NULL AUTO_INCREMENT,
studentID int(11) NOT NULL UNIQUE,
name varchar(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO student VALUES(1,1,'我没有三颗心脏');
INSERT INTO student VALUES(2,2,'我没有三颗心脏');
INSERT INTO student VALUES(3,3,'我没有三颗心脏');
- 创建工程
创建一个工程, 引入mybatis-XXXX.jar和 mysql-connector-XXX.jar包
-
创建实体类
package pojo; public class Student { private int id; private int studentID; private String name; public Student() { } public Student(int id, int studentID, String name) { this.id = id; this.studentID = studentID; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getStudentID() { return studentID; } public void setStudentID(int studentID) { this.studentID = studentID; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
-
配置数据库配置文件, 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> <!-- 别名 --> <typeAliases> <package name="pojo"/> </typeAliases> <!-- 数据库环境 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 映射文件 --> <mappers> <mapper resource="pojo/StudentMapper.xml"/> </mappers> </configuration>
-
配置映射文件 StudentMapper.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="pojo"> <select id="listStudent" resultType="Student"> select * from student </select> <insert id="insertStudent"> INSERT INTO student VALUES(#{id},#{studentID},#{name}) </insert> <delete id="deleteStudent" parameterType="int"> DELETE FROM Student WHERE id=#{id} </delete> <update id="updateStudent"> UPDATE Student SET studentID=#{studentID}, NAME=#{name} WHERE id=#{id} </update> </mapper>
- 创建测试类
package test; 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 pojo.Student; import java.io.IOException; import java.io.InputStream; import java.util.List; public class TestMyBatis { public static void printStudentTable(List<Student> listStudent) { for (Student student : listStudent) { System.out.println("ID:" + student.getId() + ",NAME:" + student.getName()); } System.out.println("-----------------------"); } public static void main(String[] args) throws IOException { // 根据 mybatis-config.xml 配置的信息得到 sqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 然后根据 sqlSessionFactory 得到 session. 官方推荐如下写法, 保证session被及时关闭 try (SqlSession session = sqlSessionFactory.openSession()) { //[增] Student student = new Student(4, 4, "我没有三颗心脏"); session.insert("insertStudent", student); session.commit(); //[查] List<Student> studentList = session.selectList("listStudent"); printStudentTable(studentList); //[删] Student student1 = new Student(); student1.setId(4); session.delete("deleteStudent", student1); //这里sql中要动态插入的参数唯一, 所以也可以用以下语句 //session.delete("deleteteStudent", 4); session.commit(); studentList = session.selectList("listStudent"); printStudentTable(studentList); //[改] Student student2 = new Student(3, 4, "我没有四颗心脏"); session.update("updateStudent", student2); session.commit(); studentList = session.selectList("listStudent"); printStudentTable(studentList); } } }
-
运行结果
-
数据库结果
-
4.入门笔记
-
session.insert()必须带有一个id参数, 对应于StudentMapper.xml文件中配置的id, 决定了调用哪条sql语句
-
第二个参数可选, Object类型; 当sql语句中需要动态插入数据时, 即可通过这个参数动态填入.动态插入多项数据时, 推荐填入封装好的JavaBean, 单项参数时, 可以直接传入那项数据
-
delete(), select(), update()方法均有以上规则, 后不赘述.
-
默认情况下, 执行insert(), delete(), update()方法后是不会立即提交到数据库,需要手动执行commit()方法后, 才会执行
-
作用域(Scope)和生命周期
SqlSessionFactoryBuilder
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
SqlSessionFactory
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。 这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。 下面的示例就是一个确保 SqlSession 关闭的标准模式:
try (SqlSession session = sqlSessionFactory.openSession()) { // 你的应用逻辑代码 }
-
mapper.xml配置的一些注意的点
- resultType 只写一个, 即返回类型为集合时, 只写该集合对应的泛型, 而不是写集合的类型, 对应于例子就是写Student, 而不是
List<Student>
- parameterType 只写一个, 普通类型(8个基本类型+String)直接写, 其他类型的组合需要封装成对象.
- 参数封装成javaBean时, sql中的#{key}需要和bean类型中的参数名对应, 允许bean中参数为空(即可以只赋值一部分数据, 不用都赋值)
- resultType 只写一个, 即返回类型为集合时, 只写该集合对应的泛型, 而不是写集合的类型, 对应于例子就是写Student, 而不是