Mybatis3 快速入門
目前常見的持久層java框架有Hibernate,Mybatis,SpringData。筆者比較喜歡用SpringData。Hibernate 和 Mybatis 也經常用。今天通過 Mybatis 的簡介,數據的增刪改查,表的級聯查詢,動態SQL語句 來快速入門 Mybatis 。
1 Mybatis 簡介
摘錄百度百科的內容:MyBatis 是一款優秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可以使用簡單的 XML 或注解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄
如果 Hibernate 是自動化持久層框架,那么 Mybatis 就是半自動化持久層框架。 半自動 ??? 聽起來好像 lower 了。其實不然,Mybatis 將 sql 和 java 分離開。讓專業的db工程師負責 sql 的優化,提高其性能,在高並發的場景,系統依然 穩如dog 。程序員可以把更多的精力放在業務邏輯上。
Mybatis:https://github.com/mybatis/mybatis-3/
2 Mybatis 快速入門
需求:使用 mybatis 框架完成數據的增刪改查操作,和級聯查詢,模糊查詢,調用存儲過程,使用mybatis的一二級緩存
技術:mybatis,maven
源碼:見文章底部
說明:本文內容屬於快速入門,通過手寫 xml 映射文件了解 mybatis 的工作原理。實際開發中,一般采用官方提供的逆向工程自動生成需要的 java 文件和 xml 文件
結構:

准備:
Mysql數據庫表結構

