日志
日志工厂
可以在settings中的logImpl中设置
分为以下几种:
- SLF4J
- LOG4J
- LOG4J2 |
- JDK_LOGGING
- COMMONS_LOGGING
- STDOUT_LOGGING
- NO_LOGGING
在Mybatis中具体使用哪一个日志在设置中指定。
测试加上了一段配置
返回的结果:
log4j
什么是log4j:
- log4j是Apache的一个开源项目,通过它可以把日志输送到控制台、文件以及GUI组件。
- 我们可以控制每一条日志的输出格式
- 可以控制日志的生成级别,更加细致的控制日志的生成级别
- 使用配置文件来进行配置,而不用修改代码
使用方法:
- 先导入maven包
- 再编写配置文件
分页
先回忆一下数据库的分页语句:
-- 如果pageSize为-1表示从startIndex查到最后一个数据,
-- 如果只写了pageSize一个参数,默认从Index为0处查询
select * from table limit startIndex,pageSize
接口代码:
/**
* 通过limit实现分页
* @param map
* @return
*/
List<User> getUserByLimit(Map<String,Integer> map);
mapper.xml:
<select id="getUserByLimit" resultMap="userMap">
select * from user limit #{startIndex},#{pageSize}
</select>
接口测试结果:
测试通过。
注解开发
注解开发可以省去很多配置了,具体代码如下:
package com.mao.dao;
import com.mao.pojo.User;
import org.apache.ibatis.annotations.Select;
public interface UserDao {
//直接在getUserById上加注解并在其中写sql即可实现功能。
@Select("select * from mybatis.user where id = #{id}")
User getUserById(Integer id);
}
mybatis-config.xml中要注意:要做如下配置
<mappers>
<mapper class="com.mao.dao.UserDao"></mapper>
</mappers>
缺陷
上面这种开发方式是有明显缺陷的:正如官网所说,这种方式只能处理简单的语句,而当数据库名与对象属性名不一致或者遇到其他很复杂的情况的时候就不禁用了。一般还是用配置文件的比较多
自动事务与@Param注解
自动事务的开启:
openSession(boolean var),设置var的值为true则默认开启自动事务。
@param注解主要用于映射@Select中的#{xx}的名字,如果是一个基本类型或者String,可以省略。如果有多个就必须加。
mybatis处理多对一
任课老师和学生之间的关系是一对多的,所以其实体类设计可以简化为:
package com.mao.pojo;
import lombok.Data;
import java.util.List;
/**
* 老师类
*/
@Data
public class Teacher {
private Integer id;
private String name;
}
package com.mao.pojo;
import lombok.Data;
/**
* 学生类
*/
@Data
public class Student {
private Integer id;
private Integer age;
private Teacher teacher;
}
有两种方法可以实现:
通过类似子查询的方式实现
<select id="getStudentById" resultMap="StudentTeahcer" resultType="Student">
select * from mybatis.student where id = #{id}
</select>
<!-- resultMap的子标签中,association是对应对象的,collection对应集合 -->
<resultMap id="StudentTeahcer" type="Student">
<association property="teacher" column="tid" javaType="Teacher" select="getTeacherById"/>
</resultMap>
<select id="getTeacherById" resultType="Teacher">
select * from mybatis.teacher where id = #{id}
</select>
我们可以看到通过resultMap来为表和实体类做映射的时候,复杂对象teacher 用了association标签,表明他是通过column的tid来映射成javaType中的Teacher,而具体获得的途径则是在其中嵌套了一个select即getTeacherById,这样就可以把查询所得的teacher表中信息赋予student中的teacher了;
通过类似联表查询获得
<select id="getStudentById" resultType="Student" resultMap="StudentTeacher2">
select
s.id,s.age,t.name tname
from
teacher t,student s
where
s.id = #{id}
and
s.tid = t.id
</select>
<resultMap id="StudentTeacher2" type="Student">
<result column="id" property="id"></result>
<result column="age" property="age"></result>
<association property="teacher" javaType="Teacher">
<result property="id" column="id"></result>
<result property="name" column="tname"></result>
</association>
</resultMap>
动态SQL
动态sql简而言之就是根据不同的情况生成不同的sql。
搭建环境
package com.mao.pojo;
import lombok.Data;
import java.util.Date;
@Data
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private Integer view;
}
package com.mao.dao;
import com.mao.pojo.Blog;
public interface BlogMapper {
/**
* 添加博客
* @return
*/
int insertBlog(Blog blog);
}
<?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.mao.dao.BlogMapper">
<insert id="insertBlog" parameterType="blog">
insert into
mybatis.blog(id,title,author,create_time,view)
values
(#{id},#{title},#{author},#{createTime},#{view})
</insert>
</mapper>
数据库插入:
动态sql之if
@Test
public void queryByTitleAndAuthor(){
SqlSession session = MyUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
Map map = new HashMap();
map.put("title","我哎卿");
map.put("author","童卿");
Blog blog = mapper.queryBlogsByXxx(map);
System.out.println(blog);
}
}
<select id="queryBlogsByXxx" parameterType="map" resultType="blog">
select * from mybatis.blog where 1=1
<if test="title!=null">
and title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</select>
上述写法的问题及改进
上述写法中用了where 1=1,这个写法不是很正规,为了去掉where 1=1就要用到了<where>
标签,这个标签可以做到当前面没有查询条件的时候自动去掉拼接的sql中的and。所以上面的代码也可以写成:
<select id="queryBlogIf" resultType="blog">
select
id,title,author,create_time,view
from
study.blog
<where>
<if test="title!=null">
title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</where>
</select>
我们把测试也改一改:
@Test
public void queryBlogIf(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
//map.put("title","宗汉绝唱");
map.put("author","老武伟");
List<Blog> blogs = mapper.queryBlogIf(map);
System.out.println(blogs);
}catch (Exception e){
e.printStackTrace();
}finally {
sqlSession.close();
}
}
结果:
可以看到执行的sql where之后就是author=?了,所以可以体现该写法的好处。
choose标签的使用
choose就类似于java中的switch,而且每一个判断条件之后都是自带break的;还是以上面的写法举例,我们只是改一下xml就行了,when就是case,otherwise就是default
<select id="queryBlogIf" resultType="blog">
select
id,title,author,create_time,view
from
study.blog
<choose>
<when test="title!=null">
title = #{title}
</when>
<when test="author!=null">
and author = #{author}
</when>
<otherwise>
and view = #{view}
</otherwise>
</choose>
</select>
set
set标签就类似于上面的where标签,用于update的时候设置值。
sql标签
我们都知道java有一个特性就是可复用,而如果有一段sql你也想复用的话,就把它提取出来,放在<sql></sql>
之中即可,举个例子:
<sql id="wuwei">
<if test="title!=null">
title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</sql>
<select id="queryBlogIf" resultType="blog">
select
id,title,author,create_time,view
from
study.blog
<where>
<include refid="wuwei">
</where>
</select>
这样就可以把id为wuwei的sql引入了。