MyBatis配置文件
文章目录
一、MyBatis全局配置文件(即mybatis-config.xml)
1、properties
加载数据库连接属性文件
2、settings
全局配置参数
注意:【settings】是设置与数据库交互的环境
- 例如可以在此处配置二级缓存,配置查询延迟加载策略等等. . .
配置的目的是为了更加有效的查询表中的记录
但是,在实际项目开发中,settings的设置基本没用
- 因为【settings】对于查询的优化,得到的效果不明显
- 对于海量级别的数据,使用【settings】配置优化,起不到任何的效果
- 对于数据量较少的项目,对于查询的效率要求的比较低,也没有必要使用【settings】配置
如果遇到了海量级别的数据,我们如何去提高查询的效率呢?
-
基础操作
- 对于常用的查询条件的字段,【设置索引】
-
高级操作
- 使用【nosql数据库】,【redis】
-
专业操作
- 【Elasticsearch】与【Solr】,针对于电商行业
- 【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” 的人
<select id="select" resultType="User">
select * from users where username like '%${value}%'
</select>
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)
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);
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>