[Spring MVC3]MyBatis详解
创始人
2024-01-15 09:52:25
0

本章重点讲述了MyBatis映射器,对数据层进行的操作,建议本篇文章和Spring Boot的持久层相互比较来看会更加收获颇多Spring Boot持久层技术

本文需要使用到MVC第一讲的模板格式与配置情况,全部代码已经放在此博客中,Spring MVC1

目录

  • MyBatis映射器
    • 映射器主要元素
    • select 元素
    • insert 元素
    • update元素
    • delete元素
    • sql元素
  • 动态SQL
    • if元素
  • Mybatis注解配置
    • 常用注解
  • MyBatis关联映射
  • 思考:DAO与Service层

MyBatis映射器

映射器主要元素

元素描述
select映射查询
insert映射插入
update映射更新
delete映射删除
sql可以被其他语句引用的可重用语句块
resultMap描述层数据库结果集加载对象
cache缓存配置
cache-ref缓存配置的引用

注意MyBatis的配置我是在AyUserMapper.xml进行配置,所定位的Dao层如下图查看,通过mapper标签对dao接口进行一对一的映射,这是相对复杂的xml配置,后面会讲到注解的方式
在这里插入图片描述
同时在applicationContext.xml进行扫描:
在这里插入图片描述

select 元素

可以从数据库读取数据,组装数据给业务人员。比如在AyUserMapper.xml使用select元素,根据id查找(相关文件与建表命令在Spring MVC1列出)
AyUserMapper.xml


这个语句就是findById,接收一个String类型的参数,并返回一个User.#{id}就是预处理语句,类似于:

String findById = "select * from ay_user where id = ?";
PreparedStatement ps = conn.prepareStatement(findById);
ps.setString(1,id);

在接口AyUserDao,AyUserService写下此方法:

AyUser findById(String id);

在AyUserServiceImpl:

public AyUser findById(String id) {return ayUserDao.findById(id);}

下面进入到控制层进行测试:AyUserController:

@GetMapping("/findById")public String findById(Model model) {AyUser m = null;m=ayUserService.findById("1");System.out.println(m.getName()+"AAA");return "hello";}

运行,浏览器输入80/user/findById,可以在控制台看到相应的信息
在这里插入图片描述
xml中的select id注意要和DAO接口的方法名要一致,否则不一致会抛出异常。
resultType:从语句返回期望类型的类完全限定类名;

下面再来看几个例子:


对于的AyUserDao如下:

int countByName(String name);

insert 元素

用来映射DML语句,MyBatis会在执行插入后返回一个整数,来表示操作后的记录数。
下面的属性如下:

属性描述
useGeneratedKeys令MyBatis使用JDBC来获取数据库的主键
keyColumn指明第几列为主键,不与keyProperty公用
keyProperty指明哪个列作为主键
下面来看几个例子:
insert into ay_user(id,name,password) values(#{id},#{name},#{password});
//或者使用主键自增的方法
insert into ay_user(name,password) values(#{name},#{password});

对应的AyUserDao,AyUserService接口如下:

int insertUserTest(AyUser ayUser);

实现的AyUserServiceImpl:

public int insertUserTest(AyUser ayUser){return ayUserDao.insertUserTest(ayUser);}

在控制层进行测试:

 @GetMapping("/insertUserTest")public String insertUserTest(Model model) {AyUser m =new AyUser();m.setId(9);m.setName("ccc");m.setPassword("1234");int t=ayUserService.insertUserTest(m);System.out.println(t);return "hello";}

运行80/user/insertUserTest,此时查看数据库信息:
在这里插入图片描述

update元素

用来映射DML语句,主要用来更新数据,同样也会返回一个整数来表示更新的记录数,和select属性差不多。

update ay_user set name = #{name},password = #{password} where id = #{id}

在AyUserDao,AyUserService接口实现:

 int updateUser(AyUser ayUser);

在AyUserServiceImpl中实现:

public int updateUser(AyUser ayUser) {return ayUserDao.updateUser(ayUser);}

在控制层实现:

@GetMapping("/updateUser")public String updateUser(Model model) {AyUser m = new AyUser();m.setId(1);m.setName("jacinx");m.setPassword("88888");int t = ayUserService.updateUser(m);return "hello";}

运行80/user/updateUser,查看数据库信息:
在这里插入图片描述

delete元素

用来映射删除,和select差不多,这里就稍微写一下xml:

//根据Id删除记录

delete from ay_user where id = #{id}

sql元素

sql元素可以用来定义可重用的SQL代码,可以被静态参数化,可以对字段进行封装:

a.id as "id",a.name as "name",a.password as "password"

当然方便地使用include元素的refid属性进行引用,还可以使用定制使用sql元素,具体如下:


//注意使用$而不是使用#${prefix}.id as "id",${prefix}.name as "name",${prefix}.password as "password"

#与$区别:
#{}将传入的数据当成字符串,会自动加一个双引号,例如:

order by #{id}
//如果id传入为11,那么解析成
order by "11"

${}将数据直接显示在sql中

order by ${id}
order by 11

#方式可以防止sql注入,$无法防止!

动态SQL

在项目开发中,经常根据不同的条件拼接SQL语句,而MyBatis提供了对SQL语句动态的组装能力。采用功能强大的基于OGNL表达式来完成动态SQL。

属性描述
if单条件分支
choose、when、otherwise多条件判断语句,相当于case when
trim、where、set用来处理SQL拼接问题,辅助元素
foreach循环语句

if元素

用来判断语句,比如按照name查询,name可填可不填,如果没填那么就不要使用它来作为查询条件。
if标签常常与test属性联合使用且是必选属性。下面的代码来判断name 或者password是否为空,如果不为空那么就拼凑sql进行查询,如果为空则忽略:


在AyUserDao,AyUserService接口方法:

    List findByNameAndPassword(@Param("name") String name,@Param("password") String password);

在AyUserServiceImpl实现接口的方法:

public List findByNameAndPassword(@Param("name") String name, @Param("password") String password) {return ayUserDao.findByNameAndPassword(name,password);}

在控制层实现:

  @GetMapping("/findByNameAndPass")public String findByNameAndPass(Model model) {List a = null;a = ayUserService.findByNameAndPassword("ccc","1234");for(int i=0;iSystem.out.println(a.get(i).getId()+"  "+a.get(i).getName());}return "hello";}

运行80/user/findByNameAndPass,可以看到控制台打印出相应的信息:

在这里插入图片描述
关于其他的元素例如foreach等就不再赘述了。

Mybatis注解配置

常用注解

除了前面的xml的配置方法,可以使用基于注解的配置方式!
在这里插入图片描述

@Select注解与xml的select相对应,@Results注解与resultMap标签相对应,当使用注解的时候就不用在xml配置了:
在AyUserDao层接口方法:

@Select("select * from ay_user ")List findAllUser();

其他AyUserService不变

List findAllUser();

在AyUserServiceImpl中:

public List findAllUser() {return ayUserDao.findAllUser();}

在控制层实现测试:

@GetMapping("/findAlUser")public String findAlUser(Model model) {List a = null;a = ayUserService.findAllUser();for(int i=0;iSystem.out.println(a.get(i).getName());System.out.println();}return "hello";}

此时运行就能看到输出了。

其他的例如@Insert,@Update,@Delete类似

@Insert("insert into ay_user(name,password) values(#{name},#{password})")

当映射器需要多个参数,@Param注解可以被应用于映射器方法参数给每个参数取名字。

    List findByNameAndPassword(@Param("name") String name,@Param("password") String password);

MyBatis关联映射

在实际的项目中,需要遵循数据库设计范式的要求,对现实中的业务模块进行拆分,封装到不同的数据表中,表和表之间存在一对多或者多对多的对应关系。进而,对数据库的增删改查的主体从单表就变成了多表。

这里就不再赘述了。

思考:DAO与Service层

不知大家发现没有,在我的上述代码中,DAO与Service层的代码都是一样的,当然这是由于我是表单模式下的。所以这就引发我对DAO与Service层的思考:
这里引用一下zhihu的问题:java为什么要分为service层,dao层,controller层?
在这里插入图片描述
Service类封装业务流程(或者说是界面上的业务流程),DAO类封装对持久层的访问,DTO类封装业务实体对象。为什么要用Service接口和DAO接口?其实就是为了解耦,解耦说的意思是你更改某一层代码,不会影响我其他层代码。
Service + DAO,即DAO中只做CRUD及类似的简单操作(称之为功能点,不包含业务逻辑),Service中通过调用一个或多个DAO中的功能点来组合成为业务逻辑.Service的数量应该由功能模块来决定。在这种模型中业务逻辑是放在Service中的,事务的边界也应该在Service中控制.

以上,希望对你有所帮助。

相关内容

热门资讯

户口挂靠协议书 户口挂靠协议书  甲方: 市人才服务中心  乙方:(姓名)  (身份证号码:)  经甲、乙双方协商同...
环保徒步公益活动倡议书 小编导语:经CVA倡议的“中国徒步日”是每年4月的第三个星期六,在当天举办的徒步活动吸引着越来越多的...
龙年新春对联 龙年新春对联· 鸟鸣春日惊山水 鱼跃龙门动地天 ()· 龙舟竞渡波澜阔 华夏中兴日月甜 ()· 龙腾...
国网工会信息报送范文(精选2... 国网工会信息报送范文 第一篇各位代表、同志们:在岁末年首、辞旧迎新之际,我们在党的精神鼓舞下,迎来了...
企业搬迁祝贺信范文28篇 企业搬迁祝贺信范文 第一篇1. 莺声到此鸣金谷;麟趾于今步玉堂。2. 旭日乍临家室乐;和风初度物华新...
工程项目施工委托书 工程项目施工委托书(通用5篇)  被委托人在行使委托书上的合法权益内,被委托人不承担任何法律责任。在...
知心爱人纪念日短信 知心爱人纪念日短信·亲爱的:在这特别的日子,我只能用心去默默地想你、爱你。只想告诉你:永远深爱着你,...
慈善协会捐款倡议书 慈善协会捐款倡议书(通用15篇)  在快速变化和不断变革的新时代,需要使用倡议书的场合越来越多,通过...
绿色上网倡议书 绿色上网倡议书范文3篇  营造健康文明的网络文化环境,清除不健康信息已成为全社会的共同呼唤。下面是公...
有关家长反馈意见 有关家长反馈意见  不仅学生和家长的互相沟通与理解可以影响到学生的学习质量,老师与家长之间的交流与沟...
追女孩子经典短信 追女孩子经典短信  追女孩子经典短信1  1、在爱情的问题上,往往没有谁对谁错,爱情只是一种缘分。缘...
遵守交通规则,安全文明出行倡... 遵守交通规则,安全文明出行倡议书范文(精选8篇)  在不断进步的社会中,在很多情况下我们需要用到倡议...
好书伴我行评比作文200字4... 好书伴我行评比作文200字 第一篇闲暇之余,我总喜欢静静地坐在窗边,或眺望远方,看那都市的繁华,看那...
请病假条 请病假条范文  因生病而写的请假条,那么你知道该怎么写吗?以下为大家分享的'范文,希望对大家有所帮助...
简单的师徒结对协议书 简单的师徒结对协议书  在不断进步的社会中,协议使用的情况越来越多,签订协议能够较为有效的约束违约行...
写给叛逆期的孩子的一封信 写给叛逆期的孩子的一封信范文(通用6篇)  在日常的学习、工作、生活中,大家都不可避免地要接触到书信...
铝合金工程施工安全协议书 铝合金工程施工安全协议书  甲方单位名称:楚雄毅顺建筑安全工程有限责任公司  乙方单位名称:昆明久亚...
付款单位证明 付款单位证明付款单位证明付款单位证明付款单位(或个人)证明付款单位(个人)名称(盖章) 电话付款单位...
付款承诺函 付款承诺函范文3篇付款承诺函范文3篇1致:  感谢贵公司一直以来对我司的支持与信任,为了加速公司资金...
弟弟写给姐姐的一封信 弟弟写给姐姐的一封信(8篇)  在平日的学习、工作和生活里,大家都接触过书信吧,书信具有明确而特定的...