年轻的时候,遇见了那个人,便以为余生再没有江湖,后来,才发现,她才是江湖的起源。
上一章简单介绍了MyBatis的核心配置文件 SqlMapConfig.xml(五),如果没有看过,请观看上一章。
在MyBatis 中,将Dao层的接口与对应的Mapper.xml 配置文件进行组合使用,而不是以前的接口实现类处理。 这里着重讲解一下,这个配置文件的使用。 将XxxMapper.xml 放置在与接口XxxMapper.java 同级的目录下。
当然,前面不要忘记 xml文件的头部。
有一个根节点,是mapper, 里面只有一个属性, namespace, 命名空间。 后面跟的值一般为其所在的包路径,或者说是XxxMapper.java 接口所在的包路径。
在根节点 mapper 下的节点有:
其中,有一个parameterMap ,已经被放弃使用了。
数据库数据为:
select 下面有 id属性,parameterType 参数类型, resultType 结果类型属性等节点, 这些不同的节点表示不同的作用与意义。 除了这些之外,还有其他的节点属性。 只需要记住一些常见的节点即可。
下面就开始讲解 select元素的常见使用。
在UserMapper.java 接口中:
public int countByName(String name);
在UserMapper.xml 配置中其对应的配置语句为:
测试方法为:
@Test
public void countByNameTest(){
SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
int count=userMapper.countByName("%蝴蝶%");
System.out.println("输出数目为:"+count);
}
控制台显示为:
缺点, 上面传入的参数 需要自己手动拼接 %% 连接符, 用户只需要传入参数即可。 真正的拼接,应该放在数据库去完成。 每个数据库都有自己对应的字符串拼接方式。 mysql 可以使用 concat() 函数, oracle 可以使用 || .
上面是两个%%的形式,如果是前% 为 concat(’%’,#{name}), 后%为 concat(#{name},’%’);
传参可以使用三种方式
接口:
//多个参数的时候。
public List findByNameAndSexMap(Map map);
xml配置实现
测试方法:
@Test
public void findByNameAndSexMapTest(){
SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//定义参数
Map paraMap=new HashMap();
//key与xml 中配置的相同
paraMap.put("name","蝴蝶");
paraMap.put("sex","男");
List allList=userMapper.findByNameAndSexMap(paraMap);
allList.forEach(n ->System.out.println(n));
}
要注意,map 中的key 键值 要与 sql语句中的#{值} 保持一致。
接口:
public List findByNameAndSexAnnotation(@Param(value="name") String name,
@Param(value="sex") String sex);
sql语句配置:
测试方法, 为传参的形式
@Test
public void findByNameAndSexAnnotationTest(){
SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
List allList=userMapper.findByNameAndSexAnnotation("蝴蝶","男");
allList.forEach(n ->System.out.println(n));
}
查询的结果与上面的一样。
此时,sql语句中的值要与 注解的value 值相同,不一定要与方法中的形参的值相同。 适用于参数较少的情况,一般不超过5个。
接口:
public List findByNameAndSexBean(User user);
sql语句:
测试方法:
@Test
public void findByNameAndSexBeanTest(){
SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
User user=new User();
user.setName("蝴蝶");
user.setSex("男");
List allList=userMapper.findByNameAndSexBean(user);
allList.forEach(n ->System.out.println(n));
}
查询的结果与上面的一致。
map 形式: map传入进去,是不知道key值是什么的,与sql 语句隔离了,导致了业务可读性的丧失,导致了后续的扩展与维护的困难,应当果断废弃这种方式。
param 注解方式: 受参数个数的影响, 当n<=5 时,是最好的方式, 比java bean 还好,应该比java bean 更直观。 当n>5 时,多个参数调用会出现困难。
java bean 方式: 当参数个数过多时使用。 >5 时。
排序,用order by 进行排序。
接口:
public List orderByAge(String age);
sql语句:
测试方法:
@Test
public void orderByAgeTest(){
SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
List allList=userMapper.orderByAge("age");
allList.forEach(n ->System.out.println(n));
}
接口:
public List orderByAgeAndId(@Param("age") String age,@Param("id") String id);
sql语句:
测试方法:
@Test
public void orderByAgeAndIdTest(){
SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
List allList=userMapper.orderByAgeAndId("age","id");
allList.forEach(n ->System.out.println(n));
}
在sql 语句的前面进行查询
接口:
public List selectColumn(@Param(value="column1") String column1,
@Param(value="column2") String column2,@Param(value="column3") String column3);
sql语句:
测试方法:
@Test
public void selectColumnTest(){
SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
List allList=userMapper.selectColumn("name","sex","description");
allList.forEach(n ->System.out.println(n));
}
只有要查询的列才有值。
数据表的字段要与实体Bean 的类属性保持一致。 如,在实体类中是:
属性与字体一致的,可以进行相应的查询。
接口:
public List findAll();
sql语句:
测试方法:
@Test
public void findAllTest(){
SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
List allList=userMapper.findAll();
allList.forEach(n ->System.out.println(n));
}
如果数据表的名称与属性不一致的话,那么此时的查询呢? name和age不一致的情况。
在数据表中,将原先的name 改成 u_name, age 改成u_age
这个时候的查询呢?
发现 name 和age 是没有值的, 因为无法正确的setter 和getter,所以是取不到值的。
这个时候运行查询,是正确的。
如果现在列名改成了,多个sql 语句查询时,都要设置别名,是不是太麻烦了呢?
将结果集重新定义,定义成 resultMap 便可以了。 resultMap的详细用法,在一对一,一对多的关联关系中会仔细讲解。
查询时,可以正确的查询出来值。
resultMap 是很强大的元素, 以后会重点讲解。
关于insert 的用法,可以参看第三章的知识。
其中,插入的时候,可能并不是以1 进行插入,会自定义规则。 测试方法与前面的一样,sql接口是:
select if(max(id) is null,1,max(id)+2) as newId from user
insert into user(id,name,sex,age,description)
values(#{id},#{name},#{sex},#{age},#{description})
关于update 和delete的用法,可以参看第三章的知识。
在一个表中, 用select * from user 中 select * 是不太好的,实际开发中会用属性来代替, 如select id,u_name,sex,u_age,descrption from user 那么这个前面的查询会写很多个,如果改变了其中的一个字段,那么就要改变多个。 可以先将这个select id,u_name,sex,u_age,description 先当成sql 片段定义起来,然后再各个地方进行引用即可。
id,u_name,sex,u_age,description
用sql元素来定义片段, 用 include 来引入片段。
${prefix}.id,${prefix}.u_name,${prefix}.sex,${prefix}.u_age,${prefix}.description
注意,用的是${}, 并不是以前常用的#{} .
谢谢!!!