MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
Mybatis不是一个完全的orm框架,Mybatis需要程序员自己写sql,但是也存在映射(输入参数映射,输出结果映射),学习门槛mybatis比hibernate低;同时灵活性高,特别适用于业务模型易变的项目,使用范围广。
应用场合:在日常的开发项目中,如中小型项目,例如ERP,需求与关系模型相对固定建议使用Hibernate,对于需求不固定的项目,比如:互联网项目,建议使用mybatis,因为需要经常灵活去编写sql语句。
mybatis提供两种配置文件, 核心配置文件 mybatis.xml 与 SQL映射文件mapper.xml。
db.properties配置文件:
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:XE
username=SCOTT
password=TIGER
mybatis.xml文件配置内容:
<configuration>
<properties resource="db.properties" />
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
<typeAliases>
<package name="com.pojo"/>
typeAliases>
<environments default="ev">
<environment id="ev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver"
value="${driver}"/>
<property name="url"
value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/mappers/deptmapper.xml"/>
<mapper resource="com/mappers/deptmapper2.xml"/>
<mapper resource="com/mappers/empmapper.xml"/>
<mapper resource="com/mappers/deptmapper3.xml"/>
mappers>
configuration>
定义Dept类javabean:
private Integer deptno;
private String dname;
private String loc;
deptmapper(sql映射文件):
<mapper namespace="com.mappers.deptmapper">
<select id="queryAll" resultType="Dept">
select * from dept
select>
<select id="querybydeptno" parameterType="int" resultType="dept">
select * from dept where deptno = #{deptno}
select>
mapper>
测试代码:
import com.pojo.Dept;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
public class TestDept01 {
public static void main(String[] args) throws IOException {
//1.加载执行核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis.xml");
//2.构建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//3.根据工厂获取回话
SqlSession session = factory.openSession();
//4.执行指定的sql
//selectList("命名空间.id")
List<Dept> list = session.selectList("com.mappers.deptmapper.queryAll");
//selectOne("命名空间.id")
//selectOne("命名空间.id",入参)
Dept d1 = session.selectOne("com.mappers.deptmapper.querybydeptno",20);
//selectMap("命名空间.id","作为key的字段名")
//selectMap("命名空间.id",入参,"作为key的字段名")
Map<Integer,Dept> map = session.selectMap("com.mappers.deptmapper.queryAll",10,"deptno");
//5.处理数据
list.forEach(System.out::println);
System.out.println(d1);
System.out.println(map);
//6.关闭回话
session.close();
}
}
入参类型(parameterType)包括基本数据类型及其包装类 String Date Javabean Map List 数组 …
结果类型(resultType)包括基本数据类型及其包装类 String Date JavaBean List Map List
具体通过代码来进行演示:
deptmapper2(sql映射文件):
<mapper namespace="com.mappers.deptmapper2">
<select id="queryallbydeptno" parameterType="int" resultType="Dept">
select * from dept where deptno = #{deptno}
select>
<select id="querydeptbydname" parameterType="string" resultType="Dept">
select * from dept where dname = #{dname}
select>
<select id="querybynoname" parameterType="Dept" resultType="Dept">
select * from dept where deptno = #{deptno} and dname = #{dname}
select>
<select id="querybydeptnos" resultType="Dept">
select * from dept where deptno in (
<foreach collection="array" item="item" separator=",">
#{item}
foreach>
)
select>
<select id="querybynos" parameterType="list" resultType="Dept">
select * from dept where deptno in (
<foreach collection="list" item="item" separator=",">
#{item}
foreach>
)
select>
<select id="querybynoorname" parameterType="map" resultType="Dept">
select * from dept where dname = #{dname} or loc = #{loc}
select>
mapper>
测试代码:
import com.pojo.Dept;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestDept02 {
public static void main(String[] args) throws IOException {
SqlSession session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml")).openSession();
//测试入参为基本数据类型|包装类
Dept d2 = session.selectOne("com.mappers.deptmapper2.queryallbydeptno",10);
System.out.println(d2);
//测试入参为String类型
List<Dept> list = session.selectList("com.mappers.deptmapper2.querydeptbydname","SALES");
System.out.println(list);
//测试入参为javabean类型
Dept d1 = session.selectOne("com.mappers.deptmapper2.querybynoname",new Dept(20,"RESEARCH",null));
System.out.println(d1);
//测试入参为数组类型
int[] arr = {
20,30,40};
List<Dept> list2 = session.selectList("com.mappers.deptmapper2.querybydeptnos",arr);
System.out.println(list2);
//测试入参为List类型
List<Dept> list3 = session.selectList("com.mappers.deptmapper2.querybynos",List.of(10,20));
System.out.println(list3);
//测试入参为Map类型
Map<String,Object> map = new HashMap<>();
map.put("dname","RESEARCH");
map.put("loc","NEW YORK");
List<Dept> list4 = session.selectList("com.mappers.deptmapper2.querybynoorname",map);
System.out.println(list4);
session.close();
}
}
定义Emp类javabean:
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Integer sal;
private Integer comm;
private Integer deptno;
empmapper(sql映射文件):
<mapper namespace="com.mappers.empmapper">
<select id="queryallbyhiredate" parameterType="date" resultType="Emp">
select * from emp where hiredate = #{hiredate}
select>
<select id="querysalbyempno" parameterType="int" resultType="int">
select sal from emp where empno = #{empno}
select>
<select id="queryenamebynamelike" parameterType="string" resultType="string">
select ename from emp where ename like '%'||#{ename}||'%'
select>
<select id="queryhiredatebyempno" parameterType="int" resultType="date">
select hiredate from emp where empno = #{empno}
select>
<select id="queryenameandsalbyempno" parameterType="int" resultType="Emp">
select ename,sal from emp where empno = #{empno}
select>
<select id="queryallbyempno" parameterType="int" resultType="map">
select * from emp where empno = #{empno}
select>
<select id="queryallbydeptno" parameterType="int" resultType="map">
select * from emp where deptno = #{deptno}
select>
mapper>
测试代码:
import com.pojo.Emp;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class TestEmp01 {
public static void main(String[] args) throws IOException, ParseException {
SqlSession session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml")).openSession();
//测试入参类型为Date类型
List<Emp> list = session.selectList("com.mappers.empmapper.queryallbyhiredate",new SimpleDateFormat("yyyy/MM/dd").parse("1981/12/3"));
list.forEach(System.out::println);
//测试结果类型为基本数据类型或其包装类
int sal = session.selectOne("com.mappers.empmapper.querysalbyempno",7566);
System.out.println(sal);
//测试结果类型为String
List<String> list2 = session.selectList("com.mappers.empmapper.queryenamebynamelike","A");
list2.forEach(System.out::println);
//测试结果类型为Date
Date date = session.selectOne("com.mappers.empmapper.queryhiredatebyempno",7566);
System.out.println(date);
//测试结果类型为javabean
Emp e1 = session.selectOne("com.mappers.empmapper.queryenameandsalbyempno",7566);
System.out.println(e1);
//测试结果类型为Map类型
Map<String,Object> map = session.selectOne("com.mappers.empmapper.queryallbyempno",7839);
System.out.println(map);
//测试结果为List
List<Map<String,Object>> list3 = session.selectList("com.mappers.empmapper.queryallbydeptno",20);
list3.forEach(System.out::println);
session.close();
}
}
deptmapper3(sql映射文件):
<mapper namespace="com.mappers.deptmapper3">
<insert id="insertdept" parameterType="dept">
insert into dept values (#{deptno},#{dname},#{loc})
insert>
<update id="updatedept" parameterType="string">
update dept set loc = #{loc} where deptno=80
update>
<delete id="deletedept" parameterType="int">
delete from dept where deptno = #{deptno}
delete>
mapper>
测试代码:
import com.pojo.Dept;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
public class TestDept03 {
public static void main(String[] args) throws IOException {
SqlSession session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml")).openSession(true);//自动提交事务
//测试添加数据
int row = session.update("com.mappers.deptmapper3.insertdept",new Dept(80,"bbbb","shanghai"));
if (row>0){
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
//测试修改数据
int row2 = session.update("com.mappers.deptmapper3.updatedept","beijing");
if (row2>0){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
//测试删除数据
int row3 = session.update("com.mappers.deptmapper3.deletedept",80);
if (row3>0){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
session.close();
}
}
日志分为五个级别:DEBUG(人为调试信息)、INFO(普通信息)、WARN(警告)、ERROR(错误) 和 FATAL(系统错误)
这五个级别是有顺序的,DEBUG < INFO < WARN < ERROR < FATAL,分别用来指定这条日志信息的重要程度,Log4j的规则是只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR和FATAL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。
Log4J配置文件:
# Set root category priority to INFO and its only appender to CONSOLE.
# 输出到控制台(普通语句执行是不输出debug日志)
# 提高整体日志级别为ERROR
log4j.rootCategory=ERROR, CONSOLE
# 单独设置SQL语句的输出级别为DEBUG级别
# 包级别
log4j.logger.com.mappers=DEBUG
# 输出到控制台和日志文件
#log4j.rootCategory=INFO, CONSOLE, LOGFILE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
# 日志文件路径
log4j.appender.LOGFILE.File=E:/java code/log4j/log4j.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=- %m %l%n
Myabtis中,提供了一套接口绑定方案,程序员可以提供一个接口,然后提供一个与接口所对应的SQL映射文件,Myabaits会自动将接口与xml文件进行绑定。根据接口和对应的xml文件会创建一个接口的实现类和对象,方便方法的调用。
SQL映射文件与指定接口绑定的规则:
mybatis配置文件:
<configuration>
<properties resource="db.properties" />
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
<typeAliases>
<package name="com.pojo"/>
typeAliases>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<package name="com.mappers"/>
mappers>
configuration>
封装工具类获得SqlSession:
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 java.io.IOException;
//获取会话的工具类
public class SessionUtils {
//factory-> SqlSessionFactory是单例的
private static SqlSessionFactory factory = null;
static {
try {
factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
//获取会话
public static SqlSession getSession(){
SqlSession session = null;
if(factory!=null){
session = factory.openSession(true); //自动提交
}
return session;
}
}
定义接口:
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface EmpMapper {
//测试不传参数
List<Emp> queryAllEmp();
//测试传入一个参数
Emp queryAllbyEmpno(int empno);
//测试传入两个相同类型的参数
List<Emp> queryAllbydeptnoandsal(int deptno,int sal);
//测试传入两个不同类型的参数
List<Emp> queryAllbyjobandsal(@Param("job") String job, @Param("sal") int sal);
//测试增加数据
int insertEmp(@Param("empno") int empno,@Param("ename") String ename,@Param("sal") int sal);
//测试修改数据
int updateEmp(@Param("sal") int sal,@Param("empno") int empno);
//测试删除数据
int deleteEmp(@Param("empno") int empno);
}
绑定的sql映射文件:
<mapper namespace="com.mappers.EmpMapper">
<select id="queryAllEmp" resultType="emp">
select * from emp
select>
<select id="queryAllbyEmpno" parameterType="int" resultType="emp">
select * from emp where empno = #{param1}
select>
<select id="queryAllbydeptnoandsal" resultType="emp">
select * from emp where deptno=#{param1} and sal>#{param2}
select>
<select id="queryAllbyjobandsal" resultType="emp">
select * from emp where job=#{job} and sal>=#{sal}
select>
<insert id="insertEmp">
insert into emp(empno,ename,sal) values(#{empno},#{ename},#{sal})
insert>
<update id="updateEmp">
update emp set sal=#{sal} where empno=#{empno}
update>
<delete id="deleteEmp">
delete from emp where empno=#{empno}
delete>
mapper>
测试代码:
import com.mappers.EmpMapper;
import com.pojo.Emp;
import com.utils.SessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
//测试接口绑定方案的使用
public class EmpTest01 {
public static void main(String[] args) {
//1.获取会话
SqlSession session = SessionUtils.getSession();
//2.获取接口的实现类对象
EmpMapper empMapper = session.getMapper(EmpMapper.class);
//3.调用方法
//测试不传参数
List<Emp> list = empMapper.queryAllEmp();
list.forEach(System.out::println);
//测试传入一个参数
Emp e = empMapper.queryAllbyEmpno(7839);
System.out.println(e);
//测试传入两个相同类型的参数
List<Emp> list1 = empMapper.queryAllbydeptnoandsal(20,1000);
list1.forEach(System.out::println);
//测试传入两个不同类型的参数
List<Emp> list2 = empMapper.queryAllbyjobandsal("SALESMAN",1500);
list2.forEach(System.out::println);
//测试增加数据
int row1 = empMapper.insertEmp(9999,"zhangsan",10000);
System.out.println(row1>0?"添加成功":"添加失败");
//测试修改数据
int row2 = empMapper.updateEmp(5000,9999);
System.out.println(row2>0?"修改成功":"修改失败");
//测试删除数据
int row3 = empMapper.deleteEmp(9999);
System.out.println(row3>0?"删除成功":"删除失败");
//4.关闭
session.close();
}
}
定义接口:
import com.pojo.Emp;
import java.util.List;
public interface EmpMapper2 {
//批量添加数据
int insertEmpSome(List<Emp> list);
//批量修改数据
int updateEmpSome(List<Emp> list);
//批量删除数据
int deleteEmpSome(List<Integer> list);
}
绑定的sql映射文件:
<mapper namespace="com.mappers.EmpMapper2">
<insert id="insertEmpSome">
insert into emp(empno,ename,sal)
<foreach collection="list" item="item" separator="union">
select #{item.empno},#{item.ename},#{item.sal} from dual
foreach>
insert>
<update id="updateEmpSome">
begin
<foreach collection="list" item="item" separator=";">
update emp set sal=#{item.sal} where empno=#{item.empno}
foreach>
;end;
update>
<delete id="deleteEmpSome">
delete from emp where empno in
<foreach collection="list" item="item" separator="," open="(" close=")">
#{item}
foreach>
delete>
mapper>
测试代码:
import com.mappers.EmpMapper2;
import com.pojo.Emp;
import com.utils.SessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class EmpTest02 {
public static void main(String[] args) {
SqlSession session = SessionUtils.getSession();
EmpMapper2 empMapper = session.getMapper(EmpMapper2.class);
//测试批量添加数据
empMapper.insertEmpSome(List.of(
new Emp(1111,"张三",10000),
new Emp(2222,"李四",20000),
new Emp(3333,"王五",30000)
));
//测试批量修改数据
empMapper.updateEmpSome(List.of(
new Emp(1111,15000),
new Emp(2222,25000)
));
//测试批量删除数据
empMapper.deleteEmpSome(List.of(1111,2222,3333));
session.close();
}
}
用于进行条件判断,test 属性用于指定判断条件,为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件
<select id="sel" resultType="user">
select * from t_user where 1=1
<if test="username != null and username != ''">
and username=#{username}
if>
<if test="password != null and password != ''">
and password=#{password}
if>
select>
用于管理 where 子句,有如下功能:
<select id="sel" resultType="user">
select * from t_user
<where>
<if test="username != null and username != ''">
and username=#{username}
if>
<if test="password != null and password != ''">
and password=#{password}
if>
where>
select>
功能类似于javase中的switch…case…语句
<select id="sel" resultType="user">
select * from t_user
<where>
<choose>
<when test="username != null and username != ''">
and username = #{username}
when>
<when test="password != null and password != ''">
and password = #{password}
when>
<otherwise> and 1=1 otherwise>
choose>
where>
select>
用于维护update语句中的set语句,功能如下:
<update id="updUser" parameterType="user">
update t_user
<set>
id=#{id},
<if test="username != null and username != ''">
username=#{username},
if>
<if test="password != null and password != ''">
password=#{password},
if>
set>
where id=#{id}
update>
用于在前后添加或删除一些内容,功能如下:
<update id="updUser" parameterType="user">
update t_user
<trim prefix="set" prefixOverrides="user" suffix="hahaha"
suffixOverrides=","> username=#{username},
trim>
where id=#{id}
update>
对于数据进行再加工,一般用于模糊查询
<select id="sel" resultType="user">
select * from t_user
<where>
<if test="username!=null and username!=''">
<bind name="username" value="'%' + username + '%'" />
and username like #{username}
if>
where>
select>
用于在SQL语句中遍历集合参数,在in查询中使用:
用于提取SQL语句,include用于引用SQL语句
<sql id="mySql"> id, username, password sql>
<select id="selIn" parameterType="list" resultType="user">
select
<include refid="mySql" />
from t_user where id in
<foreach collection="list" open="(" separator="," close=")"
item="item"> #{item}
foreach>
select>
例:
定义接口:
import com.pojo.Emp;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface EmpMapper3 {
//测试where,if
List<Emp> queryTest(@Param("empno") Integer empno, @Param("deptno") Integer deptno);
//测试choose...when...otherwise
List<Emp> queryTestChoose(@Param("empno") Integer empno,@Param("deptno") Integer deptno);
//测试trim
List<Emp> queryTestTrim(@Param("deptno") Integer deptno);
//测试bind
List<Emp> queryEmpLike(@Param("s") String s);
}
绑定的sql映射文件:
<mapper namespace="com.mappers.EmpMapper3">
<sql id="allField">
empno,ename,mgr,hiredate,sal,comm,deptno
sql>
<select id="queryTest" resultType="emp">
select <include refid="allField"/> from emp
<where>
<if test="empno!=null and empno!=0">
and empno=#{empno}
if>
<if test="deptno!=null and deptno!=0">
and deptno=#{deptno}
if>
where>
select>
<select id="queryTestChoose" resultType="emp">
select <include refid="allField"/> from emp
<where>
<choose>
<when test="empno!=null and empno!=0">
and empno=#{empno}
when>
<when test="deptno!=null and deptno!=0">
and deptno=#{deptno}
when>
<otherwise>
and 1=1
otherwise>
choose>
where>
select>
<select id="queryTestTrim" resultType="emp">
select <include refid="allField"/> from emp
<trim prefix="where">
deptno=#{deptno}
trim>
select>
<select id="queryEmpLike" resultType="emp">
select <include refid="allField"/> from emp
<trim prefix="where">
<bind name="s" value="'%'+s+'%'"/>
ename like #{s}
trim>
select>
mapper>
测试代码:
import com.mappers.EmpMapper3;
import com.pojo.Emp;
import com.utils.SessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
//测试动态SQL
public class EmpTest03 {
public static void main(String[] args) {
SqlSession session = SessionUtils.getSession();
EmpMapper3 empMapper = session.getMapper(EmpMapper3.class);
测试where,if
List<Emp> list = empMapper.queryTest(0,0);
list.forEach(System.out::println);
//测试choose...when...otherwise
List<Emp> list2 = empMapper.queryTestChoose(0,20);
list2.forEach(System.out::println);
//测试trim
List<Emp> list3 = empMapper.queryTestTrim(10);
list3.forEach(System.out::println);
//测试bind
List<Emp> list4 = empMapper.queryEmpLike("A");
list4.forEach(System.out::println);
session.close();
}
}
<select id="selAll" resultType="user">
select id id1, username username1, password password2 from t_user
select>
<resultMap type="user" id="umap">
<id column="id" property="id1" />
<result column="username" property="username1" />
<result column="password" property="password1" />
resultMap>
<select id="selAll" resultMap="umap"> select * from t_user select>
数据库中的表有着一对一,一对多,多对多等关系,如果实现表连接得到数据,需要在对应类中定义另一个类的对象为成员变量。
以Emp表与Dept表为例,每一个员工有自己的部门,一个部门有很多的员工,如果想查询部门信息及部门员工信息时就需要关系映射查询。
实现查询部门信息及部门中员工的信息:
Dept类javabean:
private Integer deptno;
private String dname;
private String loc;
private List<Emp> emps;
Emp类javabean:
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Integer sal;
private Integer comm;
private Integer deptno;
定义接口:
import com.pojo.Dept;
import java.util.List;
public interface DeptMapper {
//查询所有部门的部门信息和员工信息
List<Dept> queryDept();
}
sql映射文件:
<mapper namespace="com.mappers.DeptMapper">
<resultMap id="mymap" type="dept">
<id property="deptno" column="deptno"/>
<result property="dname" column="dname"/>
<result property="loc" column="loc"/>
<collection property="emps" javaType="list" ofType="emp">
<id property="empno" column="empno"/>
<result property="ename" column="ename"/>
<result property="job" column="job"/>
<result property="mgr" column="mgr"/>
<result property="hiredate" column="hiredate"/>
<result property="sal" column="sal"/>
<result property="comm" column="comm"/>
<result property="deptno" column="deptno"/>
collection>
resultMap>
<select id="queryDept" resultMap="mymap">
select d.deptno,d.dname,d.loc,e.empno,e.ename,e.sal,e.comm from dept d left join emp e on d.deptno=e.deptno
select>
mapper>
测试代码:
import com.mappers.DeptMapper;
import com.pojo.Dept;
import com.utils.SessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class DeptTest {
public static void main(String[] args) {
SqlSession session = SessionUtils.getSession();
DeptMapper mapper = session.getMapper(DeptMapper.class);
List<Dept> list = mapper.queryDept();
list.forEach(System.out::println);
session.close();
}
}
实现查询员工个人信息及其所在部门信息:
Emp类javabean:
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Integer sal;
private Integer comm;
private Integer deptno;
private Dept dept;
Dept类javabean:
private Integer deptno;
private String dname;
private String loc;
定义接口:
import com.pojo.Emp;
import java.util.List;
//查询所有员工的个人信息及其所在部门信息
public interface EmpMapper {
List<Emp> queryEmp();
}
sql映射文件:
<mapper namespace="com.mappers.EmpMapper">
<resultMap id="mymap" type="emp">
<id property="empno" column="empno"/>
<result property="ename" column="ename"/>
<result property="job" column="job"/>
<result property="mgr" column="mgr"/>
<result property="hiredate" column="hiredate"/>
<result property="sal" column="sal"/>
<result property="comm" column="comm"/>
<result property="deptno" column="deptno"/>
<association property="dept" javaType="dept">
<id property="deptno" column="deptno"/>
<result property="dname" column="dname"/>
<result property="loc" column="loc"/>
association>
resultMap>
<select id="queryEmp" resultMap="mymap">
select e.empno,e.ename,e.job,e.mgr,e.sal,e.comm,d.deptno,d.dname,d.loc from emp e join dept d on e.deptno=d.deptno
select>
mapper>
测试代码:
import com.mappers.EmpMapper;
import com.pojo.Emp;
import com.utils.SessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class EmpTest {
public static void main(String[] args) {
SqlSession session = SessionUtils.getSession();
EmpMapper mapper = session.getMapper(EmpMapper.class);
List<Emp> list = mapper.queryEmp();
list.forEach(System.out::println);
session.close();
}
}
二级缓存的应用场景:对于访问多的查询请求并且用户对查询结果实时性要求不高的情况下,可采用mybatis二级缓存,降低数据库访问量,提高访问速度,根据需求可以在cache标签后设置相应的flushInterval(刷新间隔时间),单位为ms
二级缓存的失效条件:
定义接口:
import com.pojo.Emp;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface EmpMapper {
//Select注解
@Select("select * from emp")
List<Emp> queryAll();
@Select("select * from emp where deptno=#{deptno} and sal>=#{sal}")
List<Emp> queryAllByDeptnoSal(@Param("deptno") Integer deptno,@Param("sal") Integer sal);
//Insert注解
@Insert("insert into emp(empno,ename,sal) values(#{empno},#{ename},#{sal})")
int insertEmp(Emp e);
//Update注解
@Update("update emp set sal=#{sal} where empno=#{empno}")
int updateEmp(@Param("sal") Integer sal,@Param("empno") Integer empno);
//Delete注解
@Delete("delete from emp where ename=#{ename}")
int deleteEmp(@Param("ename") String ename);
}
测试代码:
import com.mappers.EmpMapper;
import com.pojo.Emp;
import com.utils.SessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class EmpTest {
public static void main(String[] args) {
SqlSession session = SessionUtils.getSession();
EmpMapper mapper = session.getMapper(EmpMapper.class);
//测试Select注解
List<Emp> list1 = mapper.queryAll();
list1.forEach(System.out::println);
List<Emp> list2 = mapper.queryAllByDeptnoSal(30,1500);
list2.forEach(System.out::println);
//测试Insert注解
int row1 = mapper.insertEmp(new Emp(9999,"张三",10000));
System.out.println(row1>0?"添加成功":"添加失败");
//测试Update注解
int row2 = mapper.updateEmp(15000,9999);
System.out.println(row2>0?"修改成功":"修改失败");
//测试Delete注解
int row3 = mapper.deleteEmp("张三");
System.out.println(row3>0?"删除成功":"删除失败");
session.close();
}
}
代码:
测试One注解:
定义接口:
//测试One注解
import com.pojo.Dept;
import com.pojo.Emp;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface EmpMapper {
@Select("select deptno,dname,loc from dept where deptno=#{deptno}")
List<Dept> queryDept(@Param("deptno") Integer deptno);
@Select("select empno,ename,sal,deptno from emp")
@Results(value = {
@Result(property = "empno",column = "empno",id = true),
@Result(property = "ename",column = "ename"),
@Result(property = "sal",column = "sal"),
@Result(property = "deptno",column = "deptno"),
@Result(property = "dept",one = @One(select = "com.mappers.EmpMapper.queryDept"),column = "deptno")
})
List<Emp> queryAllEmp();
}
测试代码:
//测试One注解
import com.mappers.EmpMapper;
import com.pojo.Emp;
import com.utils.SessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class EmpTest {
public static void main(String[] args) {
SqlSession session = SessionUtils.getSession();
EmpMapper mapper = session.getMapper(EmpMapper.class);
List<Emp> list = mapper.queryAllEmp();
list.forEach(System.out::println);
session.close();
}
}
测试Many注解:
定义接口:
//测试Many注解
import com.pojo.Dept;
import com.pojo.Emp;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface DeptMapper {
@Select("select * from emp where deptno=#{deptno}")
List<Emp> queryEmpByDeptno(@Param("deptno") Integer deptno);
@Select("select * from dept")
@Results(value = {
@Result(property = "deptno",column = "deptno",id = true),
@Result(property = "dname",column = "dname"),
@Result(property = "loc",column = "loc"),
@Result(property = "emps",many = @Many(select = "com.mappers.DeptMapper.queryEmpByDeptno"),column = "deptno")
})
List<Dept> queryAllDept();
}
测试代码:
测试Many注解
import com.mappers.DeptMapper;
import com.pojo.Dept;
import com.utils.SessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class DeptTest {
public static void main(String[] args) {
SqlSession session = SessionUtils.getSession();
DeptMapper mapper = session.getMapper(DeptMapper.class);
List<Dept> list = mapper.queryAllDept();
list.forEach(System.out::println);
session.close();
}
}
mybatis-generator是一款mybatis自动代码生成工具,可以通过配置,快速生成pojo,mapper和xml文件。
官网地址:http://mybatis.org/generator/configreference/xmlconfig.html
generatorConfig.xml文件:
<generatorConfiguration>
<properties resource="db.properties" />
<context id="Tables" targetRuntime="MyBatis3">
<property name="javaFileEncoding" value="UTF-8" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="false" />
commentGenerator>
<jdbcConnection
driverClass="${driver}"
connectionURL="${url}"
userId="${username}"
password="${password}">
jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
javaTypeResolver>
<javaModelGenerator targetPackage="com.pojo"
targetProject="E:\java code\javaworkspace\mybatis05\src">
<property name="constructorBased" value="true"/>
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
javaModelGenerator>
<sqlMapGenerator targetPackage="com.mappers"
targetProject="E:\java code\javaworkspace\mybatis05\src">
<property name="enableSubPackages" value="true" />
sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.mappers" targetProject="E:\java code\javaworkspace\mybatis05\src">
<property name="enableSubPackages" value="true" />
javaClientGenerator>
<table tableName="dept" domainObjectName="Dept"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">table>
<table tableName="emp" domainObjectName="Emp"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
<columnOverride column="empno" javaType="Integer"/>
table>
context>
generatorConfiguration>
启动代码:
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Util {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<>();
boolean overwrite = true;
try {
//指定 逆向工程配置文件
File configFile = new File("src/generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
} catch (Exception e) {
e.printStackTrace();
}
}
}