学习笔记 : MyBatis的核心配置
MyBatis的核心对象
SqlSessionFactory
SqlSessionFactory
是MyBatis中十分重要的对象,它是单个数据库映射关系经过编译后的内存镜像,其作用是创建SqlSession
. SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用执行期间都会存在.如果我们多次地创建同一个数据库的SqlSessionFactory势必会耗尽数据库资源! 通常每一个数据库都会只对应一个SqlSessionFactory,所以在构建SqlSessionFactory时建议使用单例模式
哟 !
SqlSession
SqlSession
是MyBatis框架中另一个重要的对象,它是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作. 注意: 每一个线程都应该有一个自己的SqlSession实例,并且该实例是不能被共享的,同时SqlSession
实例也是线程不安全的,因此其使用范围最好在一次请求或一个方法中,绝不能将其放在一个类的静态字段,实例或任何类型的管理范围中使用.使用后理应及时地关闭它 !
配置文件
主要元素结构图
映射文件
官方简介 : MyBatis的真正强大在于它的映射语句,这是它的魔力所在.由于它的异常强大,映射器的XML文件就显得相对简单.如果拿它跟具有相同功能的JDBC代码进行对比,你会立即发现省掉了将近95%的代码! 俺喜欢简洁(✪ω✪) ~
主要元素
在映射文件中,<mapper>
元素是映射文件的根元素,其它元素都是它的子元素,其子元素及其作用如下所示 :
<select>
: 映射查询语句,可自定义参数,返回结果等.<insert>
: 映射插入语句,执行后返回一个整数,代表插入到条数.<update>
: 映射更新语句,执行后返回一个整数,代表更新的条数.<delete>
: 映射删除语句,执行后返回一个整数,代表删除的条数.<sql>
: 用于定义一部分SQL,然后可被其它语句引用此SQL.<cache-ref>
: 其他命名空间缓存配置的引用.<resultMap>
: 用于描述如何从数据库结果集中来加载数据.
简单案例
MyBatis框架的强大之处体现在映射文件,下面使用上述主要元素来编写一个简单的CURE程序 ~
数据表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 客户信息表(用于测试增删改查元素)
create table t_customer (
id INT(32) PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) NOT NULL,
job VARCHAR(45) NOT NULL,
phone VARCHAR(16) NOT NULL
)
# 用户信息表(用于测试<resultMap>元素)
CREATE TABLE t_user(
t_id INT PRIMARY KEY AUTO_INCREMENT,
t_name VARCHAR(20) NOT NULL,
t_age INT NOT NULL
)db.properties : 数据库配置信息
1
2
3
4
5#database configuration information
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://LOCALHOST/MyBatis?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
jdbc.username=root
jdbc.password=GoodTimemybatis-config.xml : MyBatis核心配置文件
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
<configuration>
<!-- 数据库配置文件 -->
<properties resource="db.properties" />
<!-- 配置环境.默认环境id为MySQL -->
<environments default="MySQL">
<environment id="MySQL">
<!-- 使用JDBC事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 将SQL映射文件注册到全局配置文件中 -->
<mappers>
<mapper resource="pers/huangyuhui/mybatis/mapper/UserMapper.xml"/>
<mapper resource="pers/huangyuhui/mybatis/mapper/CustomerMapper.xml"/>
</mappers>
</configuration>CustomerMapper.xml : 操作’t_customer’数据表的映射文件
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
<mapper namespace="pers.huangyuhui.mybatis.mapper.CustomerMapper">
<!-- 使用<sql>元素定义可重用的sql代码片段,简化代码 -->
<sql id="customerColumns">id,username,job,phone</sql>
<!-- 使用<insert>元素查询客户信息 -->
<select id="findCustomerById" parameterType="Integer" resultType="pers.huangyuhui.mybatis.bean.Customer">
select <include refid="customerColumns"/> from t_customer where id = #{id}
</select>
<!-- 使用<insert>元素添加客户信息并返回数据库生成的主键值 -->
<insert id="addCustomer" parameterType="pers.huangyuhui.mybatis.bean.Customer" keyProperty="id" useGeneratedKeys="true">
insert into t_customer(username,job,phone) values(#{username},#{job},#{phone})
</insert>
<!-- 使用<insert>元素添加客户信息并使用MyBatis提供的方式生成主键值 -->
<insert id="addCustomer2" parameterType="pers.huangyuhui.mybatis.bean.Customer" >
<selectKey keyProperty="id" resultType="Integer" order="BEFORE">
select if(max(id) is null,1,max(id)+1) as newId from t_customer
</selectKey>
insert into t_customer(id,username,job,phone) values(#{id},#{username},#{job},#{phone})
</insert>
<!-- 使用<update>元素更新客户信息 -->
<update id="updateCustomerById" parameterType="pers.huangyuhui.mybatis.bean.Customer">
update t_customer set username=#{username},job=#{job},phone=#{phone} where id = #{id}
</update>
<!-- 使用<delete>元素删除客户信息 -->
<delete id="deleteCustomerById" parameterType="Integer">
delete from t_customer where id = #{id}
</delete>
</mapper>UserMapper.xml : 操作’t_user’数据表的映射文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<mapper namespace="pers.huangyuhui.mybatis.mapper.UserMapper">
<!-- <resultMap>元素可解决数据表中的列与需要返回的对象的属性名可能不一致的问题 -->
<resultMap type="pers.huangyuhui.mybatis.bean.User" id="resultMap">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
<result property="age" column="t_age"/>
</resultMap>
<select id="findAllUser" resultMap="resultMap">
select t_id,t_name,t_age from t_user
</select>
</mapper>MyBatisUtils.java : MyBatis工具类
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
40package pers.huangyuhui.mybatis.util;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* @ClassName: MyBatisUtils
* @Description: MyBatis工具类
* @author: HuangYuhui
* @date: May 18, 2019 3:59:18 PM
*
*/
public class MyBatisUtils {
private MyBatisUtils() {
}
private static SqlSessionFactory sqlSessionFactory = null;
static {
// 使用MyBatis提供的Resources类加载MyBatis的配置文件
try (Reader reader = Resources.getResourceAsReader("mybatis-config.xml");) {
// 构建SqlSessionFactory工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
// 获取SqlSession对象的静态方法
public static SqlSession getSession() {
return sqlSessionFactory.openSession();
}
}MyBatisTest.java : 测试类
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150package pers.huangyuhui.mybatis.test;
import java.io.IOException;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import pers.huangyuhui.mybatis.bean.Customer;
import pers.huangyuhui.mybatis.bean.User;
import pers.huangyuhui.mybatis.util.MyBatisUtils;
/**
* @ClassName: MyBatisTest
* @Description: MyBatis核心配置: CURE
* @author: HuangYuhui
* @date: May 18, 2019 4:03:47 PM
*
*/
public class MyBatisTest {
private static Customer customer;
private static String namespace = "pers.huangyuhui.mybatis.mapper.CustomerMapper.";
public static void init() throws IOException {
customer = new Customer();
}
// 根据客户编id查询客户信息
public void findCustomerByIdTest() {
// 获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSession();
// 执行SqlSession的查询方法,并返回结果
Customer customerInfo = sqlSession.selectOne(namespace + "findCustomerById", 1);
// 输出查询结果信息
System.out.println(customerInfo);
// 关闭SqlSession
sqlSession.close();
}
// 插入客户信息并获取由数据库生成的主键值
public void addCustomerTest() {
SqlSession sqlSession = MyBatisUtils.getSession();
customer.setUsername("YUbuntu0109");
customer.setJob("student ~");
customer.setPhone("15111111111");
int rows = sqlSession.insert(namespace + "addCustomer", customer);
if (rows > 0) {
System.out.println("插入数据的主键id值为: " + customer.getId());
System.out.println("成功插入了 " + rows + " 条数据哟 ~");
} else {
System.out.println("插入数据操作失败 !");
}
sqlSession.commit();
sqlSession.close();
}
// 添加客户信息并使用MyBatis提供的方式生成主键值
public void addCustomer2Test() {
SqlSession sqlSession = MyBatisUtils.getSession();
customer.setUsername("YUbuntu0109");
customer.setJob("student ~");
customer.setPhone("13111111111");
int rows = sqlSession.insert(namespace + "addCustomer2", customer);
if (rows > 0) {
System.out.println("mybatis生成的主键为: " + customer.getId());
System.out.println("成功插入了 " + rows + " 条数据哟 ~");
} else {
System.out.println("插入数据操作失败 !");
}
sqlSession.commit();
sqlSession.close();
}
// 根据客户id更新客户信息
public void updateCustomerByIdTest() {
SqlSession sqlSession = MyBatisUtils.getSession();
customer.setId(1);
customer.setUsername("YUbuntu0109");
customer.setJob("speaker");
int rows = sqlSession.update(namespace + "updateCustomerById", customer);
if (rows > 0) {
System.out.println("成功更新了 " + rows + " 条数据哟 ~");
} else {
System.out.println("数据更新操作失败 !");
}
sqlSession.commit();
sqlSession.close();
}
// 根据客户id删除客户信息
public void deleteCustomerById() {
SqlSession sqlSession = MyBatisUtils.getSession();
int rows = sqlSession.delete(namespace + "deleteCustomerById", 1);
if (rows > 0) {
System.out.println("成功删除了 " + rows + " 条记录哟 ~");
} else {
System.out.println("删除数据操作失败 !");
}
sqlSession.commit();
sqlSession.close();
}
// 使用<resultMap>元素查找`t_user`表中所有用户信息
public void findAllUserTest() {
SqlSession sqlSession = MyBatisUtils.getSession();
List<User> users = sqlSession.selectList("pers.huangyuhui.mybatis.mapper.UserMapper.findAllUser");
for (User user : users) {
System.out.println(user);
}
}
}log4j.properties : 日志配置文件
1
2
3
4
5
6
7
8#Global configuration
log4j.rootLogger=DEBUG,stdout
#Log configuration
log4j.logger.pers.huangyuhui.mybatis.test=TRACE
#Console configuration
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.layout.ConversionPattern=%5p [%t] - %m%n