創建四張表,其中 person 獨立存在。classroom 和 student,teacher 存在主外鍵關系。
① classroom 的 student_id 和 student 的 class_id 存在主外鍵關系,並且是一對多的關系
② classroom 的 teacher_id 和 teacher 的 id 存在主外鍵關系,並且是一對一的關系
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for classroom -- ---------------------------- DROP TABLE IF EXISTS `classroom`; CREATE TABLE `classroom` ( `id` int(11) NOT NULL AUTO_INCREMENT, `room` varchar(255) DEFAULT NULL, `teacher_id` int(11) DEFAULT NULL, `student_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `c_t_id` (`teacher_id`), KEY `c_s_id` (`student_id`), CONSTRAINT `c_t_id` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`) ON DELETE SET NULL ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of classroom -- ---------------------------- INSERT INTO `classroom` VALUES ('1', 'JavaEE', '1', '1'); INSERT INTO `classroom` VALUES ('2', 'Linux', '2', '2'); -- ---------------------------- -- Table structure for person -- ---------------------------- DROP TABLE IF EXISTS `person`; CREATE TABLE `person` ( `id` int(11) NOT NULL AUTO_INCREMENT, `email` varchar(255) DEFAULT NULL, `last_name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of person -- ---------------------------- INSERT INTO `person` VALUES ('1', 'lxl@qq.com', 'lxl'); INSERT INTO `person` VALUES ('2', 'cyy@qq.com', 'cyy'); INSERT INTO `person` VALUES ('3', 'itdrgon@qq.com', 'itdragon'); INSERT INTO `person` VALUES ('4', 'java@qq.com', 'java'); -- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `class_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `s_c_id` (`class_id`), CONSTRAINT `s_c_id` FOREIGN KEY (`class_id`) REFERENCES `classroom` (`student_id`) ON DELETE SET NULL ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES ('1', 'ITDragon', '1'); INSERT INTO `student` VALUES ('2', 'Marry', '1'); INSERT INTO `student` VALUES ('3', 'XiaoMing', '2'); -- ---------------------------- -- Table structure for teacher -- ---------------------------- DROP TABLE IF EXISTS `teacher`; CREATE TABLE `teacher` ( `id` int(11) NOT NULL AUTO_INCREMENT, `subject` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of teacher -- ---------------------------- INSERT INTO `teacher` VALUES ('1', 'Java'); INSERT INTO `teacher` VALUES ('2', 'Docker');
Maven 項目的核心文件 pom.xml (有些不是必要的,后續做整合會用到)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.itdragon.mybatis</groupId> <artifactId>mybatis-basic</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <commons-lang3.version>3.3.2</commons-lang3.version> <commons-io.version>1.3.2</commons-io.version> <commons-net.version>3.3</commons-net.version> <junit.version>4.12</junit.version> <slf4j.version>1.6.4</slf4j.version> <mybatis.version>3.2.8</mybatis.version> <mybatis.spring.version>1.2.2</mybatis.spring.version> <mybatis.paginator.version>1.2.15</mybatis.paginator.version> <mysql.version>5.1.6</mysql.version> <druid.version>1.0.9</druid.version> </properties> <dependencies> <!-- Apache工具組件 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> </dependency> <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>${commons-net.version}</version> </dependency> <!-- 單元測試 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- 日志處理 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <!-- Mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis.spring.version}</version> </dependency> <dependency> <groupId>com.github.miemiedev</groupId> <artifactId>mybatis-paginator</artifactId> <version>${mybatis.paginator.version}</version> </dependency> <!-- MySql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!-- 連接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> </dependencies> </project>
Mybatis 的配置文件 SqlMapConfig.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> <!-- 標簽必須按順序寫,否則會提示錯誤:The content of element type "configuration" must match "(properties?,settings?,...)". --> <!-- 引入配置文件 --> <properties resource="db.properties" /> <!-- 配置實體類的別名 --> <typeAliases> <!-- 給指定包取別名,別名為實體類對應的簡單類名,如 com.itdragon.pojo.Person 的別名就是 Person --> <package name="com.itdragon.pojo" /> </typeAliases> <!-- 配置數據庫鏈接 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <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> <!-- 注冊映射文件 --> <mappers> <mapper resource="com/itdragon/mapper/PersonMapper.xml" /> <mapper resource="com/itdragon/mapper/ClassroomMapper.xml" /> </mappers> </configuration>
數據庫的配置文件 db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/jpa?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
到這里准備工作就做完了。
3 數據的增刪改查
Person.java 實體類
package com.itdragon.pojo; // 學習 mybatis crud 實體類 public class Person { private Integer id; private String email; private String lastName; // 這里lastName 在數據庫中對應的是 last_name, 這會出現:字段名與實體類屬性名不相同的沖突問題 public Person() { } public Person(Integer id, String email, String lastName) { this.id = id; this.email = email; this.lastName = lastName; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email == null ? null : email.trim(); } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName == null ? null : lastName.trim(); } @Override public String toString() { return "Person [id=" + id + ", email=" + email + ", lastName=" + lastName + "]"; } }
PersonMapper.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="com.itdragon.mapper.PersonMapper"> <!-- CRUD 操作 --> <!-- 基礎知識: select 查詢數據 insert 插入數據 delete 刪除數據 update 更新數據 namespace 命名空間 id 方法名, 命名空間 + 方法名 = 唯一方法 parameterType 傳入參數類型 resultType 返回值類型 resultMap 以鍵值對的類型返回結果 參數傳值:#{xxx} parameterType 如果不是實體類,對應的參數名可以自定義。如 #{id} 也可以是 #{xxxx} 如果是實體類,對應的參數名必須是實體類屬性名。為了避免錯誤,盡量全部都用屬性名。 擴展知識: resultType 的值是 com.itdragon.pojo.Person 全類名,但為了方便,可以考慮使用別名 resultMap 為了避免類似 lastName 和 last_name 沖突,導致查詢的 last_name 會是 null 問題,可以設置鍵值關系 --> <select id="getPersonById" parameterType="int" resultType="com.itdragon.pojo.Person"> select * from person where id=#{id} </select> <!-- 解決字段名與實體類屬性名不相同的沖突問題第一種辦法(不推薦) --> <select id="getPersonByIdOne" parameterType="int" resultType="com.itdragon.pojo.Person"> select id, email, last_name lastName from person where id=#{id} </select> <select id="getPersonByIdTwo" parameterType="int" resultMap="getPersonMap"> select * from person where id=#{id} </select> <!-- 使用 resultMap 設置沖突字段名和實體類屬性名對應關系,(推薦) --> <resultMap type="Person" id="getPersonMap"> <result property="lastName" column="last_name" /> </resultMap> <!-- parameterType 中直接使用了 Person 是因為在 SqlMapConfig.xml 文件中設置了別名 --> <insert id="createPerson" parameterType="Person"> insert into person(email, last_name) values(#{email}, #{lastName}) </insert> <delete id="deletePersonById" parameterType="int"> delete from person where id=#{id} </delete> <update id="updatePersonById" parameterType="Person"> update person set email=#{email}, last_name=#{lastName} where id=#{id} </update> <select id="getAllperson" resultType="Person"> select * from person </select> </mapper>
測試方法:
package com.itdragon.test; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import com.itdragon.pojo.Classroom; import com.itdragon.pojo.Person; public class MyBatisTest { public SqlSession getSqlSession() { String resource = "SqlMapConfig.xml"; InputStream is = MyBatisTest.class.getClassLoader().getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); SqlSession session = factory.openSession(true); // false 默認手動提交, true 自動提交 return session; } // crud 操作 @Test public void getPersonById() { String statement = "com.itdragon.mapper.PersonMapper.getPersonById"; Person person = getSqlSession().selectOne(statement, 2); System.out.println(person); statement = "com.itdragon.mapper.PersonMapper.getPersonByIdOne"; person = getSqlSession().selectOne(statement, 2); System.out.println(person); statement = "com.itdragon.mapper.PersonMapper.getPersonByIdTwo"; person = getSqlSession().selectOne(statement, 2); System.out.println(person); } @Test public void getAllperson() { String statement = "com.itdragon.mapper.PersonMapper.getAllperson"; List<Person> persons = getSqlSession().selectList(statement); System.out.println(persons); } @Test public void createPerson() { String statement = "com.itdragon.mapper.PersonMapper.createPerson"; int result = getSqlSession().insert(statement, new Person(3, "itdragon@qq.com", "ITDragon")); System.out.println(result); } @Test public void updatePersonById() { String statement = "com.itdragon.mapper.PersonMapper.updatePersonById"; int result = getSqlSession().update(statement, new Person(4, "itdragon@qq.com", "ITDragon博客")); System.out.println(result); } @Test public void deletePersonById() { String statement = "com.itdragon.mapper.PersonMapper.deletePersonById"; int result = getSqlSession().delete(statement, 4); System.out.println(result); } }
4 級聯查詢
為了滿足一對一和一對多的級聯操作,新增三個實體類,分別是 Classroom(教室),Teacher(老師),Student(學生)
Classroom 和 Teacher 是一對一的關系,Classroom 和 Student 是一對多的關系
package com.itdragon.pojo; import java.io.Serializable; import java.util.List; // 學習 表的關聯關系所用字段,一個教室關聯一個老師(一對一),一個教室關聯一群學生(一對多) public class Classroom implements Serializable { private Integer id; private String room; private Teacher teacher; private List<Student> students; public Classroom() { } public Classroom(Integer id, String room, Teacher teacher, List<Student> students) { this.id = id; this.room = room; this.teacher = teacher; this.students = students; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getRoom() { return room; } public void setRoom(String room) { this.room = room; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } public List<Student> getStudents() { return students; } public void setStudents(List<Student> students) { this.students = students; } @Override public String toString() { return "Classroom [id=" + id + ", room=" + room + ", teacher=" + teacher + ", students=" + students + "]"; } }
package com.itdragon.pojo; import java.io.Serializable; public class Teacher implements Serializable{ private Integer id; private String subject; public Teacher() { } public Teacher(Integer id, String subject) { this.id = id; this.subject = subject; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } @Override public String toString() { return "Teacher [id=" + id + ", subject=" + subject + "]"; } }
package com.itdragon.pojo; import java.io.Serializable; public class Student implements Serializable { private Integer id; private String name; public Student() { } public Student(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + "]"; } }
ClassroomMapper.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="com.itdragon.mapper.ClassroomMapper"> <!-- 關聯表查詢 --> <!-- 基礎知識: association:用於一對一的關聯查詢 property:對象的屬性名 javaType:對象的類型 column:對應數據表中外鍵 select:使用另外一個查詢的封裝結果 collection:用於一對多的關聯查詢 ofType:指定集合對象的類型 --> <!-- 需求:通過 id 查詢 classroom, 並打印 teacher 信息 嵌套查詢:通過執行另外一個SQL映射語句來返回預期的復雜類型 第一步:先查詢 classroom SELECT * FROM classroom WHERE id=?; 第二步:再查詢 teacher SELECT * FROM teacher WHERE id=classroom.id //classroom 是第一步的查詢結果 說明:嵌套查詢的方法,雖然好理解,當時不建議 --> <select id="getClassroomById" parameterType="int" resultMap="getClassroomMap"> SELECT * FROM classroom WHERE id=#{id} </select> <select id="getTeacherById" parameterType="int" resultType="Teacher"> SELECT * FROM teacher WHERE id=#{id} </select> <resultMap type="Classroom" id="getClassroomMap"> <association property="teacher" column="teacher_id" select="getTeacherById"> <!-- 如果 teacher 存在屬性字段和字段沖突,需要在這里設置 --> </association> </resultMap> <!-- 需求:通過 id 查詢 classroom, 並打印 teacher 信息 嵌套結果:使用嵌套結果映射來處理重復的聯合結果的子集,封裝聯表查詢的數據(去除重復的數據) select * from classroom, teacher where classroom.teacher_id=teacher.id and classroom.id=? --> <select id="getClassroom2ById" parameterType="int" resultMap="getClassroom2Map"> SELECT * FROM classroom c, teacher WHERE c.teacher_id = teacher.id AND c.id = #{id} </select> <resultMap type="Classroom" id="getClassroom2Map"> <id property="id" column="id"/> <result property="room" column="room"/> <association property="teacher" javaType="Teacher"> <id property="id" column="id"/> <result property="subject" column="subject"/> </association> </resultMap> <!-- 需求:通過 id 查詢 classroom, 並打印 teacher 和 student 信息 嵌套查詢:通過執行另外一個SQL映射語句來返回預期的復雜類型 第一步:先查詢 classroom SELECT * FROM classroom WHERE id=?; 第二步:再查詢 teacher SELECT * FROM teacher WHERE id=classroom.id //classroom 是第一步的查詢結果 第三步:再查詢 student SELECT * FROM student WHERE id=classroom.id //classroom 是第一步的查詢結果 --> <select id="getClassroom3ById" resultMap="getClassroom3Map"> SELECT * FROM classroom WHERE id=#{id} </select> <!-- getTeacherById 上面有了,就不重復寫了 --> <select id="getStudentById" parameterType="int" resultType="Student"> SELECT * FROM student WHERE class_id=#{id} </select> <resultMap type="Classroom" id="getClassroom3Map"> <association property="teacher" column="teacher_id" select="getTeacherById"></association> <collection property="students" column="student_id" select="getStudentById"></collection> </resultMap> <!-- 需求:通過 id 查詢 classroom, 並打印 teacher 和 student 信息 嵌套結果:使用嵌套結果映射來處理重復的聯合結果的子集,封裝聯表查詢的數據(去除重復的數據) SELECT * FROM classroom c, teacher t,student s WHERE c.teacher_id=t.id AND c.id=s.class_id AND c.id=? --> <select id="getClassroom4ById" parameterType="int" resultMap="getClassroom4Map"> SELECT * FROM classroom c, teacher t, student s WHERE c.teacher_id=t.id AND c.student_id=s.class_id AND c.id=#{id} </select> <resultMap type="Classroom" id="getClassroom4Map"> <id property="id" column="id"/> <result property="room" column="room"/> <association property="teacher" javaType="Teacher"> <id property="id" column="id"/> <result property="subject" column="subject"/> </association> <collection property="students" ofType="Student"> <!-- 存在問題 如果兩表聯查,主表和明細表的主鍵都是id的話,明細表的多條只能查詢出來第一條。 <id property="id" column="s_id"/> 解決方法:https://www.cnblogs.com/junge/p/5145881.html --> <result property="name" column="name"/> </collection> </resultMap> </mapper>
測試方法:
// 關聯表的查詢 @Test public void getClassroomById() { String statement = "com.itdragon.mapper.ClassroomMapper.getClassroomById"; Classroom classroom = getSqlSession().selectOne(statement, 1); System.out.println(classroom); statement = "com.itdragon.mapper.ClassroomMapper.getClassroom2ById"; classroom = getSqlSession().selectOne(statement, 1); System.out.println(classroom); statement = "com.itdragon.mapper.ClassroomMapper.getClassroom3ById"; classroom = getSqlSession().selectOne(statement, 1); System.out.println(classroom); statement = "com.itdragon.mapper.ClassroomMapper.getClassroom4ById"; classroom = getSqlSession().selectOne(statement, 1); System.out.println(classroom); }
5 動態SQL語句
這里通過模糊查詢 Email 來了解動態SQL語句,在 PersonMapper.xml 中添加如下代碼
<!-- 動態SQL與模糊查詢 --> <!-- 需求:通過模糊查詢郵箱和指定id范圍查詢數據 動態SQL: if:判斷語句 <if test=''></if> where:去掉多余的 and 和 or <where><if test=''>AND xxx</if></where> set:去掉多余的 "," <set><if test=''>xxx , </if></set> trim: 代替 where , set if + where == <trim prefix="WHERE" prefixOverrides="AND |OR "></trim> if + set == <trim prefix="SET" suffixOverrides=","></trim> choose: (when, otherwise) 類似java的switch case default <choose><when test="">xxx</when><otherwise>xxx</otherwise></choose> foreach:類似java的加強for循環 <foreach collection="array" item="xxx" open="(" separator="," close=")"></foreach> 說明:mybatis 提供了自動生成的逆向工程的工具,這里只需要了解即可,雖然是很重要的知識點 學習博客:http://limingnihao.iteye.com/blog/782190 --> <select id="getPersonLikeKey" parameterType="Person" resultMap="getPersonMap"> select * from person where <if test='email != "%null%"'> email like #{email} and </if> id > #{id} </select>
測試方法:
// 調用存儲過程 @Test public void getPersonCountGtId(){ String statement = "com.itdragon.mapper.PersonMapper.getPersonCountGtId"; Map<String, Integer> parameterMap = new HashMap<String, Integer>(); parameterMap.put("personId", 1); parameterMap.put("personCount", -1); getSqlSession().selectOne(statement, parameterMap); Integer result = parameterMap.get("personCount"); System.out.println(result); }
6 存儲過程
引用百度百科:存儲過程(Stored Procedure)是在大型數據庫系統中,一組為了完成特定功能的SQL 語句集,存儲在數據庫中,經過第一次編譯后再次調用不需要再次編譯,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象。
這里通過獲取大於Person id 數量的邏輯來了解Mybatis 是如何調用存儲過程的。首先在Mysql 命令行中執行一下代碼
#創建存儲過程 傳入Id的值,返回id大於該值的數量 DELIMITER $ #在 jpa 數據庫中,創建一個名為get_person_count的方法,傳入參數是person_id,返回參數是person_count CREATE PROCEDURE jpa.get_person_count(IN person_id INT, OUT person_count INT) BEGIN SELECT COUNT(*) FROM jpa.person WHERE person.id > person_id INTO person_count; END $ #調用存儲過程 DELIMITER ; SET @person_count = 0; CALL jpa.get_person_count(1, @person_count); SELECT @person_count;
打印結果如下,則說明創建成功了

還是在 PersonMapper.xml 文件中添加如下代碼
<!-- 調用存儲過程 --> <!-- 通過id,獲取大於該id的數量 CALL jpa.get_person_count(1, @person_count); 注意:需關閉二級緩存 Caching stored procedures with OUT params is not supported. Please configure useCache=false in ... --> <select id="getPersonCountGtId" parameterMap="getPersonCountMap" statementType="CALLABLE"> CALL jpa.get_person_count(?,?) </select> <parameterMap type="java.util.Map" id="getPersonCountMap"> <parameter property="personId" mode="IN" jdbcType="INTEGER"/> <parameter property="personCount" mode="OUT" jdbcType="INTEGER"/> </parameterMap>
測試方法:
// 調用存儲過程 @Test public void getPersonCountGtId(){ String statement = "com.itdragon.mapper.PersonMapper.getPersonCountGtId"; Map<String, Integer> parameterMap = new HashMap<String, Integer>(); parameterMap.put("personId", 1); parameterMap.put("personCount", -1); getSqlSession().selectOne(statement, parameterMap); Integer result = parameterMap.get("personCount"); System.out.println(result); }
7 一二級緩存
一級緩存:基於PerpetualCache 的 HashMap本地緩存,其存儲作用域為 Session,當 Session flush 或 close 之后,該Session中的所有 Cache 就將清空。
① 若Session 被關閉了,緩存清空
② 若數據執行了 創建,更新,刪除操作,緩存清空
③ 如果不是同一個Session,緩存失效
二級緩存:與一級緩存其機制相同,不同在於其存儲作用域為 Mapper(Namespace),並且可自定義存儲源,如 Ehcache。
① 默認是關閉的
② 是一個映射文件級的緩存,
③ 開啟二級緩存 <cache/>
還是在 PersonMapper.xml 文件中添加如下代碼
<!-- 開啟二級緩存 --> <!-- eviction="FIFO" 回收策略為先進先出 flushInterval="60000" 自動刷新時間60s size="512" 最多緩存512個引用對象 readOnly="true" 只讀 --> <cache eviction="FIFO" flushInterval="60000" size="1024" readOnly="true"/>
打印結果如下
log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. [Person [id=2, email=cyy@qq.com, lastName=cyy]] 1 0 Classroom [id=1, room=JavaEE, teacher=Teacher [id=1, subject=Java], students=null] Classroom [id=1, room=JavaEE, teacher=Teacher [id=1, subject=Java], students=null] Classroom [id=1, room=JavaEE, teacher=Teacher [id=1, subject=Java], students=[Student [id=1, name=ITDragon], Student [id=2, name=Marry]]] Classroom [id=1, room=JavaEE, teacher=Teacher [id=1, subject=Java], students=[Student [id=null, name=ITDragon], Student [id=null, name=Marry]]] [Person [id=1, email=lxl@qq.com, lastName=null], Person [id=2, email=cyy@qq.com, lastName=null], Person [id=3, email=itdrgon@qq.com, lastName=null]] Person [id=2, email=cyy@qq.com, lastName=null] Person [id=2, email=cyy@qq.com, lastName=cyy] Person [id=2, email=cyy@qq.com, lastName=cyy] 2 1
源碼地址:https://github.com/ITDragonBlog/daydayup/tree/master/mybatis/mybatis-basic
到這里,Mybatis 的入門知識就講完了。如果大家覺得不錯,可以關注我!后續還有很多不錯的內容提供。
