多出了抽象类来管理mapper.xml 的sql语句命名,必须指定名字的mapper.xml 的namespace 需要指定对应的抽象类的全包名,然后 sql的id则与抽象类中的方法名相同,这样来调用方法,就是调用mapper.xml中的sql语句,使用了工具类来加快开发效率,提升安全性

优化

1、抽象类

UXvx2Q.png

抽象类内容:

1
2
3
4
5
6
7
8
package com.ls.mybatis.dao;

import com.ls.mybatis.model.User;

public interface UserMapper {
public User selectOneUser(Integer uid);
}

需要指定返回值,传入参数

2、mapper优化

UXvzvj.png

这里的mapper要写dao的全路径,以后就会调用dao下面的方法,dao接收的参数会传入mapper中与dao方法名字相同的 查询元素中,返回值也如此返回。

3、工具类

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.ls.mybatis.utils;

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.Reader;

public class MyBatisUtils {

private static SqlSessionFactory sqlSessionFactory;
/*
* 创建本地线程变量,为每一个线程独立管理一个session对象 每一个线程只有且仅有单独且唯一的一个session对象
* 使用ThreadLocal对session进行管理,可以保证线程安全,避免多实例同时调用同一个session对象
*/
private static ThreadLocal<SqlSession> threadlocal = new ThreadLocal<SqlSession>();

// 创建sessionFactory对象,因为整个应用程序只需要一个实例对象,故用静态代码块
static {
try {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 新建session会话,并把session放在线程变量中
*/
private static void newSession() {
// 打开一个session会话
SqlSession session = sqlSessionFactory.openSession();
SqlSession sqlSession = threadlocal.get();
// 将session会话保存在本线程变量中
threadlocal.set(session);
}

/**
* 返回session对象
*
* @return session
*/
public static SqlSession getSession() {
//优先从线程变量中取session对象
SqlSession session = threadlocal.get();
//如果线程变量中的session为null,
if (session == null) {
//新建session会话,并把session放在线程变量中
newSession();
//再次从线程变量中取session对象
session = threadlocal.get();
}
return session;
}

/**
* 关闭session对象,并从线程变量中删除
*/
public static void closeSession() {
//读取出线程变量中session对象
SqlSession session = threadlocal.get();
//如果session对象不为空,关闭sessoin对象,并清空线程变量
if (session != null) {
//关闭资源
session.close();
//从threadlocal中移除session
threadlocal.set(null);
}
}

/**
* 提交并关闭资源
*/
public static void commitAndclose() {

//获取连接
SqlSession openSession = getSession();
//非空判断
if (openSession != null) {
//提交
openSession.commit();
//关闭资源
openSession.close();
//从threadlocal中移除session
threadlocal.remove();
}
}

}

实现了一些线程安全相关方面

目前流程小结

1、配置类

1
2
3
4
5
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
<mapper resource="mapper/ProductMapper.xml"/>
<mapper resource="mapper/UserMapper2.xml"/>
</mappers>

没有较大改变,mappers下面的属性会频繁添加,导致调用 mapper的sql查询。

2、测试类

1
2
3
4
5
6
7
SqlSession session = MyBatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectOneUser(1);

System.out.println(user);

MyBatisUtils.closeSession();

使用了工具类,封装了一些底层繁琐的重复工作,使用更加简单方便。

3、抽象类

通过调用抽象类的方法实现功能,而不是需要自己指定 命名空间.语句id 的形式了

4、mapper的sql

较大更改是将 命名空间改为了 dao相对的文件在项目中的相对位置,查询的返回值会返回给名字相同抽象类。