MyBatis学习

MyBatis框架学习

1. 环境搭建

1.1. 工程导入jar包

mybatis-3.5.0.jar

mysql-connector-java-8.0.11.jar

log4j-1.2.17.jar

1.2. mybatis.xml

在src文件夹下生成

transactionManager

  • type=”JDBC” 事务管理使用JDBC原生事务管理方式
  • type=”MANAGED” 事务管理转交给其他容器,使原生JDBC.setAutoMapping(false)

dataSource

  • type=”UNPOOLED” 不使用数据库连接池
  • type=”POOLED” 使用数据库连接池
  • type=”JNDI” java命名目录接口(Java Naming and Directory Inteface)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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>
<!-- 可以生成多个环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<!-- POOLED 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/login?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="mysql123//"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/runaccpeted/mapper/UserMapper.xml"/>
</mappers>
</configuration>

1.3. UserMapper.java

在com.runaccpeted.mapper包下新建

1
2
3
4
5
6
7
8
package com.runaccpeted.mapper;

import java.util.List;
import com.runaccpeted.pojo.User;

public interface UserMapper {
List<User> selAll();
}

1.4. UserMapper.xml

1
2
3
4
5
6
7
8
9
10
11
<?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">
<!-- namespace 类全路径 -->
<mapper namespace="com.runaccpeted.mapper.UserMapper">
<!-- id:方法名 resultType返回值类型-->
<select id="selAll" resultType="com.runaccpeted.pojo.User">
select * from user
</select>
</mapper>

在mybatis.xml中配置mappers

1
2
3
<mappers>
<mapper resource="com/runaccpeted/mapper/UserMapper.xml"/>
</mappers>

