接上次的mybatis学习
日志
Mybatis提供的日志支持
可选的值有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING,或者是实现了
org.apache.ibatis.logging.Log
接口,且构造方法以字符串为参数的类完全限定名。
mybatis-config.xml文件中配置日志,配置文件必须遵循规范
<!--数据库外部文件配置-->
<properties resource="db.properties"/>
<!--日志配置的位置,必须在properties和typeAliases中间,STDOUT_LOGGING标准的日志工厂实现-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.itxing.pojo"/>
</typeAliases>
LOG4J
使用Log4j,可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIXSyslog守护进程等。
可以控制每一条日志的输出格式,控制日志的生成过程
1.导入依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2.编写配置文件
##Log4J的配置之简单使它遍及于越来越多的应用中了
##Log4J配置文件实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签等全套功能。择其一二使用就够用了。
##此文件(log4j.properties)内容来自网络
log4j.rootLogger = DEBUG, console,file
log4j.addivity.org.apache = true
# 应用于控制台
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = [framework] % d - % c -%- 4r [ % t] %- 5p % c % x - % m % n
#log4j.appender.CONSOLE.layout.ConversionPattern = [start] % d {DATE} [DATE] % n % p[PRIORITY] % n % x[NDC] % n % t[THREAD] n % c[CATEGORY] % n % m[MESSAGE] % n % n
#应用于文件
log4j.appender.file = org.apache.log4j.FileAppender
log4j.appender.file.File = file.log
log4j.appender.file.Append = false
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = [framework] % d - % c -%- 4r [ % t] %- 5p % c % x - % m % n
# Use this layout for LogFactor 5 analysis
# 应用于文件回滚
log4j.appender.rolling_file = org.apache.log4j.RollingFileAppender
log4j.appender.rolling_file.Threshold = ERROR
log4j.appender.rolling_file.File = rolling.log
log4j.appender.rolling_file.Append = true
log4j.appender.rolling_file.MaxFileSize = 10KB
log4j.appender.rolling_file.MaxBackupIndex = 1
log4j.appender.rolling_file.layout = org.apache.log4j.PatternLayout
log4j.appender.rolling_file.layout.ConversionPattern = [framework] % d - % c -%- 4r [ % t] %- 5p % c % x - % m % n
#应用于socket
log4j.appender.socket = org.apache.log4j.RollingFileAppender
log4j.appender.socket.RemoteHost = localhost
log4j.appender.socket.Port = 5001
log4j.appender.socket.LocationInfo = true
# Set up for Log Facter 5
log4j.appender.socket.layout = org.apache.log4j.PatternLayout
log4j.appender.socket.layout.ConversionPattern = [start] % d {DATE} [DATE] % n % p[PRIORITY] % n % x[NDC] % n % t[THREAD] % n % c[CATEGORY] % n % m[MESSAGE] % n % n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER = org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords = 2000
# 发送日志给邮件
log4j.appender.mail = org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold = FATA
log4j.appender.mail.BufferSize = 10
log4j.appender.mail.From = web@www.wuset.com
log4j.appender.mail.SMTPHost = www.wusetu.com
log4j.appender.mail.Subject = Log4J Message
log4j.appender.mail.To = web@www.wusetu.com
log4j.appender.mail.layout = org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern = [framework] % d - % c -%- 4r [ % t] %- 5p % c % x - % m % n
# 用于数据库
log4j.appender.database = org.apache.log4j.jdbc.JDBCAppender
log4j.appender.database.URL = jdbc:mysql: // localhost:3306/test
log4j.appender.database.driver = com.mysql.jdbc.Driver
log4j.appender.database.user = root
log4j.appender.database.password =
log4j.appender.database.sql = INSERT INTO LOG4J (Message) VALUES ( ' [framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n ' )
log4j.appender.database.layout = org.apache.log4j.PatternLayout
log4j.appender.database.layout.ConversionPattern = [framework] % d - % c -%- 4r [ % t] %- 5p % c % x - % m % n
log4j.appender.A1 = org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File = SampleMessages.log4j
log4j.appender.A1.DatePattern = yyyyMMdd - HH ' .log4j '
log4j.appender.A1.layout = org.apache.log4j.xml.XMLLayout
#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout = org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern = [framework] % d - % c -%- 4r [ % t] %- 5p % c % x - % m % n
自定义log4j文件
#将等为Debug的日志信息输出到console和file这两个地方
log4j.rootLogger = DEBUG,console,file
#控制台相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = [%c]-%m%n
#文件输出相关设置
log4j.appender.file = org.apache.log4j.FileAppender
#日志文件的路径
log4j.appender.file.File = ./log/itxing.log
log4j.appender.file.Append = false
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = [%p][%d{yyyy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3.配置log4j为日志的实现
<!--将std实现转换成log4j实现-->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
4.简单使用log4j
使用Logger类需要导入,import org.apache.log4j.Logger;
日志级别:ERROR、WARN、INFO、DEBUG
分页:
1.使用limit分页
select * from user limit startIndex,pagesize
2.使用mybatis分页:使用万能的参数map,将参数传递到dao查询
<select id="getUserLimit" parameterType="map" resultType="com.itxing.pojo.User">
select * from test.user limit #{startIndex},#{pageSize}
</select>
java类中使用map传参
//测试分页查询
@Test
public void getUserLimit(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("startIndex",0);
map.put("pageSize",2);
List<User> userLimit = mapper.getUserLimit(map);
for (User user : userLimit) {
System.out.println(user);
}
sqlSession.close();
}
3.面向对象实现分页,使用一个对象RowBounds
<!--使用面向对象实现分页-->
<select id="getUserLimitByObj" resultType="com.itxing.pojo.User">
select * from test.user
</select>
@Test
public void getUserByObj(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
RowBounds row = new RowBounds(1,2);
List<User> objects = sqlSession.selectList("com.itxing.dao.UserMapper.getUserLimitByObj",null,row);
for (User object : objects) {
System.out.println(object);
}
sqlSession.close();
}
4.使用分页插件PageHelper
注解开发: 主要是为了让解耦
注解的接口:,在接口方法上写上sql,适用于简单的增删改查操作,对于复杂的sql最好使用配置进行
/**
* @author xing
* @create 2020/5/19-mybatis
*/
public interface ProductMapper {
//查询注解,获取所有的产品信息
@Select("select * from test.product")
List<Product> getProductAll();
//条件查询注解
//@Param基本类型或者String类型,需要加上注解,引用类型不需要加
//如果只有一个基本类型的话,可忽略,sql中的引用就是@Param中设定的属性名
@Select("select * from test.product where pid = #{pid}")
Product getProductById(@Param("pid") int pid);
//插入数据注解
@Insert("insert into test.product(pid,pname,pprice,pcategary) values(#{pid},#{pname},#{pprice},#{pcategary})")
int addProduct(Product product);
}
底层原理是反射技术、动态代理。代理模式、工厂模式、单例模式
修改工具类,使得能够对事物进行设置
/**
* @author xing
* @create 2020/5/18-mybatis
*/
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static{
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//有sqlSessionFactory就从工厂中获取SqlSession的实例
//SqlSession完全包含了面向数据库执行sql命令所需的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
//设置参数开启事务,最好不适用自动提交事务,自己的代码应try捕获异常
//有sqlSessionFactory就从工厂中获取SqlSession的实例
//SqlSession完全包含了面向数据库执行sql命令所需的所有方法
public static SqlSession getSqlSession(boolean flag){
return sqlSessionFactory.openSession(flag);
}
}
lombok插件:
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
lombok常用注解:
@Data 自动生成get/set
@NoArgsConstructor 无参构造函数
@ToString toString方法
@AllArgsConstructor 全参数构造函数
Mybatis复杂查询
多对一和一对多,站在不同的角度。再提resultMap
resultMap元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets数据提取代码中解放出来,并在一些情形下允许你进行一些JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap能够代替实现同等功能的数千行代码。
建立复杂查询关联表:学生表和教师表,一个老师对应对个学生,测试使用的表
##生成一张教师表
CREATE TABLE `teacher`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
###插入教师数据
INSERT INTO `teacher`(`id`,`name`) VALUES(1,'xing');
#生成一张学生表,关联老师
CREATE TABLE `student`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY(`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
)ENGINE = INNODB DEFAULT CHARSET=utf8;
##插入多个学生
INSERT INTO `student`(`id`,`name`,`tid`) VALUES (1,'小一',1);
INSERT INTO `student`(`id`,`name`,`tid`) VALUES (2,'小二',1);
INSERT INTO `student`(`id`,`name`,`tid`) VALUES (3,'小三',1);
INSERT INTO `student`(`id`,`name`,`tid`) VALUES (4,'小四',1);
INSERT INTO `student`(`id`,`name`,`tid`) VALUES (5,'小五',1);
1.多对一处理
方式一:创建对应的实体类(方式一相当于两步进行操作,第一步先将学生查询出来,第二步根据学生查询出来的结果查询外键关联的表)
/**
* @author xing
* @create 2020/5/20-mybatis
*/
@Data
@NoArgsConstructor
@ToString
public class Student {
int id;
String name;
//学生关联老师,对应的老师类型
Teacher teacher;
}
/**
* @author xing
* @create 2020/5/20-mybatis
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Teacher {
int id;
String name;
}
编写对应的配置文件
主配置文件中为两个实体类配置别名
<typeAliases>
<typeAlias type="com.itxing.pojo.Teacher" alias="Teacher"></typeAlias>
<typeAlias type="com.itxing.pojo.Student" alias="Student"></typeAlias>
</typeAliases>
Student对应的mapper配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itxing.dao.StudentMapper">
<!--首先查询响应的学生,根据学生的tid查询老师
查询结果进行结果集映射,学生中的教师信息使用association进行映射,将根据结果集中的id进行教师信息查询
-->
<select id="getStudentList" resultMap="StudentTeacher">
select * from test.student
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"> </association>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from test.teacher where id = #{id}
</select>
</mapper>
Teacher对应的配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--configuration核心配置文件-->
<mapper namespace="com.itxing.dao.TeacherMapper">
</mapper>
查询学生学生中包含有对应的教师字段:
@Test
public void getStudent(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//查询学生,以及其对应的老师信息
List<Student> studentList = mapper.getStudentList();
for (Student student : studentList) {
System.out.println(student);
}
sqlSession.close();
}
方式二:按照结果嵌套处理(联合查询)
学生的配置文件中,一个sql先将表中的所有关系查询出来在进行结果映射
<!--方式二,查询学生-->
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.name tname from test.student s,test.teacher t where s.tid=t.id
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"></result>
<result property="name" column="sname"></result>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"></result>
</association>
</resultMap>
2.一对多,一个老师对应多个学生,需要在老师表中添加外键
方式一:一条sql查询老师下的所有学生
@Data
@NoArgsConstructor
@ToString
public class Student {
int id;
String name;
//学生关联老师,一对多时只是存放教师的id
int tid;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Teacher {
int id;
String name;
//一对多,一个老师对应多个学生,使用一个集合
List<Student> student;
}
主配置文件不变,student和teacher配置文件不同
<!--教师的配置文件中的配置,一条sql语句将记录查询出来在进行map映射-->
<select id="getTeacher2" resultMap="TeacherStudent">
select t.id tid,t.name tname,s.name sname
from test.teacher t,test.student s where t.id = s.tid
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"></result>
<result property="name" column="tname"></result>
<!--
多对一使用的是对象 association 一对多使用的是collection
javaType="Student"指定属性类型
集合中使用泛型信息 ofType指定类型
-->
<collection property="student" ofType="Student">
<result property="name" column="sname"></result>
</collection>
</resultMap>
测试类:
@Test
public void testOneToMore(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
List<Teacher> teacher2 = mapper.getTeacher2();
for (Teacher teacher : teacher2) {
System.out.println(teacher);
}
sqlSession.close();
}
方式二:先将教师查询出来再去查询对应的学生信息,一对多使用的是collection
<select id="getTeacher3" resultMap="TeacherStudent2">
select * from test.teacher where id=#{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<!--collection中property是Teacher类中的学生字段,javaType是对应属性的类型,集合类型的实现类型,ofType是集合的泛型约束类型,select表示再次进行查询-->
<collection property="student" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"></collection>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from student where tid = #{tid}
</select>
测试类:
@Test
public void selectTeacherByid(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
List<Teacher> teacher3 = mapper.getTeacher3(1);
for (Teacher teacher : teacher3) {
System.out.println(teacher);
}
}
注:多对一:association 一对多collection
javaType表示实体类的属性类型 和ofType表示集合类的泛型中的约束类型
动态sql
根据不同的条件生成不同的sql语句,获取不同的数据
测试的数据库文件
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL ,
`title` VARCHAR(100)NOT NULL,
`author` VARCHAR(30) NOT NULL,
`create_time` DATETIME NOT NULL ,
`views` INT(30) NOT NULL
)ENGINE = INNODB DEFAULT CHARSET = utf8;
INSERT INTO blog(id,title,author,create_time,views) VALUES('1','nihao','itxing','2020-05-20',10)
解决数据库字段与实体类命名不一致,最好使用驼峰命名规则
<settings>
<!--设置日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启驼峰命名规则-->
<setting name="mapUnderscoreToCameCase" value="true"></setting>
</settings>
对应的实体类
/**
* @author xing
* @create 2020/5/20-mybatis
*/
@Data
@NoArgsConstructor
@ToString
@AllArgsConstructor
public class Blog {
private String id;
private String title;
private String author;
//数据库的字段为 create_time,使用驼峰命名转换
private Date createTime;
private int views;
}
动态sql之if,在blogmapper.xml中配置
<!--条件查询-->
<select id="queryBlogIF" parameterType="map" resultType="Blog">
select * from test.blog where 1=1
<if test="title != null">
and title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</select>
<!--或则使用where标签,上面与下面的功能一致,使用一种即可-->
<!--条件查询-->
<select id="queryBlogIF" parameterType="map" resultType="Blog">
select * from test.blog
<where>
<!--每一个都加入标签就算只有第一个有值,会变成where and mybatis会将第一个and去掉保证sql正确-->
<if test="title != null">
and title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</where>
</select>
choose(when、where)
<!--choose和when相当于java中的switch case语句-->
<select id="queryBlogChoose" parameterType="map" resultType="Blog">
select * from test.blog
<where>
<choose>
<when test="title != null">
title=#{title}
</when>
<when test="author != null">
and author=#{author}
</when>
<otherwise>
and views=#{views}
</otherwise>
</choose>
</where>
</select>
trim、where、set
<!--set标签,会自动将中间的set之后的参数“,”去掉-->
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author !=null">
author = #{author},
</if>
</set>
where id = #{id}
</update>
抽取公共部分
<!--使用sql标签以及include便签将可以重用的程序抽取出来-->
<sql id="if_title_author">
<if test="title != null">
title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</sql>
<!--条件查询-->
<select id="queryBlogIF" parameterType="map" resultType="Blog">
select * from test.blog
<where>
<include refid="if_title_author"></include>
</where>
</select>
<!--修改对象-->
<update id="updateBlog" parameterType="map">
update blog
<set>
<include refid="if_title_author"></include>
</set>
where id = #{id}
</update>
foreach部分查询,动态拼接出来sql语句
<!--SELECT * FROM test.blog WHERE 1=1 AND (id=1 OR id = 2 OR id = 5)进行xml配置中时,传入参数为map将map中传入一个id集合的,循环遍历集合将数据填入拼接sql语句
-->
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
select * from test.blog
<where>
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id = #{id}
</foreach>
</where>
</select>
mybatis缓存:
1.缓存是存在内存中的临时的数据,将用户经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上查询,从缓存中查询,从而提高效率,一定程度上解决高并发系统的性能问题。
2.使用缓存减少用户和数据库的交互次数,减少系统的消耗,提高系统的效率
3.适合使用缓存的是经常查询且不经常改变的数据
Mybatis中默认开启以及缓存,Sqlsession级别称为本地缓存,二级缓存需要手动的开启,基于namespace级别的缓存。
缓存清理策略:
LRU:最近最少使用过期策略
FIFO:先进先出
SOFT:软引用
WEAK:虚引用
在同一个Sqlsession中查询同一个语句执行一次,查询不同的语句查询两次,以及缓存默认开启,不能关闭在同一个SqlSession中有效可以手动清理缓存,增删改对数据库进行写操作的时候一定会刷新缓存
//不清理缓存时,默认开启一级缓存,查询相同的语句只执行一次,只在一次SqlSession中有效
@Test
public void testQuery(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.queryUserById(1);
// sqlSession.clearCache();
User user2 = mapper.queryUserById(1);
System.out.println(user1);
System.out.println(user2);
sqlSession.close();
}
清理以及缓存将sqlSession.clearCache()代码开启,执行结果会有两次与数据库交互。
xml中设置缓存的参数:xml文件的设置参数
<!--配置日志,必须放在pro和set之间-->
<settings>
<!--设置日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启驼峰命名规则-->
<setting name="mapUnderscoreToCamelCase" value="true"></setting>
<!--配置二级缓存-->
<setting name="cacheEnabled" value="true"></setting>
</settings>
缓存常用参数设置:
<!--缓存算法先进先出,大小为512-->
<cache eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"></cache>
二级缓存的测试,两次查询使用两个sqlSession回话
@Test
public void testQueryCache(){
//创建两个SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
//第一个回话查询用户1
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.queryUserById(1);
System.out.println(user1);
sqlSession.close();
//第二个回话查询用户1
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);
sqlSession2.close();
}
在缓存时,需要将对象进行实例化。
Ehcache自定义缓存,导入依赖,添加配置
<dependencies>
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
创建一个ehcache.xml的文件
<?xml version="1.0" encoding = "UTF-8"?>
<ehcache
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="./tmpdit/Tmp_Ehcache"/>
<!--
Mandatory Default Cache configuration. These settings will be applied to caches
created programmtically using CacheManager.add(String cacheName)
-->
<!--
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
在mapper.xml中使用
<!--也可以使用自定义的缓存-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
总结:
注意点:mapper绑定文件时,需要注意使用resource可以在任何位置,使用class时需要保证mapper接口与mapper.xml配置在同一包下
mybatis中的重点包括分页、mybatis二级缓存、动态sql(if、foreach、choose、when、trim)等、#{}表示预编译处理和${}字符串替换。mybatis中的一对多和多对一,以及懒加载(只有关联对象时支持懒加载)、mybatis的好处以及和hibernate的区别。
mybatis与hibernate不同
1.hibernate是一个ORM框架,不需要写sql语句,mybatis需要程序员自己写sql语句,
mybatis通过XML或注解形式灵活配置运行sql语句,将sql执行的结果映射成java对象
2.mybits易学,程序员直接编写原生的sql,适合对关系数据模型要求不高的软件开发,
但是对于不同的数据库,hibernate可以无关数据库
3.hibernate对象/关系映射能力强,数据库无关性好,可以节省很多代码.总之,按照要求的框架,维护性、扩展性良好的软件框架都是好框架xml文件使用命名空间与接口文件进行绑定使用原始的dao接口等进行开发,需要自己传入sqlSessionFactory,每个dao方法中需要自己手动获取opensession对象。
mybatis配置文件的参数顺序是固定的。
mappers映射器:
1.使用resource寻找对应的xml文件,寻找sql语句文件,再找到接口文件
2.使用class类型声明时,只能填写mapper接口类,必须要遵循原则使用同名称的文件名(接口文件与xml文件的类名相同)且在同一包下
3.使用url指定路径,但是必须使用物理路径(不适用)