一、Mybatis概述
1、JDBC的缺点2、Mybatis的优势 二、使用Mybatis执行相应的sql语句
1、创建模块,导入坐标2、编写Mybatis核心配置文件3、编写SQL映射文件4、编写代码 三、Mapper代理开发四、MyBatis核心配置文件五、解决数据库中的字段名称和实体名称不一致,导致无法自动封装数据
1、通过起别名解决2、通过resultMap解决(推荐) 六、用MyBatis实现各种sql语句
1、查询详情
1.1 、#{ } 与 ${ }的区别1.1、sql语句的特殊字段处理 2、多条件查询 七、动态SQL
1、If标签2、where标签3、choose标签和when标签(主要用于单个条件的动态sql语句)4、插入 *** 作5、set标签(用于修改 *** 作)6、删除 *** 作
6.1、简单的删除 *** 作6.2、批量删除(foreach标签) 八、Mybatis参数传递
1、单个参数2、多个参数 九、使用注解实现CRUD
一、Mybatis概述MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
简单来讲,Mybatis就是一个简化JDBC(对JDBC代码进行封装)的框架,有了Mybatis我们就不用编写繁琐的JDBC代码,大大提高了我们编写代码的效率
JavaEE三层框架:表现层、业务层、持久层
那么什么是持久层呢??
持久层指的是负责将数据保存到数据库中的那些关键代码,因此在以后的Java程序开发中,我们将 *** 作数据库的Java代码作为持久层。
1、JDBC的缺点
在前面已经提了一下JDBC的缺点,就是繁琐,我们每次对数据库进行 *** 作都是要注册驱动然后获取链接,接下来再对编写sql语句,极度不便开发。
*** 作繁琐
使用JDBC对数据库进行 *** 作,除了要手动编写链接数据库的代码,还需要手动设置sql语句的参数查询的结果需要手动封装,当数量一多就会显得极度繁琐 硬编码
注册驱动、获取链接这些都是写死了的代码,倘若日后程序需要更换数据库,那么那些写死了的代码都需要修改,不利于程序日后的维护当表结构或者查询内容发生改变,便需要修改sql语句的内容,大量sql语句的修改不利于后期维护
2、Mybatis的优势
在Mybatis中,JDBC的缺点都得到了一定程度下的优化,减少了程序猿的工作压力
硬编码可以通过配置到配置文件来实现SQL语句可以动态 *** 作繁琐的代码Mybatis中可以自动完成
二、使用Mybatis执行相应的sql语句
想要使用Mybatis替代JDBC进行数据库的 *** 作,使用Mybatis有以下步骤:
创建相对应的模块,导入对应的Mybatis坐标编写Mybatis核心配置文件,其主要是为了配置数据库的连接信息,从而解决JDBC的硬编码问题编写SQL映射文件,为的是统一管理sql语句,解决硬编码问题编写代码
定义相对应得POJO类加载核心配置文件,获取SqlSessionFactory对象获取SqlSession对象,执行SQL语句释放资源
在编写代码那一部分,我们真正要做的往往只是执行SQL语句那一部分即可,因为其他的部分在MyBatis官网已经提供了,我们只需要在官网CV过来然后修改一丢丢即可投入使用。
MyBatis官网:https://mybatis.org/mybatis-3/zh/index.html
1、创建模块,导入坐标
在新建好的模块的工程目录下可以找到一个pom.xml的配置文件,我们需要在该配置文件中添加相应的依赖坐标
4.0.0 org.example MyBstis_Demo1.0-SNAPSHOT 8 8 org.mybatis mybatis3.5.5 mysql mysql-connector-java5.1.46 junit junit4.13 test org.slf4j slf4j-api1.7.20 ch.qos.logback logback-classic1.2.3 ch.qos.logback logback-core1.2.3
2、编写Mybatis核心配置文件
创建好模块和导入坐标之后,我们需要编写Mybatis核心配置文件来实现数据库的连接
3、编写SQL映射文件
在Mybatis核心配置文件中的mappers标签,设置了一个UserMapper.xml的SQL映射文件,那么创建一个SQL的映射文件
select * from tb_user;
4、编写代码
首先定义相对应得POJO类
package com.kang.pojo; public class User { private Integer id; private String username; private String password; private String gender; private String addr; public User(Integer id, String username, String password, String gender, String addr) { this.id = id; this.username = username; this.password = password; this.gender = gender; this.addr = addr; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + ''' + ", password='" + password + ''' + ", gender='" + gender + ''' + ", addr='" + addr + ''' + '}'; } }
接着编写测试类代码
package com.kang; import com.kang.pojo.User; 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class MyBatisDemo { public static void main(String[] args) throws IOException { //1、加载mybatis核心配置文件 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //获取SqlSession对象,用来执行sql SqlSession sqlSession = sqlSessionFactory.openSession(); //执行sql,通过名称空间来识别执行哪一个sql语句 Listusers = sqlSession.selectList("test.selectAll"); System.out.println(users); //释放资源 sqlSession.close(); } }
运行程序
三、Mapper代理开发
使用上面的方法对数据库进行 *** 作的时候不难发现,这当中依然存在着硬编码的问题,那么当我们用Mapper代理开发的时候就可以更好地解决这一问题。
使用Mapeer代理开发需要完成以下步骤:
定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放在同一目录下
设置SQL映射的namespace属性为Mapper接口全限定名(也就是接口名字要和namespace的空间名字要相同)
在Mapper接口中定义方法,方法名就是SQL映射文件中的sql语句的id,并保持参数类型和返回值一致
编写程序
代码如下:
BrandMapper接口
package com.kang.mapper; import com.kang.pojo.Brand; import com.kang.pojo.User; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; public interface BrandMapper { public ListselectAll(); }
SQL映射文件
Java测试类
package com.kang; import com.kang.mapper.UserMapper; import com.kang.pojo.User; 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class MyBatisDemo2 { public static void main(String[] args) throws IOException { //1、加载mybatis核心配置文件 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //获取SqlSession对象,用来执行sql SqlSession sqlSession = sqlSessionFactory.openSession(); //获取UserMapper接口的代理对象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); Listusers = mapper.selectAll(); System.out.println(users); //释放资源 sqlSession.close(); } }
注意:
如果Mapper接口名和SQL映射名称相同的时候,并在同一目录下,则可以使用扫描包的方式简化SQL映射文件加载
四、MyBatis核心配置文件
配置MyBatis核心配置文件的时候需要注意各个标签的前后顺序
MyBatis核心配置文件的顶层结构如下:
configuration(配置)
properties(属性)settings(设置)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象工厂)plugins(插件)environments(环境配置)
environment(环境变量)transactionManager(事务管理器)dataSource(数据源) databaseIdProvider(数据库厂商标识)mappers(映射器)
五、解决数据库中的字段名称和实体名称不一致,导致无法自动封装数据 1、通过起别名解决
在对应的xml文件中加入sql标签
id, brand_name as brandName, company_name as companyName, ordered, description, status
id是唯一标识,引用时候也是根据该值进行引用的
使用该别名的时候,需要在原sql语句引用上述sql片段,refid指定上述sql片段的id值
2、通过resultMap解决(推荐)
使用sql片段的方式可以解决上述问题,但是这当中难免也存在问题,比如我们只需要查询其中一个字段段的时候,又需要重新编写一个sql片段,这样代码会显得非常冗余。
在映射配置文件中,使用resultMap定义字段和属性的映射关系
而sql语句可以正常编写,但是之前的resultType换为resultMap
六、用MyBatis实现各种sql语句 1、查询详情
在相对应的接口定义id查询数据的方法
Brand selectById(int id);
编写SQL语句
其中花括号的id要与接口中的参数一致
编写测试类
@Test public void testSelectById() throws IOException { //传入参数 int id = 1; //1.加载mybatis的核心配置文件,从而获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2.获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //3.获取Mapper接口代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4.执行方法 Brand brand = brandMapper.selectById(id); System.out.println(brand); //5.释放资源 sqlSession.close(); }
1.1 、#{ } 与 ${ }的区别
#{}:执行sql时候,会将#{}占位符替换为?,将来自动设置参数值${}:拼接sql语句,会存在sql注入问题
1.1、sql语句的特殊字段处理
在编写sql语句的xml文件中,当我们使用小于(<)或者大于(>)的时候,会报错
针对这种情况下,有两种解决方案
转义字符
比如以下就是小于号的转移字符
<
使用来将小于包裹,表明这是一个小于的符号,这样计算机就不会报错了
2、多条件查询
在实际开发中,我们难免会遇到多条件查询,也就是查询的条件有多个,而Mybatis针对多参数有多种实现
通过@Param(“参数名称”)标记每一个产生,在映射配置文件中就需要使用#{参数名称}进行占位
ListselectByCondition(@Param("status") int status, @Param("companyName") String companyName,@Param("brandName") String brandName);
将多个参数标记为一个实体类对象,并将该实体类对象作为接口的方法参数,该方法要求在映射文件中sql中使用#{内容}的时候,里面的内容必须和实体类的属性名保持一致
ListselectByCondition(Brand brand);
将多个参数封装到map集合中,将map集合作为接口方法参数。该方法要求在映射文件中sql中使用#{内容}的时候,里面的内容必须map集合中的键保持一致
ListselectByCondition(Map map);
注意:倘若使用模糊查询,需要将字符串拼接成%XXXX%的形式才可以
//接收参数 int status = 1; String companyName = "华为"; String brandName = "华为"; // 处理参数 companyName = "%" + companyName + "%"; brandName = "%" + brandName + "%";
七、动态SQL
上述的功能实现无非还是有点硬编码的味道,当我们查询的内容不一样的时候,则需要修改SQL语句,极度不方便我们开发
针对这种情况,Mybatis对动态SQL提供了很强的支撑:
Ifchoose(when,otherwise)trim(where,set)foreach
1、If标签
if标签:条件判断标签
test属性:逻辑表达式
可以看到,像上面的代码,倘若status不为空,则sql语句为where and status = XXXX,这样的sql语句明显是错误的,因为为了解决这个问题,我们可以在前面加一个1 = 1,这样就不会出错了
2、where标签
像上面这也的 1=1 这样解决这个问题,虽然可以简单除暴地解决,但是依然不是很好。
Mybatis早就想到这个问题,它向我们用户提供了where标签
其作用是:
替换where关键词会动态去掉第一个条件前的and如果所有参数没有值则不加where关键词
注意:
每个条件前面都要加上and关键词
3、choose标签和when标签(主要用于单个条件的动态sql语句)
在实际开发中,查询的时候难免可以选择查询条件来查询,因此Mybatis提供了choose(when,otherwise)来实现动态但条件查询
测试类(需要什么条件查询就把用改条件new一个对象)
@Test public void selectByConditionSingle() throws IOException { //传入参数 int status = 1; String companyName = "华为"; String brandName = "华为"; //处理参数 companyName = "%" + companyName + "%"; brandName = "%" + brandName + "%"; Brand brand = new Brand(); //status查询 brand.setStatus(status); // brand.setCompanyName(companyName); // brand.setBrandName(brandName); // Map stringStringMap = new HashMap(); // stringStringMap.put("status", status); // stringStringMap.put("companyName", companyName); // stringStringMap.put("brandName", brandName); //1.加载mybatis的核心配置文件,从而获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2.获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //3.获取Mapper接口代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4.执行方法 Listbrands = brandMapper.selectByConditionSingle(brand); System.out.println(brands); //5.释放资源 sqlSession.close(); } }
4、插入 *** 作
useGeneratedKeys 为true的作用 :获取插入记录的自增长字段值。
insert into mybatis.tb_brand (brand_name, company_name, ordered, description, status) values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
5、set标签(用于修改 *** 作)
set标签主要是用来解决每个更新语句后面的“,”导致无法实现动态的sql语句
set标签可以用于动态包含需要更新的列,忽略其它不更新的列。
update mybatis.tb_brand where id = #{id}; brand_name = #{brandName}, company_name = #{companyName}
测试用例的时候,我们需要手动提交事务或者自动提交事务,修改 *** 作才可以完成。
@Test public void testUpdate() throws IOException { //接收参数 int status = 0; String companyName = "波导手机"; String brandName = "波导"; String description = "波导手机,手机中的战斗机"; int ordered = 200; int id = 6; //封装对象 Brand brand = new Brand(); brand.setStatus(status); brand.setId(id); //1. 获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //设置事务提交为ture //SqlSession sqlSession = sqlSessionFactory.openSession(true); //3. 获取Mapper接口的代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4. 执行方法 int count = brandMapper.update(brand); System.out.println(count); //提交事务 sqlSession.commit(); //5. 释放资源 sqlSession.close(); } }
6、删除 *** 作 6.1、简单的删除 *** 作
简单的删除 *** 作非常简单实现,只需要实现在相应的映射文件中编写删除的xml代码
delete from tb_brand where id = #{id};
接着在对应的接口编写对应的删除方法即可
void deleteById(int id);
6.2、批量删除(foreach标签)
批量删除则需要将要删除的东东存放在一个数组里,知识映射文件中的sql语句编写有点不一样
接口中的方法
void deleteByIds(@Param("ids")int[] ids);
而在映射文件中的sql语句,则需要使用foreach标签来实现
foreach标签有五个属性
collection属性
mybatis会将数组参数封装成一个Map集合
默认为:array = 数组使用@Param注解改变map集合的默认key的名称 item属性:本次迭代获取到的元素spearator属性:集合项迭代之间的分隔符。 foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加 分隔符。open 属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一次close 属性:该属性值是在拼接SQL语句拼接后拼接的语句,只会拼接一次
delete from mybatis.tb_brand where id in #{id} ;
八、Mybatis参数传递 1、单个参数
POJO类型
直接使用。要求属性名和参数占位符名称一致
Map集合类型
直接使用。要求map集合的键名和参数占位符名称一致
Collection集合类型
Mybatis会将集合封装到map集合中,如下
map.put("arg0", collection集合); map.put("collection",collection集合);
可以使用@Param注解替换map集合中的默认的arg键名
List集合
Mtbatis会将集合封装到map集合中,如下:
map.put("arg0",list集合); map.put("collection",list集合); map.put("list",list集合);
可以使用@Param注解替换map集合中的默认的arg键名
Array集合
Mybatis 会将集合封装到 map 集合中,如下:
map.put("arg0",数组); map.put("array",数组);
可以使用@Param注解替换map集合中的默认的arg键名
其他类型
比如int类型,占位符叫什么都可以,尽量做到见名知其意即可
2、多个参数
接口参数是多个时,在每个参数上都使用 @Param 注解。这样代码的可读性更高。
九、使用注解实现CRUD
crud是指在做计算处理时的增加(Create)、检索(Retrieve)、更新(Update)和删除(Delete)几个单词的首字母简写。crud主要被用在描述软件系统中数据库或者持久层的基本 *** 作功能
@Select(value = "select * from tb_user where id = #{id}") public User select(int id);
Mybatis 针对 CURD *** 作都提供了对应的注解,已经做到见名知意。如下:
查询 :@Select添加 :@Insert修改 :@Update删除 :@Delete
``java
map.put(“arg0”, collection集合);
map.put(“collection”,collection集合);
可以使用@Param注解替换map集合中的默认的arg键名 4. List集合 Mtbatis会将集合封装到map集合中,如下: ```java map.put("arg0",list集合); map.put("collection",list集合); map.put("list",list集合);
可以使用@Param注解替换map集合中的默认的arg键名
Array集合
Mybatis 会将集合封装到 map 集合中,如下:
map.put("arg0",数组); map.put("array",数组);
可以使用@Param注解替换map集合中的默认的arg键名
其他类型
比如int类型,占位符叫什么都可以,尽量做到见名知其意即可
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)