41. Mybatis1 - 入门 demo, 核心配置文件中的属性

搭建过程

导入 jar 包

1
2
3
mysql-connector-java-5.1.7-bin.jar
mybatis-3.4.1.jar
log4j.jar

创建source folder 文件夹 conf,存放 log4j.xml

创建核心文件

添加 dtd 约束文件。让 xml 有提示功能。需要在 3 的位置选择对应 dtd 文件,在 4 的位置选择 URI 或者 Public ID。在 5 的位置填入对应的值就行。如果是 Public ID 那么 5 的位置应该是 PUBLIC 后面的字符串。如果是 URI 那么 5 的位置应该是 dtd 文件的 url 地址。

一般核心配置文件名称为 mybatis-conf.xml。基础内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/ssm" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 引入映射文件 -->
<mappers>
<mapper resource="UserMapper.xml" />
</mappers>
</configuration>

创建映射文件

映射文件名称一般为 xxxMapper.xml。这里要注意,里面的 SQL 语句的变量有两种写法,一种是 ${value},即Statement - 字符串拼接的方式,另一种是 #{变量名} - PreparedStatement - 通配符赋值的方式。在 SQL 语句中有两类不能使用通配符 ?赋值。第一类是批量删除和批量修改。第二类是模糊查询。因为使用通配符赋值(通配符赋值其实相当于 PreparedStatement 的方式, 字符串拼接相当于 Statement 的方式)会默认在赋值字符串的两边加上单引号。导致 SQL 发生变化。

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.atguigu.mapper.UserMapper">
<!-- 定义查询语句,id 设置 SQL 语句的唯一标识。resultType 代表结果类型 -->
<select id="getUserByUid" resultType="com.atguigu.bean.User">
<!--
select * from user where uid = ${value}
SQL 语句还可以是上面的样子,${value} 创建出来的是 Statement 对象,#{变量名} 创建出来的是 PreparedStatement 对象
即:
${value} - Statement - 字符串拼接的方式
#{变量名} - PreparedStatement - 通配符赋值的方式
在 SQL 语句中有两类不能使用通配符 ?赋值。第一类是批量删除和批量修改。第二类是模糊查询。因为使用通配符赋值(通配符赋值其实相当于 PreparedStatement 的方式, 字符串拼接相当于 Statement 的方式)会默认在赋值字符串的两边加上单引号。导致 SQL 发生变化。
-->

select * from user where uid = #{id}
</select>
</mapper>

创建 mapper 接口,实现两个绑定

创建 UserMapper 接口,并新建 getUserByUid 方法。

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

import com.atguigu.bean.User;

public interface UserMapper {
User getUserByUid(String uid);
}

两个绑定:

  1. 接口的全限定名和 Mapper.xml 文件中的 namespace 的值保持一致
  2. 接口中的方法名称和 SQL 语句的 id 保存一致
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.atguigu.mapper.UserMapper">
<!-- 定义查询语句,id 设置 SQL 语句的唯一标识。resultType 代表结果类型 -->
<select id="getUserByUid" resultType="com.atguigu.bean.User">
<!--
select * from user where uid = ${value}
SQL 语句还可以是上面的样子,${value} 创建出来的是 Statement 对象,#{变量名} 创建出来的是 PreparedStatement 对象
即:
${value} - Statement - 字符串拼接的方式
#{变量名} - PreparedStatement - 通配符赋值的方式
在 SQL 语句中有两类不能使用通配符 ?赋值。第一类是批量删除和批量修改。第二类是模糊查询。因为使用通配符赋值(通配符赋值其实相当于 PreparedStatement 的方式, 字符串拼接相当于 Statement 的方式)会默认在赋值字符串的两边加上单引号。导致 SQL 发生变化。
-->

select * from user where uid = #{id}
</select>
</mapper>

获取 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
package com.atguigu.test;

import static org.junit.jupiter.api.Assertions.*;

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;
import org.junit.jupiter.api.Test;

import com.atguigu.bean.User;
import com.atguigu.mapper.UserMapper;

class TestMybatis {

@Test
void test() throws IOException {
// 获取操作数据库的会话对象
InputStream is = Resources.getResourceAsStream("mybatis-conf.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession openSession = sqlSessionFactory.openSession();

// getMapper 会通过动态代理动态的生成 UserMapper 实现类,所以后续可以调用 getUserByUid 方法(不然抽象类中方法不能直接调用)
UserMapper userMapper = openSession.getMapper(UserMapper.class);
User user = userMapper.getUserByUid("1");
System.out.println(user);
}
}

数据库字段和实体类字段不匹配问题

以上查询输出的结果为

1
User [uid=1, userName=null, password=123456]

因为数据库中的 userName 字段是 user_name, 而实体类中的是 userName。所以这里数据显示为 null。我们应该将 sql 语句修改一下,改成别名的方式就能解决。

1
select uid, user_name as userName, password, age, sex from user where uid = #{id}

核心配置文件中的属性

environments

environments 用来设置连接数据库的环境,default 属性设置默认用的数据库环境。

environment 用来设置某个具体的数据库环境,id 是该数据库环境的唯一标识。

transactionManager 用于设置事务管理器,以后会将给 Spring 管理。

dataSource 用于设置数据源,以后会将给 Spring 管理。

properties

可以单独配置,或者从文件中加载 properties。单独配置如下:

1
2
3
<properties>
<property name="jdbd.driver" value="com.mysql.jdbc.Driver"/>
</properties>

从文件中加载

1
<properties resource="jdbc.properties"></properties>

最后整合框架的时候需要将 dataSource 交给 Spring 管理的,所以这里也没那么重要。

settings

例如可以设置下划线转驼峰

1
2
3
4
<!-- 下划线转驼峰。这样的话之前设置的别名就不需要了 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

typeAliases

typeAliases 可以为类型设置类型别名,若只设置 type,那么默认的别名就是类名,且不区分大小写。如果 typeAliases 里面有 package 标签,表示为某个包下的所有类都设置别名。

1
2
3
4
5
6
7
8
9
<!-- 为类型设置类型别名,若只设置 type,那么默认的别名就是类名,且不区分大小写 
如下写法,UserMapper.xml 中 resultType 则可以不写全限定名,而是写类名 User 或者 user
-->
<typeAliases>
<typeAlias type="com.atguigu.bean.User"/>

<!-- 表示 com.atguigu.bean 下所有的类都会被创建别名 -->
<!-- <package name="com.atguigu.bean"/> -->
</typeAliases>

代码地址