1.5. 测试连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {

try {
//配置文件加载
InputStream in = Resources.getResourceAsStream("mybatis.xml");
//工厂设计模式
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//生产SqlSession
SqlSession session = factory.openSession();
//查询 -- List
List<User> list=session.selectList("selAll");
for (User user:list) {
System.out.println(user);
}
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}

2. 查询三种方式

2.1. selectList

返回List类型的所有表信息

1
2
3
<select id="selAll" resultType="com.runaccpeted.pojo.User">
select * from user
</select>
1
2
3
4
5
//查询
List<User> list=session.selectList("selAll");
for (User user:list) {
System.out.println(user);
}

2.2. selectOne

返回的是Integer或一行数据

1
2
3
4
5
6
7
<select id="selCount" resultType="int">
select count(*) from user
</select>

<select id="selById" parameterType="int" resultType="com.runaccpeted.pojo.User">
select * from user where id=#{0}
</select>

测试

1
2
3
4
5
int count=session.selectOne("selCount");
System.out.println(count);

User u= session.selectOne("selById",1);
System.out.println(u);

2.3. selectMap

把数据库中选中的列的值当作map的key,返回类型由resultType控制

1
2
3
<select id="selsome" resultType="com.runaccpeted.pojo.User">
select * from user
</select>

Map<key, resultType>

1
2
3
4
5
6
Map<Object, Object> map=session.selectMap("selsome", "id");

Set<Object> key=map.keySet();
for (Object obj : key) {
System.out.println(obj+" "+map.get(obj));
}

3. log4j支持

日志处理类库,可以输出数据到控制台和文件

fatal致命错误 error warning info debug

1
2
3
4
import org.apache.log4j.Logger;

Logger log =Logger.getLogger(Main.class);
log.info("");

3.1. settings

修改mybatis运行时的行为方式

在mybatis.xml中添加配置

1
2
3
4
5
6
7
8
9
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<environments>
</environments>
<mappers>
</mappers>
</configuration>

3.2. log4j.properties

文件位于src下

log4j.logger.com.runaccpeted.mapper 对应于UserMapper.xml中mappers的namespace 类全路径

1
2
3
4
5
6
7
8
9
10
11
12
13
log4j.rootCategory=ERROR, CONSOLE,LOGFILE
log4j.logger.com.runaccpeted.mapper=DEBUG

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=-%p-%d{yyyy/MM/dd HH:mm:ss,SSS}-%l-%L-%m%n


log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=src/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=-%p-%d{yyyy/MM/dd HH:mm:ss,SSS}-%l-%L-%m%n

UserMapper.xml

1
<mapper namespace="com.runaccpeted.mapper">

使得仅输出sql语句

1
2
3
Preparing: select * from user
Parameters:
Total: 10

4. parameterType参数

4.1. #{0}

采用的是占位符语法 PreparedStatement

#{0} 表示第一个参数

1
2
3
<select id="selById" resultType="com.runaccpeted.pojo.User" parameterType="int">
select * from user where id=#{0}
</select>
1
2
User user=session.selectOne("selById",1);
System.out.println(user);

4.2. #{param1}

#{param1}表示第一个参数

1
2
3
<select id="selById" resultType="com.runaccpeted.pojo.User" parameterType="int">
select * from user where id=#{param1}
</select>

4.3. #{id}

获取参数的内容支持,索引获取,param1获取来指定位置参数,并且SQL使用?占位符

只有一个参数是基本数据类型或String时,对#{}内没有要求只要写内容

参数为对象时,写#{属性名}

参数为map时,写#{key}

1
2
3
4
5
6
7
8
<select id="selById" resultType="com.runaccpeted.pojo.User" parameterType="int">
select * from user where id=#{id}
</select>


<select id="selByName" parameterType="map" resultType="User">
select * from user where username=#{username}
</select>

打印

1
2
3
4
5
6
HashMap<String, String> map=new HashMap<>();
map.put("username", "abc");
List<User> users = session.selectList("selByName",map);
for (User u : users) {
System.out.println(u.getId()+" "+ u.getUsername()+" "+u.getPassword());
}

4.4. ${id}

字符串拼接不使用?,查找参数对象的get/set方法,若参数为数据则直接输出数字

1
2
3
<select id="selById" resultType="com.runaccpeted.pojo.User" parameterType="com.runaccpeted.pojo.User">
select * from user where id=${id}
</select>

5. 实现分页查询

select * from user limit 0,2;

从0开始,查询2行

1
2
3
<select id="selById" resultType="com.runaccpeted.pojo.User" parameterType="map">
select * from user limit #{pageStart},#{pageSize}
</select>

参数

1
2
3
4
5
6
7
8
9
10
11
12
13
//第几页
int pageNumber=1;
//每页几个
int pageSize=2;
//传参
HashMap<String, Integer> map = new HashMap();
map.put("pageSize", pageSize);
map.put("pageStart", pageSize*(pageNumber-1));

List<User> user=session.selectList("selById",map);
for(User u:user){
System.out.println(u);
}

6. 设置别名

在mybatis.xml中

1
2
3
4
<!-- 设置别名 单个-->
<typeAliases>
<typeAlias type="com.runaccpeted.pojo.User" alias="User"/>
</typeAliases>
1
2
3
4
<!-- 设置别名 整个包-->
<typeAliases>
<package name="com.runaccpeted.pojo"/>
</typeAliases>

别名应用在UserMapper.xml中,直接为类名

1
2
3
<select id="selAll" resultType="User">
select * from user
</select>

7. 新增

mybatis默认关闭JDBC的自动提交功能

session.commit() 提交事务

openSession(true) 自动提交

默认返回值为int 返回的是影响几行

1
2
3
<insert id="insert" parameterType="User">
insert into user values(default,#{username},#{password})
</insert>

测试

1
2
3
4
5
6
7
8
9
10
11
12
try{
User us = new User();
us.setUsername("abc");
us.setPassword("1234");

int count =session.insert("ins", us);
session.commit();
System.out.println(count);
}catch(Exception e){
//实现事务回滚
session.rollback();
}

log4j:

1
2
3
Preparing: insert into user values(default,?,?) 
Parameters: abc(String), 1234(String)
Updates: 1

8. 修改

1
2
3
<update id="update" parameterType="User">
update user set username=#{username} where id=#{id}
</update>
1
2
3
4
5
6
User user = new User();
user.setUsername("abc");
user.setId(1);

session.update("update", user);
session.commit();
1
2
3
Preparing: update user set username=? where id=? 
Parameters: abc(String), 1(Integer)
Updates: 1

9. 删除

1
2
3
<delete id="delete" parameterType="int">
delete from user where id=#{0}
</delete>
1
2
session.delete("delete",6);
session.commit();
1
2
3
Preparing: delete from user where id=? 
Parameters: 6(Integer)
Updates: 1

10. getMapper(class)

代理模式 mybatis.xml 下添加package属性

1
2
3
<mappers>
<package name="com.runaccpeted.mapper"/>
</mappers>

对应于UserMapper.xml mapper的package的namespace为具体接口实现类

1
2
3
4
5
<mapper namespace="com.runaccpeted.mapper.UserMapper">
<select id="selAll" resultType="com.runaccpeted.pojo.User">
select * from user
</select>
</mapper>

在同一包下创建接口UserMapper 方法一一对应于UserMapper.xml中的select id

1
2
3
public interface UserMapper {
List<User> selAll();
}

测试使用getMapper

UserMapper mapper =session.getMapper(UserMapper.class);

1
2
3
4
5
6
7
8
9
10
11
12
//配置文件加载
InputStream in = Resources.getResourceAsStream("mybatis.xml");
//工厂设计模式 + 构建者设计模式
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//生产SqlSession
SqlSession session = factory.openSession();

UserMapper mapper =session.getMapper(UserMapper.class);
List<User> user = mapper.selAll();
for(User u:user){
System.out.println(u);
}

10.1. 多参数传递

1
User selectByNamePwd(String name,String pwd);

使用#{param1} #{param2}

1
2
3
<select id="selectByNamePwd" resultType="User">
select * from user where username=#{param1} and password=#{param2}
</select>

当希望使用方法参数name,pwd时,使用的是map的键值对方法

1
User selectByNamePwd(@Param("name") String name,@Param("pwd") String pwd);
1
2
3
<select id="selectByNamePwd" resultType="User">
select * from user where username=#{name} and password=#{pwd}
</select>

11. 动态SQL

11.1. if

< if test=”name!=null and name!=’’ “> 直接写判断

1
2
3
4
5
6
7
8
9
<select id="selectByNamePwd" resultType="User">
select * from user where 1=1
<if test="name!=null and name!='' ">
and username=#{name}
</if>
<if test="pwd!=null and pwd!='' ">
and password=#{pwd}
</if>
</select>

调用 mapper.selectByNamePwd(“”, “123”);

select * from user where 1=1 and password=?

调用 mapper.selectByNamePwd(“wt1”, “”);

select * from user where 1=1 and username=?

11.2. where

去掉第一个and自动生成and

1
2
3
4
5
6
7
8
9
10
11
<select id="selectByNamePwd" resultType="User">
select * from user
<where>
<if test="name!=null and name!='' ">
and username=#{name}
</if>
<if test="pwd!=null and pwd!='' ">
and password=#{pwd}
</if>
</where>
</select>

调用 mapper.selectByNamePwd(“wt1”, “123”);

select * from user WHERE username=? and password=?

11.3. choose,when, otherwise

只要有一个成立,其他不执行

1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="selectByNamePwd" resultType="User">
select * from user
<where>
<choose>
<when test="name!=null and name!='' ">
and username=#{name}
</when>
<when test="pwd!=null and pwd!='' ">
and password=#{pwd}
</when>
</choose>
</where>
</select>

调用 mapper.selectByNamePwd(“wt1”, “123”);

select * from user WHERE username=?

11.4. set

去掉最后一个逗号,填写set

id=#{id}, 防止 username,password都为null时不生成update语句

1
2
3
4
5
6
7
8
9
10
11
12
13
<update id="update" parameterType="User">
update user
<set>
id=#{id},
<if test="username!=null and username!='' ">
username=#{username},
</if>
<if test="password and password!='' ">
password=#{password}
</if>
</set>
where id=#{id}
</update>

调用

1
2
3
4
5
6
7
User user = new User();
user.setUsername("qw");
user.setPassword("12345");
user.setId(2);

mapper.update(user);
session.commit();

update user SET id=?,username=?, password=? where id=?

11.5. trim

prefix 前面加上

prefixOverrides 前面去掉

suffix 后面加上

suffixOverrides 后面去掉

select * from user where id=?

1
2
3
4
5
6
<select id="selById" resultType="User">
select * from user
<trim prefix="where" prefixOverrides="and">
and id=#{id}
</trim>
</select>

11.6. bind

适合于模糊查询

< bind name=”name” value=”name+’%’”/>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<select id="selectByNamePwd" resultType="User">
<bind name="name" value="name+'%'"/>
select * from user
<where>
<choose>
<when test="name!=null and name!='' ">
and username like #{name}
</when>
<when test="pwd!=null and pwd!='' ">
and password like #{pwd}
</when>
</choose>
</where>
</select>

select * from user WHERE username like ?

11.7. forEach

多用于in查询

select * from user where id in ( ? , ? )

1
2
3
4
5
6
<select id="selectById" resultType="User">
select * from user where id in
<foreach collection="list" item="u" open="(" close=")" separator=",">
#{u}
</foreach>
</select>

传入的是list

1
2
3
4
5
6
7
8
9
10
UserMapper mapper =session.getMapper(UserMapper.class);

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(3);

List<User> user = mapper.selectById(list);
for(User u:user){
System.out.println(u);
}

11.7.1. 批量新增

insert into user values (default,?,?), (default,?,?)

1
2
3
4
5
6
7
8
<insert id="insert" parameterType="list">
insert into user values
<trim suffixOverrides=",">
<foreach collection="list" item="user">
(default,#{user.username},#{user.password}),
</foreach>
</trim>
</insert>

实现批量处理

在SqlSession 执行类型设置为

SqlSession session = factory.openSession(ExecutorType.BATCH);

等价于

PerparedStatement.addBatch();

1
2
3
4
5
6
7
8
9
10
11
ArrayList<User> list = new ArrayList<User>();

for(int i=0;i<10;i++){
User user = new User();
user.setUsername("wt"+i);
user.setPassword("123");
list.add(user);
}

int insert = mapper.insert(list);
session.commit();

11.8. sql

定义sql代码段

1
2
3
<sql id="mysql">
id,username,password
</sql>

复用

1
2
3
<select id="selAll" resultType="User">
select <include refid="mysql"></include> from user
</select>

12. 缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.runaccpeted.util;

import java.io.IOException;
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;


public class MyBatisUtil {

private static SqlSessionFactory factory;
private static ThreadLocal<SqlSession> tl = new ThreadLocal<>();
static {
try {
InputStream in = Resources.getResourceAsStream("mybatis.xml");
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSession() {
SqlSession session= tl.get();
if (session==null) {
session=factory.openSession();
}
return session;
}
public static void CloseSession() {
SqlSession session = tl.get();
if (session!=null) {
session.close();
}
}

}

减少与数据库的交互,提升程序运行效率

mybatis 默认缓存开启

  • 同一个SqlSession对象调用同一个< select>时,只有第一次访问数据库,以后会把查询结果放在SqlSession缓存区中
  • 缓存的是statement对象,一个select对应一个statement
  • 有效范围为同一个SqlSession对象

12.1. 二级缓存

SqlSessionFactory 缓存

同一个factory内SqlSession都可以获取

当数据频繁被使用时,很少被修改

使用二级缓存在UserMapper.xml中添加

1
<cache readOnly="true"></cache>

当SqlSession对象close()时或commit()时,会把缓存数据flush到SqlSesisonFactory缓存区中

13. 多表联合

13.1. 单表resultMap

1
2
3
4
5
6
7
public class User {

private int id;
private String username;
private String password;
private int tId;
}

resultMap的id对应于select的resultMap

column和property可以不同

1
2
3
4
5
6
7
8
9
10
11
12
<resultMap type="User" id="usermap">
<!-- 主键使用id标签配置映射关系 -->
<!-- column列名 property 属性名-->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="tId" property="tId"/>
</resultMap>

<select id="selectAll" resultMap="usermap">
select * from user
</select>

结果仍为查询所有信息

1
2
3
4
List<User> users=session.selectList("selectAll");
for (User user : users) {
System.out.println(user);
}

13.2. 多表resultMap – 单个对象

在User类中包含Teacher类

1
2
3
4
5
6
7
8
9
10
11
12
13
public class User {

private int id;
private String username;
private String password;
private int tId;
private Teacher teacher;
}

public class Teacher {
private int id;
private String tname;
}

13.2.1. 联合查询

association 表示关联外部的一个对象

property 在类中的关联对象名

select 外部查询语句

column 关联的tId主键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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.runaccpeted.mapper.UserMapper">
<resultMap type="User" id="userT">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="tId" property="tId"/>
<association property="teacher" select="com.runaccpeted.mapper.TeacherMapper.selById" column="tId">
<id column="id" property="id"/>
<result column="tname" property="tname"/>
</association>
</resultMap>
<select id="selWithT" resultMap="userT">
select * from user
</select>
</mapper>

对于teacher来说仍然是按id查询

1
2
3
4
5
6
7
8
9
<?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.runaccpeted.mapper.TeacherMapper">
<select id="selById" resultType="Teacher" parameterType="int">
select * from teacher where id=#{0}
</select>
</mapper>

13.2.2. 出错

 Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.runaccpeted.mapper.TeacherMapper.selById

mybatis.xml中的mapper设置

1
2
3
<mappers>
<package name="com.runaccpeted.mapper"/>
</mappers>

实现TeacherMapper接口

1
2
3
4
5
6
7
8
package com.runaccpeted.mapper;

import com.runaccpeted.pojo.Teacher;

public interface TeacherMapper {
Teacher selById(int id);

}

或者设置mybatis.xml

1
2
3
4
<mappers>
<mapper resource="com/runaccpeted/mapper/UserMapper.xml"/>
<mapper resource="com/runaccpeted/mapper/TeacherMapper.xml"/>
</mappers>

13.2.3. 结果

1
2
3
4
List<User> users=mapper.selWithT();
for (User user : users) {
System.out.println(user);
}

13.2.4. 左外连接

结果一致

1
2
3
4
<select id="selT" resultType="User">
select t.id `teacher.id`,t.tname `teacher.tname`,u.id id,username,password,tId
from user u left join teacher t on u.tId=t.id;
</select>

13.3. 多表resultMap–集合

一个teacher对应多个user

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Teacher {

private int id;
private String tname;
private List<User> list;

@Override
public String toString() {
String str= "Teacher [id=" + id + ", tname=" + tname + ", user=" ;
str+="\n";
for (User user : list) {
str+=user+"\n";
}
str+="]";
return str;
}
}

13.3.1. TeacherMapper.xml

collection对应多个对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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.runaccpeted.mapper.TeacherMapper">
<resultMap type="Teacher" id="TeacherUser">
<id column="id" property="id"/>
<result column="tname" property="tname"/>
<collection property="list" select="com.runaccpeted.mapper.UserMapper.selById" column="id">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
</collection>
</resultMap>
<select id="selAll" resultMap="TeacherUser">
select * from teacher;
</select>
</mapper>

13.3.2. UserMapper.xml

查询对应user表中的tId

1
2
3
4
5
6
7
8
9
<?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.runaccpeted.mapper.UserMapper">
<select id="selById" parameterType="int" resultType="User">
select * from user where tId=#{0}
</select>
</mapper>

13.3.3. 接口

1
2
3
4
5
6
7
public interface UserMapper {
User selById(int id);
}

public interface TeacherMapper {
List<Teacher> selAll();
}

13.3.4. 结果

1
2
3
4
5
TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
List<Teacher> teacher=teacherMapper.selAll();
for (Teacher teacher2 : teacher) {
System.out.println(teacher2);
}

Console

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Teacher [id=1, tname=abc, user=
User [id=1, username=abc, password=123, teacher=null]
User [id=3, username=a, password=123456, teacher=null]
User [id=4, username=abcd, password=123456, teacher=null]
]
Teacher [id=2, tname=qw, user=
User [id=7, username=w1, password=123, teacher=null]
User [id=43, username=abc, password=1234, teacher=null]
]
Teacher [id=3, tname=wt1, user=
User [id=8, username=ww1, password=123, teacher=null]
User [id=9, username=wt9, password=123, teacher=null]
User [id=41, username=aaaaaa, password=123, teacher=null]
]
Teacher [id=4, tname=张三1, user=
User [id=39, username=a, password=123, teacher=null]
User [id=40, username=aaaaaa, password=123, teacher=null]
]

13.4. 左外连接

自动合并老师信息

1
2
3
4
5
6
7
8
9
10
11
12
13
<resultMap type="Teacher" id="map1">
<id column="tid" property="id"/>
<result column="tname" property="tname"/>
<collection property="list" ofType="user">
<id column="uid" property="id"/>
<result column="sname" property="username"/>
<result column="pass" property="password"/>
<result column="tId" property="tId"/>
</collection>
</resultMap>
<select id="TwithU" resultMap="map1">
select t.id tid,t.tname tname,u.id uid,u.username sname,u.password pass,tId from teacher t left join user u on t.id=u.tId;
</select>

14. 注解形式

1
2
3
4
5
6
7
8
9
10
public interface TeacherMapper {
@Results(value= {
@Result(id=true,column ="id",property = "id"),
@Result(column = "tname",property = "tname"),
@Result(property = "list",column = "id",
many=@Many(select = "com.runaccpeted.mapper.UserMapper.selById"))
})
@Select("select * from teacher")
List<Teacher> selAll();
}

直接添加到接口方法中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.runaccpeted.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import com.runaccpeted.pojo.*;

public interface UserInfoMapper {

@Select("select * from user")
List<User> selAll();

@Select("select * from user where id=#{0}")
User selById(int id);

@Update("update user set username=#{username} where id=#{id}")
int update(User user);

@Insert("insert into user values(default,#{username},#{password},#{tId})")
int insert(User user);

@Delete("delete from user where id=#{0}")
int delete(int id);

}

15. 运行原理

  • Resource IO流工具类

  • SqlsessionFactoryBuilder() 构建器

    创建SqlSessionFactory接口实现类

  • XMLConfigBuilder mybatis全局配置文件内容构建器类

    负责将流内容转换为java代码

  • Configuration 封装了全局配置文件所有配置信息

    Configuration config=factory.getConfiguration();

  • DefaultSqlSessionFactory 是SqlSessionFactory接口实现类

  • Transaction事务类

    每个SqlSession带有一个事务对象

  • TransactionFactory 事务工厂

    负责生产Transaction

  • Executor

    • 执行器,负责执行sql语句
    • 相等于JDBC的statement对象(PreparedStatement,CallableStatement)
    • 默认执行器 SimpleExceutor
    • 批量操作BatchExectuor
    • 通过openSession(控制事务)
  • DefaultSqlSession SqlSession接口实现类

  • ExceptionFactory 异常工厂

本文结束  感谢您的阅读
  • 本文作者: Wang Ting
  • 本文链接: /zh-CN/2019/09/05/MyBatis学习/
  • 发布时间: 2019-09-05 07:22
  • 更新时间: 2022-10-24 20:20
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!