MyBatis配置文件解析

MyBatis配置文件

一、MyBatis全局配置文件(即mybatis-config.xml)

1、properties

加载数据库连接属性文件
在这里插入图片描述

2、settings

全局配置参数

注意:【settings】是设置与数据库交互的环境

  • 例如可以在此处配置二级缓存,配置查询延迟加载策略等等. . .

配置的目的是为了更加有效的查询表中的记录

但是,在实际项目开发中,settings的设置基本没用

  • 因为【settings】对于查询的优化,得到的效果不明显
  • 对于海量级别的数据,使用【settings】配置优化,起不到任何的效果
  • 对于数据量较少的项目,对于查询的效率要求的比较低,也没有必要使用【settings】配置

如果遇到了海量级别的数据,我们如何去提高查询的效率呢?

  • 基础操作

    • 对于常用的查询条件的字段,【设置索引】
  • 高级操作

    • 使用【nosql数据库】,【redis】
  • 专业操作

    • 【Elasticsearch】与【Solr】,针对于电商行业
      在这里插入图片描述
3、typeAliases

设置类型别名

  • 在实际项目开发中,对于别名的设置,主要是针对于pojo的设置
  • 框架默认支持的别名
(1)方式1

为指定的类分别起别名,别名的命名由我们自己来决定

  • type:要为哪个【domian】起别名填写【包.类】名称
  • alias:别名的名字
    在这里插入图片描述
    此时在查询语句中返回值类型即可使用我们自定义的别名
    在这里插入图片描述
(2)方式2(常用)

使用package标签批量起别名

​ 别名是MyBatis默认为我们取好的,命名不是由我们自己决定,别名为类名(类名的字母不区分大小写)。虽然字母不区分大小写,但是我们还是要按照预定俗成的规则填写类名,类名首字母可以小写

  • name:指定一个包结构,表示在该包下,所有的【domain】自动起好了别名
    在这里插入图片描述
    此时在查询语句中返回值类型只可填写【domain】包下的类名,但不区分大小写
    在这里插入图片描述
(3)总结
  • 未来实际项目开发中,如果公司需要使用起别名的机制,我们要使用批量起别名的方式
  • 在市场上也有很多企业摒弃使用MyBaits起别名的机制
    • 公司会认为将domian写成全路径,可以有效的提供代码的可读性
4、mappers

映射器:用来在核心配置文件中注册和加载映射文件。

(1)resource形式

使用resource属性,指定mapper映射文件
在这里插入图片描述

(2)class形式

使用class属性,找到dao层接口的全路径
在这里插入图片描述

(3)package形式(常用)

批量注册

  • name属性:指向dao层的包,表示在该dao包 下,所有的mapper映射文件自动注册
    在这里插入图片描述
(4)总结

​ 未来实际项目开发中,我们一定是【批量注册mapper映射文件】

二、MyBatis映射文件(如UserDao.xml)

1、parameterType

设置参数类型
parameterType用于设置输入参数的java类型。parameterType 的值为参数类型的java类型或者别名,Sql 语句获取参数的值使用 #{} 或者 ${} 。使用时可省略。

(1)使用简单数据类型(8大基本数据类型 + String)为参数
<select id="select" parameterType="String" resultType="User">
	select * from users where id=#{id}
</select>

测试:parameterType 使用简单数据类型 String

User u = UserDao.select("A0001");
System.out.println(s);
(2)使用引用数据类型为参数

如果我们为 sql 语句传递的参数类型为一个domian引用类型,那么#{}中的标识符必须是【domain类的属性名】

<select id="select" parameterTypeE"User" resultType="User">
	select * from users where name=#{name} and age=#{age}
</select>

​ 如果我们要为 sql 语句传递多个参数,我们应该将这多个参数封装到一个domain对象中,或者是打包到一个map集合中。

测试:parameterType, 使用domain(User u)为参数

