Mybatis学习总结二
Mybatis學習總結二
- 0、不需要修改的文件(在src下面)
- jdbc.properties文件
- log4j.properties文件
- SqlMapConfig.xml文件
- 1、高級結果映射
- 1.1、一對一
- 數據表內容
- 開發環境
- Address類
- User類
- UserMapper(Dao)接口
- UserMapper.xml文件
- 測試
- 測試結果
- 1.2、一對多
- 數據庫內容
- 開發環境
- Address類
- Phone類
- User類
- UserMapper接口
- UserMapper.xml文件(第一種寫法)
- UserMapper.xml文件(第二種寫法)
- 測試
- 測試結果
- 1.3、多對多
- 1.3.0、不變的東西
- 數據庫信息
- 開發環境
- Course類
- Student類
- SqlMapConfig.xml的一些小改變
- 1.3.1、查詢學生所選課程的情況
- StudentMapper.xml配置
- StudentMapper接口
- 測試
- 測試結果
- 1.3.2、查詢本門課程的所有學生
- CourseMapper.xml配置
- CourseMapper接口
- 測試
- 測試結果
- 1.3.3、增加一條選修記錄
- StudentCourseMapper.xml配置
- StudentCourse接口
- 測試(記得提交事務)
- 測試結果
- 2、延遲加載
- 2.1、什么是延遲加載
- 2.2、在SqlMapConfig.xml中設置延遲加載
- 2.3、一對多的延遲加載案例
- 數據庫信息
- 開發環境
- 兩個實體類
- Student
- Course
- 兩個接口
- StudentMapper
- CourseMapper
- 兩個xml配置(重點)
- StudentMapper.xml(注意sql語句和resultMap)
- CourseMapper.xml(注意sql語句)
- 測試
- 不加載課程信息
- 加載課程信息
- 測試結果
- 不加載課程信息結果
- 加載課程信息結果(當屬性被訪問時,再去數據庫查找,于是mapper需要這樣的sql語句)
- 3、查詢緩存
- 3.0、什么是緩存
- 3.1、一級緩存
- 開發環境
- 實體類
- 接口
- 配置文件
- 測試
- 測試結果(可以看出,只做了一次查詢)
- 3.2、二級緩存
- 二級緩存原理
- 開發環境
- 開啟緩存
- SqlMapConfig.xml配置
- StudentMapper.xml配置
- 實體類
- 接口
- 測試
- 測試結果
- 禁用緩存與刷新緩存
- 3.3、整合ehcache
- 應用場景
- 導包
- 添加ehcache.xml文件(下面的diskStore是我們自己的緩存路徑)
- 修改StudentMapper.xml
- 4、逆向工程(發送一波黑馬筆記)
- 4.1、下載逆向工程
- 4.2、創建逆向工程
- 4.3、創建Generator.java
- 4.4、添加generatorConfig.xml
- 4.5、注意事項
- 參考
0、不需要修改的文件(在src下面)
jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///mybatis jdbc.username=root jdbc.password=3306log4j.properties文件
log4j.rootLogger=DEBUG, Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n log4j.logger.org.apache=INFOSqlMapConfig.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><!-- 引入外部文件 --><properties resource="jdbc.properties"></properties><!-- 環境 --><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><!-- 加載UserMapper.xml文件 --><mappers><package name="UserMapper.xml" /></mappers> </configuration>1、高級結果映射
1.1、一對一
數據表內容
開發環境
Address類
package com.csa.po; public class Address {private Integer addressId;private String province;private String city;// get/set...方法// toString方法 }User類
package com.csa.po; public class User {private Integer userId;private String name;private Integer age;private Address address;// get/set...方法// toString方法 }UserMapper(Dao)接口
package com.csa.dao; import com.csa.po.User; public interface UserDao {/*** 通過用戶id,查找User* @param id* @return*/public User selectUserById(Integer id); }UserMapper.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.csa.dao.UserDao"><resultMap type="com.csa.po.User" id="User"><!-- user信息 --><id column="user_id" property="userId"/><result column="name" property="name"/><result column="age" property="age"/><!-- 一對一 --><association property="address" javaType="com.csa.po.Address"><id column="address_id" property="addressId"/><result column="province" property="province"/><result column="city" property="city"/></association></resultMap><!-- 查詢用戶,通過用戶id --><select id="selectUserById" parameterType="int" resultMap="User">select * from user,addresswhere user_id = #{userId} and address = address_id</select></mapper>測試
package com.csa.app; import java.io.InputStream; 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 com.csa.dao.UserDao; import com.csa.po.User;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 創建daoUserDao userDao = sqlSession.getMapper(UserDao.class);User user = userDao.selectUserById(3);System.out.println(user);// 關閉sqlSessionsqlSession.close();}}測試結果
1.2、一對多
數據庫內容
開發環境
Address類
package com.csa.po; public class Address {private Integer addressId;private String province;private String city;// get/set...方法// toString方法 }Phone類
package com.csa.po; public class Phone {private Integer phoneId;private String model;private String memory;// get/set...方法// toString方法 }User類
package com.csa.po; import java.util.List; public class User {private Integer userId;private String name;private Integer age;private Address address;private List<Phone> phoneList;// get/set...方法// toString方法 }UserMapper接口
package com.csa.dao; import com.csa.po.User; public interface UserMapper {/*** 通過用戶id,查找User* @param id* @return*/public User selectUserById(Integer id); }UserMapper.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.csa.dao.UserMapper"><resultMap type="com.csa.po.User" id="User"><!-- user信息 --><id column="user_id" property="userId"/><result column="name" property="name"/><result column="age" property="age"/><!-- 一對一 --><association property="address" javaType="com.csa.po.Address"><id column="address_id" property="addressId"/><result column="province" property="province"/><result column="city" property="city"/></association><!-- 一對多 --><collection property="phoneList" ofType="com.csa.po.Phone"><id column="phone_id" property="phoneId"/><result column="model" property="model"/><result column="memory" property="memory"/></collection></resultMap><!-- 查詢用戶,通過用戶id --><select id="selectUserById" parameterType="int" resultMap="User">select * from user,address,phonewhere user_id = #{id} and address = address_id and user = user_id</select></mapper>UserMapper.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.csa.dao.UserMapper"><resultMap type="com.csa.po.User" id="UserMap"><!-- user信息 --><id column="user_id" property="userId"/><result column="name" property="name"/><result column="age" property="age"/><!-- 一對一 --><association property="address" javaType="com.csa.po.Address"><id column="address_id" property="addressId"/><result column="province" property="province"/><result column="city" property="city"/></association></resultMap><!-- 使用到繼承 --><resultMap type="com.csa.po.User" id="User" extends="UserMap"><!-- 一對多 --><collection property="phoneList" ofType="com.csa.po.Phone"><id column="phone_id" property="phoneId"/><result column="model" property="model"/><result column="memory" property="memory"/></collection></resultMap><!-- 查詢用戶,通過用戶id --><select id="selectUserById" parameterType="int" resultMap="User">select * from user,address,phonewhere user_id = #{id} and address = address_id and user = user_id</select></mapper>測試
package com.csa.app;import java.io.InputStream; 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 com.csa.dao.UserMapper; import com.csa.po.User;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 創建daoUserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.selectUserById(3);System.out.println(user);// 關閉sqlSessionsqlSession.close();}}測試結果
1.3、多對多
1.3.0、不變的東西
數據庫信息
開發環境
Course類
package com.csa.po; import java.util.List; public class Course {private Integer courseId;private String courseName;private Integer credit;private List<Student> studentList;// get/set...方法// toString方法 }Student類
package com.csa.po; import java.util.List; public class Student {private Integer studentId;private String studentName;private Integer age;private List<Course> courseList;// get/set...方法// toString方法 }SqlMapConfig.xml的一些小改變
<!-- 加載UserMapper.xml文件 --> <mappers><mapper resource="StudentMapper.xml"/><mapper resource="CourseMapper.xml"/><mapper resource="StudentCourseMapper.xml"/> </mappers>1.3.1、查詢學生所選課程的情況
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="com.csa.dao.StudentMapper"><!-- CURD操作 --><resultMap type="com.csa.po.Student" id="Student"><id column="student_id" property="studentId"/><result column="student_name" property="studentName"/><result column="age" property="age"/><collection property="courseList" ofType="com.csa.po.Course"><id column="course_id" property="courseId"/><result column="course_name" property="courseName"/><result column="credit" property="credit"/></collection></resultMap><!-- 通過id查找該學生選修的課程 --><select id="selectStudentCoursesById" parameterType="int" resultMap="Student">select * from student natural join course natural join student_course where student_id = #{studentId}</select> </mapper>StudentMapper接口
package com.csa.dao; import com.csa.po.Student; public interface StudentMapper {/*** 通過學生id查找學生選修情況* @param id* @return*/public Student selectStudentCoursesById(Integer id); }測試
package com.csa.app;import java.io.InputStream; 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 com.csa.dao.StudentMapper; import com.csa.po.Student;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 創建daoStudentMapper studentMapper = (StudentMapper) sqlSession.getMapper(StudentMapper.class);Student student = studentMapper.selectStudentCoursesById(2);System.out.println(student);// 關閉sqlSessionsqlSession.close();}}測試結果
1.3.2、查詢本門課程的所有學生
CourseMapper.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.csa.dao.CourseMapper"><!-- CRUD操作 --><resultMap type="com.csa.po.Course" id="Course"><id column="course_id" property="courseId"/><result column="course_name" property="courseName"/><result column="credit" property="credit"/><collection property="studentList" ofType="com.csa.po.Student"><id column="student_id" property="studentId"/><result column="student_name" property="studentName"/><result column="age" property="age"/></collection></resultMap><!-- 通過課程id查詢本課程的所有學生 --><select id="selectCourseStudentsById" parameterType="int" resultMap="Course">select * from student natural join course natural join student_coursewhere course_id = #{courseId}</select></mapper>CourseMapper接口
package com.csa.dao; import com.csa.po.Course; public interface CourseMapper {/*** 通過課程id查詢本門課程的所有學生* @param id* @return*/public Course selectCourseStudentsById(Integer id); }測試
package com.csa.app;import java.io.InputStream; 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 com.csa.dao.CourseMapper; import com.csa.dao.StudentMapper; import com.csa.po.Course; import com.csa.po.Student;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 創建daoCourseMapper courseMapper = sqlSession.getMapper(CourseMapper.class);Course course = courseMapper.selectCourseStudentsById(3);System.out.println(course);// 關閉sqlSessionsqlSession.close();}}測試結果
1.3.3、增加一條選修記錄
StudentCourseMapper.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.csa.dao.StudentCourseMapper"><!-- CURD操作 --><insert id="addElective"><!-- 沒有給定參數則是為param1、param2...paramn -->insert into student_course values(#{param1.studentId},#{param2.courseId},#{param3})</insert> </mapper>StudentCourse接口
package com.csa.dao; import com.csa.po.Course; import com.csa.po.Student; public interface StudentCourseMapper {public void addElective(Student student,Course course,Integer score); }測試(記得提交事務)
package com.csa.app;import java.io.InputStream;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 com.csa.dao.StudentCourseMapper; import com.csa.po.Course; import com.csa.po.Student;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 創建daoStudentCourseMapper studentCourseMapper = sqlSession.getMapper(StudentCourseMapper.class);Student student = new Student();student.setStudentId(2);Course course = new Course();course.setCourseId(2);studentCourseMapper.addElective(student, course, 99);// 提交事務sqlSession.commit();// 關閉sqlSessionsqlSession.close();}}測試結果
2、延遲加載
2.1、什么是延遲加載
延遲加載又叫懶加載,也叫按需加載。也就是說先加載主信息,在需要的時候,再去加載從信息。
在mybatis中,resultMap標簽 的association標簽和collection標簽具有延遲加載的功能。
2.2、在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><!-- 引入外部文件 --><properties resource="jdbc.properties"></properties><settings><!-- 開啟延遲加載,默認為true --><setting name="lazyLoadingEnabled" value="true"/><!-- 將積極加載改為消極加載即按需要加載,默認為true --><setting name="aggressiveLazyLoading" value="false"/></settings><!-- 環境 --><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><!-- 加載UserMapper.xml文件 --><mappers><mapper resource="StudentMapper.xml"/><mapper resource="CourseMapper.xml"/></mappers> </configuration>2.3、一對多的延遲加載案例
數據庫信息
開發環境
兩個實體類
Student
package com.csa.po;import java.util.List;public class Student {private Integer studentId;private String studentName;private Integer age;private List<Course> courseList;// get/set...方法// toString方法 }Course
package com.csa.po;import java.util.List;public class Course {private Integer courseId;private String courseName;private Integer credit;private List<Student> studentList;// get/set...方法// toString方法 }兩個接口
StudentMapper
package com.csa.dao; import com.csa.po.Student; public interface StudentMapper {/*** 通過學生id查找學生選修情況* @param id* @return*/public Student selectStudentCoursesById(Integer id); }CourseMapper
package com.csa.dao; import com.csa.po.Course; public interface CourseMapper {/*** 通過課程id查詢本門課程的所有學生* @param id* @return*/public Course selectCourseStudentsById(Integer id); }兩個xml配置(重點)
StudentMapper.xml(注意sql語句和resultMap)
<?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.csa.dao.StudentMapper"><!-- CURD操作 --><resultMap type="com.csa.po.Student" id="Student"><id column="student_id" property="studentId"/><result column="student_name" property="studentName"/><result column="age" property="age"/><collection property="courseList" ofType="com.csa.po.Course"select="com.csa.dao.CourseMapper.selectCourseStudentsById" column="student_id"></collection></resultMap><!-- 通過id查找該學生選修的課程 --><select id="selectStudentCoursesById" parameterType="int" resultMap="Student">select * from student where student_id = #{studentId}</select> </mapper>CourseMapper.xml(注意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="com.csa.dao.CourseMapper"><!-- CRUD操作 --><resultMap type="com.csa.po.Course" id="Course"><id column="course_id" property="courseId"/><result column="course_name" property="courseName"/><result column="credit" property="credit"/><collection property="studentList" ofType="com.csa.po.Student"><id column="student_id" property="studentId"/><result column="student_name" property="studentName"/><result column="age" property="age"/></collection></resultMap><!-- 通過課程id查詢本課程的所有學生 --><select id="selectCourseStudentsById" parameterType="int" resultMap="Course">select * from course natural join student_coursewhere student_id = #{student_id}</select></mapper>測試
不加載課程信息
package com.csa.app; import java.io.InputStream; 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 com.csa.dao.StudentMapper; import com.csa.po.Course; import com.csa.po.Student;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 創建daoStudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);Student student = studentMapper.selectStudentCoursesById(2);// 將下面這段放開,則是延遲加載了course!/*for (Course course : student.getCourseList()) {System.out.println(course);}*/// 關閉sqlSessionsqlSession.close();}}加載課程信息
package com.csa.app; import java.io.InputStream; 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 com.csa.dao.StudentMapper; import com.csa.po.Course; import com.csa.po.Student;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 創建daoStudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);Student student = studentMapper.selectStudentCoursesById(2);for (Course course : student.getCourseList()) {System.out.println(course);}// 關閉sqlSessionsqlSession.close();}}測試結果
不加載課程信息結果
加載課程信息結果(當屬性被訪問時,再去數據庫查找,于是mapper需要這樣的sql語句)
# 這里的查詢條件是學號! select * from course natural join student_coursewhere student_id = #{student_id}3、查詢緩存
3.0、什么是緩存
Mybatis的緩存,包括一級緩存和二級緩存。
一級緩存指的就是sqlsession,在sqlsession中有一個數據區域,是map結構,這個區域就是一級緩存區域。一級緩存中的key是由sql語句、條件、statement等信息組成一個唯一值。一級緩存中的value,就是查詢出的結果對象。
二級緩存指的就是同一個namespace下的mapper,二級緩存中,也有一個map結構,這個區域就是一級緩存區域。一級緩存中的key是由sql語句、條件、statement等信息組成一個唯一值。一級緩存中的value,就是查詢出的結果對象。
3.1、一級緩存
一級緩存是默認使用的。同一個sqlsession中的緩存。
開發環境
實體類
package com.csa.po; public class Student {private Integer studentId;private String studentName;private Integer age;// get/set...方法// toString方法 }接口
package com.csa.dao; import com.csa.po.Student; public interface StudentMapper {/*** 通過學生id查找學生* @param id* @return*/public Student selectStudentById(Integer id); }配置文件
<?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.csa.dao.StudentMapper"><!-- CURD操作 --><resultMap type="com.csa.po.Student" id="Student"><id column="student_id" property="studentId"/><result column="student_name" property="studentName"/><result column="age" property="age"/></resultMap><!-- 通過id查找該學生選修的課程 --><select id="selectStudentById" parameterType="int" resultMap="Student">select * from student where student_id = #{studentId}</select> </mapper>測試
package com.csa.app;import java.io.InputStream; 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 com.csa.dao.StudentMapper; import com.csa.po.Student;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 創建daoStudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);Student student1 = studentMapper.selectStudentById(2);Student student2 = studentMapper.selectStudentById(2);System.out.println(student1);System.out.println(student2);// 關閉sqlSessionsqlSession.close();}}測試結果(可以看出,只做了一次查詢)
3.2、二級緩存
二級緩存需要手動開啟。
二級緩存原理
開發環境
開啟緩存
SqlMapConfig.xml配置
<!-- 開啟二級緩存 --> <setting name="cacheEnabled" value="true"/>StudentMapper.xml配置
<!-- 開啟二級緩存,默認使用了PerpettualCache --> <cache/>實體類
需要序列化!
package com.csa.po; import java.io.Serializable; public class Student implements Serializable{private Integer studentId;private String studentName;private Integer age;// get/set...方法// toString方法 }接口
與上面一樣!
測試
package com.csa.app;import java.io.InputStream; 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 com.csa.dao.StudentMapper; import com.csa.po.Student;public class App {public static void main(String[] args) throws Exception {// 讀取全局配置文件String resource = "SqlMapConfig.xml";InputStream input = Resources.getResourceAsStream(resource);// 創建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);// 創建sqlSessionSqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();SqlSession sqlSession3 = sqlSessionFactory.openSession();// 創建daoStudentMapper studentMapper1 = sqlSession1.getMapper(StudentMapper.class);StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);StudentMapper studentMapper3 = sqlSession3.getMapper(StudentMapper.class);Student student1 = studentMapper1.selectStudentById(2);// 關閉sqlSessionsqlSession1.close();Student student2 = studentMapper2.selectStudentById(2);sqlSession2.close();Student student3 = studentMapper3.selectStudentById(2);Student student11 = studentMapper3.selectStudentById(4);sqlSession3.close();System.out.println(student1);System.out.println(student2);System.out.println(student3);System.out.println(student11);}}測試結果
禁用緩存與刷新緩存
<!-- useCache:是否使用緩存flushCache:是否刷新緩存--> <!-- 通過id查找該學生選修的課程 --> <select id="selectStudentById" parameterType="int" resultMap="Student"useCache="false" flushCache="true">select * from student where student_id = #{studentId} </select>3.3、整合ehcache
應用場景
使用場景:對于訪問響應速度要求高,但是實時性不高的查詢,可以采用二級緩存技術。
注意:在使用二級緩存的時候,要設置一下刷新間隔(cache標簽中有一個flashInterval屬性)來定時刷新二級緩存,這個刷新間隔根據具體需求來設置,比如設置30分鐘、60分鐘等,單位為毫秒。
導包
添加ehcache.xml文件(下面的diskStore是我們自己的緩存路徑)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><!--The ehcache-failsafe.xml is a default configuration for ehcache, if an ehcache.xml is not configured.The diskStore element is optional. It must be configured if you have overflowToDisk or diskPersistent enabledfor any cache. If it is not configured, a warning will be issues and java.io.tmpdir will be used.diskStore has only one attribute - "path". It is the path to the directory where .data and .index files will be created.If the path is a Java System Property it is replaced by its value in therunning VM.The following properties are translated:* user.home - User's home directory* user.dir - User's current working directory* java.io.tmpdir - Default temp file path* ehcache.disk.store.dir - A system property you would normally specify on the command linee.g. java -Dehcache.disk.store.dir=/u01/myapp/diskdir ...Subdirectories can be specified below the property e.g. java.io.tmpdir/one--><diskStore path="java.io.tmpdir"/><!--Specifies a CacheManagerEventListenerFactory, be used to create a CacheManagerPeerProvider,which is notified when Caches are added or removed from the CacheManager.The attributes of CacheManagerEventListenerFactory are:* class - a fully qualified factory class name* properties - comma separated properties having meaning only to the factory.Sets the fully qualified class name to be registered as the CacheManager event listener.The events include:* adding a Cache* removing a CacheCallbacks to listener methods are synchronous and unsynchronized. It is the responsibilityof the implementer to safely handle the potential performance and thread safety issuesdepending on what their listener is doing.If no class is specified, no listener is created. There is no default.<cacheManagerEventListenerFactory class="" properties=""/>--><!--(Enable for distributed operation)Specifies a CacheManagerPeerProviderFactory which will be used to create aCacheManagerPeerProvider, which discovers other CacheManagers in the cluster.The attributes of cacheManagerPeerProviderFactory are:* class - a fully qualified factory class name* properties - comma separated properties having meaning only to the factory.Ehcache comes with a built-in RMI-based distribution system with two means of discovery ofCacheManager peers participating in the cluster:* automatic, using a multicast group. This one automatically discovers peers and detectschanges such as peers entering and leaving the group* manual, using manual rmiURL configuration. A hardcoded list of peers is provided atconfiguration time.Configuring Automatic Discovery:Automatic discovery is configured as per the following example:<cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,multicastGroupPort=4446, timeToLive=32"/>Valid properties are:* peerDiscovery (mandatory) - specify "automatic"* multicastGroupAddress (mandatory) - specify a valid multicast group address* multicastGroupPort (mandatory) - specify a dedicated port for the multicast heartbeattraffic* timeToLive - specify a value between 0 and 255 which determines how far the packets will propagate.By convention, the restrictions are:0 - the same host1 - the same subnet32 - the same site64 - the same region128 - the same continent255 - unrestrictedConfiguring Manual Discovery:Manual discovery is configured as per the following example:<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="peerDiscovery=manual,rmiUrls=//server1:40000/sampleCache1|//server2:40000/sampleCache1| //server1:40000/sampleCache2|//server2:40000/sampleCache2"/>Valid properties are:* peerDiscovery (mandatory) - specify "manual"* rmiUrls (mandatory) - specify a pipe separated list of rmiUrls, in the form//hostname:portThe hostname is the hostname of the remote CacheManager peer. The port is the listeningport of the RMICacheManagerPeerListener of the remote CacheManager peer.<cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="peerDiscovery=automatic,multicastGroupAddress=230.0.0.1,multicastGroupPort=4446, timeToLive=1"/>--><!--(Enable for distributed operation)Specifies a CacheManagerPeerListenerFactory which will be used to create aCacheManagerPeerListener, whichlistens for messages from cache replicators participating in the cluster.The attributes of cacheManagerPeerListenerFactory are:class - a fully qualified factory class nameproperties - comma separated properties having meaning only to the factory.Ehcache comes with a built-in RMI-based distribution system. The listener component isRMICacheManagerPeerListener which is configured usingRMICacheManagerPeerListenerFactory. It is configured as per the following example:<cacheManagerPeerListenerFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"properties="hostName=fully_qualified_hostname_or_ip,port=40001,socketTimeoutMillis=120000"/>All properties are optional. They are:* hostName - the hostName of the host the listener is running on. Specifywhere the host is multihomed and you want to control the interface over which clustermessages are received. Defaults to the host name of the default interface if notspecified.* port - the port the listener listens on. This defaults to a free port if not specified.* socketTimeoutMillis - the number of ms client sockets will stay open when sendingmessages to the listener. This should be long enough for the slowest message.If not specified it defaults 120000ms.<cacheManagerPeerListenerFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>--><!-- Cache configuration.The following attributes are required.name:Sets the name of the cache. This is used to identify the cache. It must be unique.maxElementsInMemory:Sets the maximum number of objects that will be created in memory (0 == no limit)maxElementsOnDisk:Sets the maximum number of objects that will be maintained in the DiskStoreThe default value is zero, meaning unlimited.eternal:Sets whether elements are eternal. If eternal, timeouts are ignored and theelement is never expired.overflowToDisk:Sets whether elements can overflow to disk when the in-memory cachehas reached the maxInMemory limit.The following attributes are optional.timeToIdleSeconds:Sets the time to idle for an element before it expires.i.e. The maximum amount of time between accesses before an element expiresIs only used if the element is not eternal.Optional attribute. A value of 0 means that an Element can idle for infinity.The default value is 0.timeToLiveSeconds:Sets the time to live for an element before it expires.i.e. The maximum time between creation time and when an element expires.Is only used if the element is not eternal.Optional attribute. A value of 0 means that and Element can live for infinity.The default value is 0.diskPersistent:Whether the disk store persists between restarts of the Virtual Machine.The default value is false.diskExpiryThreadIntervalSeconds:The number of seconds between runs of the disk expiry thread. The default valueis 120 seconds.diskSpoolBufferSizeMB:This is the size to allocate the DiskStore for a spool buffer. Writes are madeto this area and then asynchronously written to disk. The default size is 30MB.Each spool buffer is used only by its cache. If you get OutOfMemory errors considerlowering this value. To improve DiskStore performance consider increasing it. Trace levellogging in the DiskStore will show if put back ups are occurring.memoryStoreEvictionPolicy:Policy would be enforced upon reaching the maxElementsInMemory limit. Defaultpolicy is Least Recently Used (specified as LRU). Other policies available -First In First Out (specified as FIFO) and Less Frequently Used(specified as LFU)Cache elements can also contain sub elements which take the same format of a factory classand properties. Defined sub-elements are:* cacheEventListenerFactory - Enables registration of listeners for cache events, such asput, remove, update, and expire.* bootstrapCacheLoaderFactory - Specifies a BootstrapCacheLoader, which is called by acache on initialisation to prepopulate itself.Each cache that will be distributed needs to set a cache event listener which replicatesmessages to the other CacheManager peers. For the built-in RMI implementation this is doneby adding a cacheEventListenerFactory element of type RMICacheReplicatorFactory to eachdistributed cache's configuration as per the following example:<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true "/>The RMICacheReplicatorFactory recognises the following properties:* replicatePuts=true|false - whether new elements placed in a cache arereplicated to others. Defaults to true.* replicateUpdates=true|false - whether new elements which override anelement already existing with the same key are replicated. Defaults to true.* replicateRemovals=true - whether element removals are replicated. Defaults to true.* replicateAsynchronously=true | false - whether replications areasynchronous (true) or synchronous (false). Defaults to true.* replicateUpdatesViaCopy=true | false - whether the new elements arecopied to other caches (true), or whether a remove message is sent. Defaults to true.* asynchronousReplicationIntervalMillis=<number of milliseconds> - The asynchronousreplicator runs at a set interval of milliseconds. The default is 1000. The minimumis 10. This property is only applicable if replicateAsynchronously=true* asynchronousReplicationMaximumBatchSize=<number of operations> - The maximumnumber of operations that will be batch within a single RMI message. The defaultis 1000. This property is only applicable if replicateAsynchronously=trueThe RMIBootstrapCacheLoader bootstraps caches in clusters where RMICacheReplicators areused. It is configured as per the following example:<bootstrapCacheLoaderFactoryclass="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"properties="bootstrapAsynchronously=true, maximumChunkSizeBytes=5000000"/>The RMIBootstrapCacheLoaderFactory recognises the following optional properties:* bootstrapAsynchronously=true|false - whether the bootstrap happens in the backgroundafter the cache has started. If false, bootstrapping must complete before the cache ismade available. The default value is true.* maximumChunkSizeBytes=<integer> - Caches can potentially be very large, larger than thememory limits of the VM. This property allows the bootstraper to fetched elements inchunks. The default chunk size is 5000000 (5MB).--><!--Mandatory Default Cache configuration. These settings will be applied to cachescreated programmtically using CacheManager.add(String cacheName)--><defaultCachemaxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"maxElementsOnDisk="10000000"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"><persistence strategy="localTempSwap"/></defaultCache> </ehcache>修改StudentMapper.xml
<!-- 開啟二級緩存,默認使用了org.mybatis.caches.ehcache.EncacheCache --> <cache type="org.mybatis.caches.ehcache.EncacheCache"/>4、逆向工程(發送一波黑馬筆記)
4.1、下載逆向工程
逆向工程jar的下載地址
4.2、創建逆向工程
4.3、創建Generator.java
4.4、添加generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><context id="testTables" targetRuntime="MyBatis3"><commentGenerator><!-- 是否去除自動生成的注釋 true:是 : false:否 --><property name="suppressAllComments" value="true" /></commentGenerator><!--數據庫連接的信息:驅動類、連接地址、用戶名、密碼 --><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root"password="root"></jdbcConnection><!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" userId="yycg" password="yycg"> </jdbcConnection> --><!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer,為 true時把JDBC DECIMAL 和 NUMERIC 類型解析為java.math.BigDecimal --><javaTypeResolver><property name="forceBigDecimals" value="false" /></javaTypeResolver><!-- targetProject:生成PO類的位置 --><javaModelGenerator targetPackage="com.itheima.ms.po"targetProject=".\src"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /><!-- 從數據庫返回的值被清理前后的空格 --><property name="trimStrings" value="true" /></javaModelGenerator><!-- targetProject:mapper映射文件生成的位置 --><sqlMapGenerator targetPackage="com.itheima.ms.mapper"targetProject=".\src"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /></sqlMapGenerator><!-- targetPackage:mapper接口生成的位置 --><javaClientGenerator type="XMLMAPPER"targetPackage="com.itheima.ms.mapper" targetProject=".\src"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /></javaClientGenerator><!-- 指定數據庫表 --><table tableName="items"></table><table tableName="orders"></table><table tableName="orderdetail"></table><table tableName="user"></table></context> </generatorConfiguration>4.5、注意事項
Mapper.xml文件已經存在時,如果進行重新生成則mapper.xml文件時,內容不被覆蓋而是進行內容追加,結果導致mybatis解析失敗。
解決方法:刪除原來已經生成的mapper xml文件再進行生成。
Mybatis自動生成的po及mapper.java文件不是內容而是直接覆蓋沒有此問題。
參考
黑馬筆記、黑馬、黑馬!!!
總結
以上是生活随笔為你收集整理的Mybatis学习总结二的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis学习总结一
- 下一篇: 2020年共享汽车发展趋势研究报告