- MyBatis笔记
- 一.概述
- 二. MyBatis 环境搭建
- 三.创建Mybatis项目步骤
- 步骤:
- 1.根据需求设计一个类与数据库的表
- 2.接口(Mapper),实现对类的一些 *** 作
- 3.全局配置文件(mybatis.xml)配置信息
- `< typeAliases>`为类定义别名
- 配置`< mapper>`(添加SQL映射文件)
- 设置
- Mybatis日志
- 配置环境
- 创建config. properties(存储与数据库连接的信息)
- 引入config. properties
- 4.接口对应的配置文件(AdminMapper.xml)
- 驼峰映射
- 封装步骤
- 单元测试
- 类型别名
- 参数传递
- 1.简单的参数形式不需要使用 parameterType 参数定义
- 2. 多个参数使用@Param(“id”)绑定
- 3.传入复杂的参数,使用Map对象传递
- 结果处理
- 简单类型输出映射
- POJO对象输出映射
- 多表关联处理查询结果集
MyBatis原是Apache的一个开源项目iBatis, 2010年由Apache Software Foundation 迁移到了 Google Code, iBatis3.x正式更名为MyBatis。是 一个基于Java的持久层框架。 iBatis提供的持久层框架包括SQL Maps和Data Access Objects (DAO)。
MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录,是 一种 ORM(ORM Object Relational Mapping 对象关系映射)实现. Mybatis 将基本的 JDBC 常用接口封装,对外提供 *** 作即可.
- 是一个ORM框架.
ORM(Object Relational Mapping)对象关系映射 - 封装了一些关于数据库 *** 作的接口,代替了JDBC
- 对jdbc进行了封装,简化了其 *** 作
Mybatis 中文官网: mybatis – MyBatis 3 | 入门
既然mybatis封装了JDBC,那么来看一下传统JDBC和MyBatis的区别
我们使用mybatis做一个小demo来看一下和传统JDBC的区别
使用maven构建一个Mybatis,在这里我使用的工具是IDEA
传统JDBC:
- 加载数据库驱动
- 创建并获取数据库链接
- 创建 statement 对象
- 拼写 sql 语句
- 设置 sql 语句中的占位符的值 (使用预编译可以防止sql注入)
- 执行 sql 语句并获取结果
- 对 sql 执行结果进行解析处理
- 释放资源
JDBC的编程问题
- 数据库连接的创建、释放频繁造成系统资源浪费从而影响系统性能,如果使 用数据库连接池可解决该问题。
- SQL 语句编写在 Java 代码中,这种硬编码造成代码不易维护,当 SQL 变动 时需要修改 java 源代码。
- 使用 preparedStatement 向占位符传参数存在硬编码,因为 SQL 语句的 where 条件中占位符的个数可能会变化,修改 SQL 还要修改 Java 源代码, 系统不易维护.
- 对结果集解析存在硬编码,SQL 语句变化导致解析代码变化,系统不易维护。
-
先创建一个maven的项目(搭建maven:https://blog.csdn.net/lanleihhh/article/details/120978091)
-
导入mybatis/mysql的坐标(maven仓库下载:https://mvnrepository.com/)
复制后粘贴到中
org.mybatis mybatis3.4.6 mysql mysql-connector-java8.0.25
点击’M’形状的按钮安装jar包
我们可以使用日志组件(log4j)来记录程序的信息,引入log4j的坐标
log4j log4j1.2.17
注意:引入log4j的坐标后,还需在resources文件中添加配置文件:log4j.properties
log4j.rootLogger = debug,stdout,D #System out Console log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern = [%p] %d{yyyy-MM-dd HH:mm:ss,SSS} %m%n #System out File log4j.appender.D = org.apache.log4j.FileAppender log4j.appender.D = org.apache.log4j.DailyRollingFileAppender # 这里设置打印日志的文件路径 log4j.appender.D.File = E://logs/mybatisLog/LogMybatisDemo.log log4j.appender.D.Append = true log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] -[%l] %m%n
创建 MyBatis 全局配置文件 MyBatis 的配置文件包含了对 MyBatis 行为的设置信息。
配置文档的顶层 结构如下(标签需要按照特定顺序排放):
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
如下:
三.创建Mybatis项目步骤 步骤: 1.根据需求设计一个类与数据库的表
Java类:
package com.ffyc.mybatispro.model; public class Admin { private int id; private String account; private String password; private String sex; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Admin{" + "id=" + id + ", account='" + account + ''' + ", password='" + password + ''' + ", sex='" + sex + ''' + ", userName='" + userName + ''' + '}'; } }
数据库表:
CREATE DATAbase mybatis_db CHARSET utf8 CREATE TABLE admin( id INT PRIMARY KEY AUTO_INCREMENT, sex CHAr(1), account VARCHAr(20), PASSWORD VARCHAr(20) )2.接口(Mapper),实现对类的一些 *** 作
package com.ffyc.mybatispro.mapper; import com.ffyc.mybatispro.model.Admin; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; public interface AdminMapper { //插入 void saveAdmin(Admin admin); //更新 void updateAdmin(Admin admin); //删除 void deleteAdmin(int AdminId); //修改 Admin findAdminById(int AdminId); //传多个参数,使用注解标签@Param("acc") acc:传向xml文件中 #{acc} Admin findAdmin(@Param("acc")String account,@Param("sex")String sex); //传入键值对参数 Admin findAdmin(Map3.全局配置文件(mybatis.xml)配置信息map); //查询所有管理员对象 List findAllAdmin(); //查询管理员总人数 int adminCount(); }
几个.xml配置文件的区别
< typeAliases>为类定义别名- type:全类名
- alias:别名
配置< mapper>(添加SQL映射文件)
设置 Mybatis日志
Mybatis 内置的日志工厂提供日志功能,具体的日志实现有以下几种方式:
- SLF4J
- LOG4J
- LOG4J2
- JDK_LOGGING
- COMMONS_LOGGING
- STDOUT_LOGGING
- NO_LOGGING
具体选择哪个日志实现由 MyBatis 的内置日志工厂确定。它会使用最先找到的配置日志
配置环境
创建config. properties(存储与数据库连接的信息)
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/mybatis_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username=root password=lanlei6843引入config. properties
4.接口对应的配置文件(AdminMapper.xml)
insert into admin(account,password,sex,user_name)values(#{account},#{password},#{sex},#{userName})
测试方法:saveAdmin()
package com.ffyc.mybatispro.test; import com.ffyc.mybatispro.mapper.AdminMapper; import com.ffyc.mybatispro.model.Admin; 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.io.Reader; public class Test1 { public static void main(String[] args) throws IOException { Admin admin = new Admin(); admin.setAccount("admin"); admin.setPassword("123"); admin.setSex("男"); InputStream reader = Resources.getResourceAsStream("mybatis.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession sqlSession= sqlSessionFactory.openSession(); //获得映射接口的代理对象 //MapperProxy动态实现了自定义接口 //adminMapper对象实质是MapperProxy对象 org.apache.ibatis.binding.MapperProxy@79ad8b2f //使用代理对象 AdminMapper adminMapper = sqlSession.getMapper(AdminMapper.class); adminMapper.saveAdmin(admin); sqlSession.commit();//提交事务 sqlSession.close();//关闭与数据库会话连接 } }
运行一下:
查看数据库:
我们使用另一中传值方式
insert into admin(account,password,sex)values('${account}','${password}','${sex}')
运行:
传列: ${属性名} 传值: '${属性名}':${} 拼接符,会传入参数字符串,取值以后再去编译 SQL 语句,$方式无法防止sql注入 #{属性名} :#{} 占位符,是经过预编译的,编译好 SQL 语句再取值,#方式能够防止 sql 注入 values('','',''):字符串拼接方式 values(?,?,?):预编译,是安全的,可以防止sql注入 注意:MyBatis 排序时使用 order by 动态参数时需要注意,用$而不是#驼峰映射
在mybatis中默认java属性名和数据库字段名一一对应
如:
java: account
mysql:account
但两者定义语法不同
- java属性采用小驼峰(userName)
- 数据字段采用下划线(user_name)
很多时候没法将Java属性与数据库字段定义为相同的,因为要遵循规范
解决方法:
-
在sql语句中使用As设置别名,如(user_name As userName),设置与Java属性相同
-
mybatis的settings配置中有一个name为mapUnderscoreToCamelCase的参数,默认是false,设置为true,即可开启驼峰映射
可以从Java属性userName映射到数据库字段user_name,方便了很多
我们测试一下
在数据库中修改表列命名为经典下划线
-- 修改列名 ALTER TABLE admin CHANGE PASSWORD pass_word VARCHAr(20)
在java中修改属性
//private String password;原属性 private String passWord;
sql映射中修改sql语句
insert into admin(account,pass_word,sex)values(#{account},#{passWord},#{sex})
测试运行:
成功运行了,这就是驼峰映射
我们将属性与字段再修改为原来的password
封装步骤将步骤繁多的流程封装起来,我们使用的时候直接访问该封装类的方法
package com.ffyc.mybatispro.util; 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; public class MybatisUtil { static SqlSessionFactory sqlSessionFactory = null; static { InputStream reader = null; try { reader = Resources.getResourceAsStream("mybatis.xml"); } catch (IOException e) { e.printStackTrace(); } sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } public static SqlSession getSqlSession(){//返回sqlSession对象 return sqlSessionFactory.openSession(); } }单元测试
概念
-
java单元测试是最小的功能单元测试代码
-
单元测试就是针对某个Java方法的测试
-
java程序的最小功能单元是方法
使用单元测试的好处
- 不用再在main()方法中一个一个调用,测试完毕后再删除
- 确保单个方法正常运行
- 每个单元测试用例相对独立,不需要添加额外语句
- 只需查看测试结果,就可以了解整个项目的的方法接口是否通畅
我们借助juit工具进行测试
先在pom.xml中依赖单元测试的jar包,将其jar包下载到本地仓库中,然后依赖它
junit junit4.12 provided
在想要测试的方法前添加注解标签@Test,如下:
@Test public void update(){ Admin admin = new Admin(); admin.setAccount("admin"); admin.setPassword("123456"); admin.setSex("男"); //创建SqlSession对象 SqlSession sqlSession = MybatisUtil.getSqlSession(); //获取代理对象 AdminMapper mapper = sqlSession.getMapper(AdminMapper.class); mapper.updateAdmin(admin); sqlSession.commit();//提交事务 sqlSession.close();//关闭连接 }类型别名
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
当这样配置时,Admin可以在任何使用 com.ffyc.mybatispro.model.Admin 的地方。
可以在mybatis的jar包中找org.apache.ibatis.type.TypeAliasRegistry
里面定义了各种基本类型和引用类型的别名;如图
下面是mybatis为Java类库中的一些类和简单类型定义的别名
如:
//删除 void deleteAdmin(int AdminId); //修改 Admin findAdminById(int AdminId);
2. 多个参数使用@Param(“id”)绑定delete from admin where id=#{id}
Mapper接口方法
//传多个参数,使用注解标签@Param("acc") acc:传向xml文件中 #{acc} Admin findAdmin(@Param("acc")String account,@Param("sex")String sex);
xml中的实现
java测试代码
@Test public void find3(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); AdminMapper mapper = sqlSession.getMapper(AdminMapper.class); Admin admin = mapper.findAdmin("admin","男"); System.out.println(admin); sqlSession.commit(); sqlSession.close(); }3.传入复杂的参数,使用Map对象传递
Mapper接口方法
//传入键值对参数 Admin findAdmin(Mapmap);
xml中的实现
对于简单类型可不写parameterType属性,使用Java类库中的类作为参数时,使用mybatis为其定义的别名
这里可以通过mybatis3官方手册查看,XML配置–>类型别名https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases
java测试代码
@Test public void find4(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); AdminMapper mapper = sqlSession.getMapper(AdminMapper.class); Map结果处理 简单类型输出映射map = new HashMap<>(); map.put("acc", "admin"); map.put("sex", "男"); Admin admin = mapper.findAdmin(map); System.out.println(admin); sqlSession.commit(); sqlSession.close(); }
返回基本类型
//查询管理员总人数 int adminCount();
@Test public void find6(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); AdminMapper mapper = sqlSession.getMapper(AdminMapper.class); int count = mapper.adminCount(); System.out.println("管理员总人数:"+count); sqlSession.commit(); sqlSession.close(); }POJO对象输出映射
- 如果表中的类名与类中的属性名完全相同,mybatis会自动将查询结果封装 到POJO对象中
- 如果java中使用标准驼峰命名,数据库中使用下划线连接命名,可以开启全局设置实现自动转换
resultMap:
- resutlMap 的 id 属性是 resutlMap 的唯一标识
- resutlMap 的 id 属性是映射的 POJO 类
- id 标签映射主键,result 标签映射非主键
- property 设置 POJO 的属性名称,column 映射查询结果的列名称
将admin表中列名password修改为pass_word
定义resultMap
多表关联处理查询结果集
-
association – 复杂类型联合
许多查询结果合成这个类型 一对一结果映射
association 能引用自身, 或者从其它地方引用
处理一个类型的关系(类)
-
collection – 复杂类型集合 嵌套结果映射
collection 能引用自身, 或者从其它地方引用 多对一与一对多
处理一对多关联(集合)
-
部门与员工一对多
-
多个员工对应一个部门(多对一)
-
package com.ffyc.mybatisdemo.mapper; import com.ffyc.mybatisdemo.model.Dept; import java.util.List; public interface DeptMapper { //根据id查部门 Dept findDeptById(int id); //查所有部门 ListfindDeptList(); }
sql映射文件
测试根据id查部门
@Test public void findDept(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); DeptMapper mapper = sqlSession.getMapper(DeptMapper.class); Dept dept = mapper.findDeptById(1); ListdeptList = dept.getEmployeeList(); System.out.println("部门"+dept.getName()); for(Employee employee : deptList){ System.out.println("所属员工:"+employee.getName()); } sqlSession.commit(); sqlSession.close(); }
测试查所有部门
@Test public void findDeptList(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); DeptMapper mapper = sqlSession.getMapper(DeptMapper.class); Listdepts = mapper.findDeptList(); for(Dept dept : depts){ System.out.println("部门名称:"+dept.getName()); for(Employee emp : dept.getEmployeeList()){ System.out.println("部门职工:"+emp.getName()); } System.out.println(" *** 作人:"+dept.getAdmin().getAccount()); } sqlSession.commit(); sqlSession.close(); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)