//需求:查询出姓名为wyf,年龄为23岁的学员信息
User u = new User();
u.setName("wyf");
u.setAge(23);
List<User> uList = UserDao.select(u);
for(User u:uList){
	System.out.println(u);
}

注意:绝对不可以像下面的案例一样,同时为 sql 语句传递多个参数

List<User> uList = UserDao.select("wyf",23);
for(User u:uList){
	System.out.println(u);
}
(3)使用map为参数

如果我们为 sql 语句传递的参数类型为一个map类型,那么 #{} 中的标识符必须是【map 的 key】

<select id="select" parameterType="map" resultType="User">
	select * from users where name=#{name} and age=#{age}
</select>

测试:parameterType,使用map为参数

//需求:查询出姓名为wyf,年龄为23岁的学员信息
Map<String,0bject> map = new HashMap<String,0bject>();
map.put("name","wyf");
map.put("age",23);
List<User> uList = UserDao.select(u);
for(User u:uList){
	System.out.println(u);
}
(4)总结

​ 在实际项目开发中,使用domian引用类型,或者是使用map集合类型都可以为 sql 语句同时传递多个参数。 一般情况下, 我们使用domain就可以了。当domain不符合需求的情况下,我们一定要考虑使用map来传值
如:请查询出姓名为wyf,班级为一年一班的学员的详细信息

select 
from tbl_ student s
join tbl_ classroom c
on s.classroomId = c.id
where s.name = #{wyf} and c.name = #{一年一班}

​ 在实际项目开发中,一定要学会使用为 sql 传值的这几种方式。但是对于在<select>中的parameterType属性,一般我们都是省略不写的

2、#{}与${}

​ 使用在 sql 语句中的符号

(1)#{}

表示占位符,可以有效防止 sql 注入。使用#{}设置参数无需考虑参数的类型

(2)${}

表示拼接符,无法防止 sql 注入。使用${}设置参数必须考虑参数的类型

(3)传递简单类型参数
  • 如果获取简单类型参数,#{} 中可以使用value或其它名称
  • 如果获取简单类型参数,${} 中只能使用value。注意单引号的引入
<select id="select" resultType="User">
	select * from users where id='${value}'
</select>
(4)在没有特殊要求的情况下,通常使用#{}占位符
(5)有些情况必须使用${}
  • 如:动态拼接表名
select * from ${tablename}
//可理解为如下形式
String tbl = "tbl_ student";
String sql = "select * from " + tbl;
  • 如:动态拼接排序字段
select * from tablename order by ${username} desc
(6)使用${}执行like模糊查询(了解即可)

如:查询名字带 “a” 的人

  • UserDao.xml
<select id="select" resultType="User">
    select * from users where username like '%${value}%'
</select>
  • Test02
List<User> userList = userDao.select("a");
for (User user : userList){
    System.out.println(user);
}

在这里插入图片描述

(7)使用#{}执行like模糊查询
  • 方式一(了解)

UserDao.xml

<select id="select" resultType="User">
    select * from users where username like #{username}
</select>

Test02

List<User> userList = userDao.select("%a%");
for (User user : userList){
    System.out.println(user);
}
  • 方式二(掌握

UserDao.xml

<select id="select" resultType="User">
    select * from users where username like CONCAT('%',#{username},'%')
</select>

Test02

List<User> userList = userDao.select("a");
for (User user : userList){
    System.out.println(user);
}
3、 resultType

设置返回值类型

(1)返回简单类型(8大基本类型 + String)
  • 返回String类型

UserDao.xml

<select id="select" resultType="String">
    select username from users where userId=#{userId}
</select>

Test02

String username = userDao.select2(10);
System.out.println(username);
  • 返回String类型集合

UserDao.xml

<select id="select" resultType="String">
    select username from users
</select>

Test02

List<String> userList = userDao.select3();
for (String username : userList){
    System.out.println(username );
}
(2)返回pojo

UserDao.xml

<select id="select" resultType="User">
    select * from users
</select>

Test02

List<User> userList = userDao.select();
for (User user : userList){ 
    System.out.println(user);
}

在这里插入图片描述
解析:

<select id="" resultType="User">
    select * from users
</select>

​ 当执行了sql语句之后,通过查询得到的结果userId,username,password,sex,email。根据返回值类型,会自动为我们创建出来一个该类型的对象,由该对象将查询的结果封装起来

User user1 = new User();
user.setUserId(1);
user.setUsername("mike");
user.setPassword("123");
user.setSex("男");
user.setEmail("mike@qq.com");

当查询出来了第二条记录,根据返回值类型,再一次创建出来一个对象,封装第二条记录的值

User user2 = new User();
user.setUserId(1);
user.setUsername("admin");
user.setPassword("222");
user.setSex("女");
user.setEmail("admin@qq.com");

多条记录封装成为了多个Student对象

系统会自动的为我们创建出来一个【List集合】来保存这些对象

List<User> userList = new Arraylist<>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
(3)返回hashmap(注意返回值类型)
  • 返回map类型

UserDao.xml

<select id="select" resultType="map">
    select * from users
</select>

Test02

List<Map<String,Object>> mapList = userDao.select2();
for (Map<String,Object> map : mapList){
	Set<String> set = map.keySet();
	for (String key : set){
    	System.out.print("key:" + key + " = ");
    	System.out.println("value:" + map.get(key));
    }
    System.out.println("-----------------");
}

在这里插入图片描述
解析:

<select id="select" resultType="map">
    select * from users
</select>

​ 当执行了 sql 语句之后,通过查询得到的结果userId,username,password,sex,email。根据返回值类型,会自动为我们创建出来一个该类型的对象,由该对象将查询的结果保存起来。

Map<String,0bject> map1 = new HashMap<>();
map1.put("userId","1");
map1.put("username","mike");
map1.put("password","123");
map1.put("sex","男");
map1.put("email","mike@qq.com");

当查询出来了第二条记录,根据返回值类型,再一次创建出来一个对象,保存第二条记录的值

Map<String,0bject> map2 = new HashMap<>();
map1.put("userId","3");
map1.put("username","admin");
map1.put("password","222");
map1.put("sex","女");
map1.put("email","admin@qq.com");

直到内容结束
多条记录封装成为了多个map对象,系统会自动的为我们创建出来一个【List集合】来保存这些【map对象】

List<Map<String,0bject>> mapList = new ArrayList<>();
mapList.add(map1);
....
mapList.add(map6);

​ 对于 sql 语句查询的结果,我们使用domian来封装这些结果多方便,为什么还要使用map呢?

因为对于查询的结果,很多情况,使用domain封装不了,所以我们会想到使用map来保存结果。

如:根据姓名分组,查询出来每一个姓名对应的数量

select
username,count(*)
from users
group by username

​ 对于以上查询结果,使用domain能封装查询结果值吗?

不能!因为domain有name属性,但是没有count属性。使用返回map则一定可以保存查询得到的结果。

因此,能使用domain就是用domain,不能使用就使用map

(4)当查询字段名和pojo属性名不一致时的解决方案
  • 为字段起别名,别名为类中属性名
select 
userId,
fullname as username,
password 
from users
  • 使用resultMap

    id标签:用来配置主键的对应关系的
    result标签:用来配置普通字段对应关系的

对于users表, 表结果时一个id,两个普通字段。所以我们需要一个id标签,两个result标签

​ property属性:配置的是【类中的属性名】
​ column属性:配置的是【表中的字段名】

这样就能够建立起类属性和表字段一一对应的关系了

<resultMap id="userMap" type="User">
    <id property="userId" column="userId"/>
    <result property="username" column="fullname"/>
    <result property="password" column="password"/>
</resultMap>

<select id="select1" resultMap=" userMap">
	select userid,fullname,password from users
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值