【Mybatis】快速入门 基本使用 第一期
文章目录
- Mybatis是什么?
- 一、快速入门(基于Mybatis3方式)
- 二、MyBatis基本使用
- 2.1 向SQL语句传参
- 2.1.1 mybatis日志输出配置
- 2.1.2 #{}形式
- 2.1.3 ${}形式
- 2.2 数据输入
- 2.2.1 Mybatis总体机制概括
- 2.2.2 概念说明
- 2.2.3 单个简单类型参数
- 2.2.4 实体类类型参数
- 2.2.5 多个简单类型数据
- 2.2.6 Map类型参数
- 2.3 数据输出
- 2.3.1 返回单个简单类型
- 2.3.2 返回实体类对象
- 2.3.3 返回Map类型
- 2.3.4 返回List类型
- 2.3.5 返回主键值
- 2.3.6 实体类属性和数据库字段对应关系
- 2.4 CRUD强化练习
- 2.5 mapperXML标签总结
- 总结
Mybatis是什么?
官网 文档
MyBatis 是一款优秀的持久层框架,MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
开发效率:Hibernate>Mybatis>JDBC
运行效率:JDBC>Mybatis>Hibernate
一、快速入门(基于Mybatis3方式)
- 数据库
CREATE DATABASE `mybatis-example`;USE `mybatis-example`;CREATE TABLE `t_emp`(emp_id INT AUTO_INCREMENT,emp_name CHAR(100),emp_salary DOUBLE(10,5),PRIMARY KEY(emp_id)
);INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("jerry",666.66);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("andy",777.77);
- 项目的搭建 准备
- 项目搭建
- 依赖导入
<dependencies><!-- mybatis依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.11</version></dependency><!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.3.1</version></dependency>
</dependencies>
- 实体类
public class Employee {private Integer empId;private String empName;private Double empSalary;......set/get
- Mapper接口与MapperXML文件
- 定义Mapper接口
/*** @Description: dao层接口*/
public interface EmployeeMapper {/*** 根据ID查找员工信息* @param id* @return*/Employee queryById(Integer id);/*** 根据ID删除对应员工* @param id* @return*/int deleteById(Integer id);
}
- 定义Mapper xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace等于mapper接口类的全限定名,这样实现对应 -->
<mapper namespace="com.wake.mapper.EmployeeMapper"><!-- 查询使用 select标签id = 方法名resultType = 返回值类型标签内编写SQL语句--><select id="queryById" resultType="com.wake.pojo.Employee"><!-- #{id}代表动态传入的参数,并且进行赋值!... -->select emp_id empId,emp_name empName, emp_salary empSalary fromt_emp where emp_id = #{id}</select><delete id="deleteById">delete from t_emp where emp_id = #{id}</delete>
</mapper>
- 准备Mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 --><environments default="development"><!-- environment表示配置Mybatis的一个具体的环境 --><environment id="development"><!-- Mybatis的内置的事务管理器 --><transactionManager type="JDBC"/><!-- 配置数据源 --><dataSource type="POOLED"><!-- 建立数据库连接的具体信息 --><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><mappers><!-- Mapper注册:指定Mybatis映射文件的具体位置 --><!-- mapper标签:配置一个具体的Mapper映射文件 --><!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 --><!-- 对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 --><mapper resource="mappers/EmployeeMapper.xml"/></mappers></configuration>
- 运行 测试
public class MybatisTest {@Testpublic void test_01() throws IOException {// 1. 读取外部配置文件(mybatis-config.xml)InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");// 2. 创建 SqlSessionFactorySqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(ips);// 3. 根据sqlSessionFactory 创建 sqlSession (每次业务创建一个,用完就释放SqlSession session = sessionFactory.openSession();// 4. 获取接口的代理对象(代理技术) 调用代理对象的方法,就会查找Mapper接口的方法//jdk动态代理技术生成的mapper代理对象EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);// 内部拼接接口的全限定符号.方法名 去查找sql语句标签// 拼接 类的全限定符号.方法名 整合参数 -> ibatis对应的方法传入参数// mybatis底层依赖调用ibatis只不过有固定的模式!Employee employee = mapper.queryById(1);System.out.println(employee);// 4.提交事务(非DQL)和释放资源session.commit(); //提交事务 [DQL不需要,其他需要]session.close(); //关闭会话}
}
说明:
SqlSession
:代表Java程序和数据库之间的会话。- (HttpSession是Java程序和浏览器之间的会话)
SqlSessionFactory
:是“生产”SqlSession的“工厂”。- 工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。
SqlSession和HttpSession区别:
- HttpSession:工作在Web服务器上,属于表述层。
- 代表浏览器和Web服务器之间的会话。
- SqlSession:不依赖Web服务器,属于持久化层。
- 代表Java程序和数据库之间的会话。
二、MyBatis基本使用
2.1 向SQL语句传参
2.1.1 mybatis日志输出配置
Mybatis 3 配置
我们可以在mybatis的配置文件使用settings标签设置,输出运过程SQL日志!
通过查看日志,我们可以判定#{} 和 ${}的输出效果!
settings设置项:
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J(3.5.9 起废弃) | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |
---|
日志配置:
<settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings>
开启日志后 测试:
2.1.2 #{}形式
Mybatis会将SQL语句中的#{}转换为问号占位符。
使用这个防止【注入式攻击】
2.1.3 ${}形式
${}形式传参,底层Mybatis做的是字符串拼接操作。
结论:实际开发中,能用#{}实现的,肯定不用${}。
特殊情况: 动态的不是值,是列名或者关键字,需要使用${}拼接
//注解方式传入参数!!
@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);
一个特定的适用场景是:通过Java程序动态生成数据库表,表名部分需要Java程序通过参数传入;而JDBC对于表名部分是不能使用问号占位符的,此时只能使用
2.2 数据输入
Mapper接口中 不允许 重载方法
2.2.1 Mybatis总体机制概括
2.2.2 概念说明
这里数据输入具体是指上层方法(例如Service方法)调用Mapper接口时,数据传入的形式。
- 简单类型:只包含一个值的数据类型
- 基本数据类型:int、byte、short、double、……
- 基本数据类型的包装类型:Integer、Character、Double、……
- 字符串类型:String
- 复杂类型:包含多个值的数据类型
- 实体类类型:Employee、Department、……
- 集合类型:List、Set、Map、……
- 数组类型:int[]、String[]、……
- 复合类型:List<Employee>、实体类中包含集合……
2.2.3 单个简单类型参数
Mapper接口中抽象方法的声明:
/*** 根据ID 查询对应员工信息* @param id* @return*/Employee selectEmpById(Integer id);/*** 根据薪资查找员工信息* @param salary* @return*/List<Employee> selectEmpBySalary(Double salary);/*** 根据ID 删除员工对象* @param id* @return*/int deleteEmpById(Integer id);
SQL语句:
<select id="selectEmpById" resultType="com.wake.pojo.Employee">select emp_id empId , emp_name empName , emp_Salary empSalary fromt_emp where emp_id = #{id};</select><select id="selectEmpBySalary" resultType="com.wake.pojo.Employee">select emp_id empId , emp_name empName , emp_Salary empSalary fromt_emp where emp_salary = #{salary};</select><!-- 传入简单类型 key值 随便写 因为只有一个,一般情况写参数名 --><delete id="deleteEmpById">delete from t_emp where emp_id = #{id};</delete>
2.2.4 实体类类型参数
Mapper接口中抽象方法的声明:
/*** 插入一条员工信息* @param employee* @return*/int insertEmp(Employee employee);
SQL语句:
<!-- 传入实体类 key 等于 属性名 --><insert id="insertEmp">insert into t_emp (emp_name,emp_salary) values(#{empName},#{empSalary})</insert>
2.2.5 多个简单类型数据
Mapper接口中抽象方法的声明:
/*** 根据名字与薪资 查找员工* @param name* @param salary* @return*/Employee selectEmpByNameAndSalary(@Param("empName") String name, @Param("salary") Double salary);/*** 根据ID 修改名字* @param id* @return*/int updateNameById(String name,Integer id);
SQL语句:
<!-- 多个简单参数接口中使用注解@Paramormapper.xml中 用[arg1, arg0, param1, param2]指代 (arg要查找的值 , param是要修改的值)--><select id="selectEmpByNameAndSalary" resultType="com.wake.pojo.Employee">select emp_id empId , emp_name empName , emp_Salary empSalary fromt_emp where emp_name = #{empName} and emp_salary = #{salary};</select><update id="updateNameById">update t_emp set emp_name = #{param1} where emp_id = #{arg1};</update>
2.2.6 Map类型参数
Mapper接口中抽象方法的声明:
/*** 传入map员工对象数据* @param data* @return*/int insertEmpMap(Map data);
SQL语句:
<!-- 传入map的数据 使用的是map的key值 key = map key --><insert id="insertEmpMap">insert into t_emp (emp_name,emp_salary) values(#{name},#{salary})</insert>
2.3 数据输出
数据输出总体上有两种形式:
- 增删改操作返回的受影响行数:直接使用 int 或 long 类型接收即可
- 查询操作的查询结果
2.3.1 返回单个简单类型
返回单个简单类型如何指定 : resultType的写法,用返回值类型。
resultType的语法:
-
- 类的全限定符号
-
- 别名简称
- 指定查询的输出数据类型即可!并且插入场景下,实现主键数据回显示!
- 类型别名(typeAliases)
-
- 自定义类型名字
- 在 mybatis-config.xml 中全局设置:
<!-- 单个类单独定义别名 , 之后resultType 使用“自己设置的名字” --><typeAliases><typeAlias type="com.wake.pojo.Employee" alias="自己设置名字"/></typeAliases><!-- 批量修改 --><typeAliases><!-- 批量将包下的类 设置别名都为首字母小写 --><package name="com.wake.pojo"/></typeAliases><!-- 批量后 想单独设置单个类 使用注解单个类 --><!-- @Alias("666") -->
2.3.2 返回实体类对象
resultType: 返回值类型
<select id="queryEmpById" resultType="employee">select *from t_empwhere emp_Id = #{empId};</select>
要求:
查询,返回单个实体类型,要求 列名 和 属性名 要一致 !
这样才可以进行实体类的属性映射。
mybatis 可以开启属性列名的自动映射:
在 mybatis-config.xml中设置:
<!-- true开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。--><setting name="mapUnderscoreToCamelCase" value="true"/>
2.3.3 返回Map类型
- 接口:
Map<String,Object> selectEmpNameAndMaxSalary();
- sql xml
<!-- Map<String,Object> selectEmpNameAndMaxSalary(); -->
<!-- 返回工资最高的员工的姓名和他的工资 -->
<select id="selectEmpNameAndMaxSalary" resultType="map">SELECTemp_name 员工姓名,emp_salary 员工工资,(SELECT AVG(emp_salary) FROM t_emp) 部门平均工资FROM t_emp WHERE emp_salary=(SELECT MAX(emp_salary) FROM t_emp)
</select>
- junit测试
@Testpublic void mybatisTest01() throws IOException {// 1.读取配置文件InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");// 2. 创建sqlSession 数据库连接工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);// 3. 开启sqlSession 数据库连接SqlSession sqlSession = sqlSessionFactory.openSession();// 4. 确定mapper对象EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);// 5. 执行mapper方法Map<String, Object> stringObjectMap =employeeMapper.selectEmpNameAndMaxSalary();Set<Map.Entry<String, Object>> entries =stringObjectMap.entrySet();for (Map.Entry<String, Object> entry : entries) {String key = entry.getKey();Object value = entry.getValue();System.out.println(key + "---" + value);}sqlSession.close();}
2.3.4 返回List类型
返回值是集合,resultType不需要指定集合类型,只需要指定泛型即可。
因为
mybatis -> ibatis -> selectOne 单个 | selectList 集合 -> selectOne 调用[selectList]
- 接口
/*** 查询全部员工对象* @return*/List<Employee> selectAll();
- mapper.xml
<!-- List<Employee> selectAll(); --><select id="selectAll" resultType="employee">select emp_id empId,emp_name empName,emp_salary empSalaryfrom t_emp</select>
- 测试
@Testpublic void mybatisTest01() throws IOException {// 1.读取配置文件InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");// 2. 创建sqlSession 数据库连接工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);// 3. 开启sqlSession 数据库连接SqlSession sqlSession = sqlSessionFactory.openSession();// 4. 确定mapper对象EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);// 5. 执行mapper方法List<Employee> employees = employeeMapper.selectAll();for (Employee employee : employees) {System.out.println(employee);}sqlSession.close();}
2.3.5 返回主键值
1. 自增长类型主键
- 接口
/*** 插入一条员工信息* @param employee* @return*/int insertEmp(Employee employee);
- xml
<insert id="insertEmp">insert into t_emp(emp_Name,emp_salary)values(#{empName},#{empSalary});</insert>
- 测试
@Testpublic void mybatisTest01() throws IOException {// 1.读取配置文件InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");// 2. 创建sqlSession 数据库连接工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);// 3. 开启sqlSession 数据库连接【自动开启JDBC】// 自动开启事务SqlSession sqlSession = sqlSessionFactory.openSession();// 4. 执行代理对象EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);// 5. 执行mapper方法Employee e1 = new Employee();e1.setEmpName("亚伦");e1.setEmpSalary(147.6);int i = employeeMapper.insertEmp(e1);System.out.println(i);// 6. 释放资源 和 提交事务sqlSession.commit();sqlSession.close();}
主键回显:
- xml
<!--useGeneratedKeys="true" : 开启获取数据库主键值keyColumn="emp_id" : 主键列的值keyProperty="empId" : 接收主键列值的属性--><insert id="insertEmp" useGeneratedKeys="true" keyColumn="emp_id" keyProperty="empId">insert into t_emp(emp_Name,emp_salary)values(#{empName},#{empSalary});</insert>
- 测试:
@Testpublic void mybatisTest01() throws IOException {// 1.读取配置文件InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");// 2. 创建sqlSession 数据库连接工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);// 3. 开启sqlSession 数据库连接【自动开启JDBC】// 自动开启事务SqlSession sqlSession = sqlSessionFactory.openSession(true);// 4. 执行代理对象EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);// 5. 执行mapper方法Employee e1 = new Employee();e1.setEmpName("内尔");e1.setEmpSalary(258.9);// 提交前 主键值System.out.println("前:"+e1.getEmpId());System.out.println("=============================");int i = employeeMapper.insertEmp(e1);System.out.println(i);// 提交后 主键值System.out.println("后:"+e1.getEmpId());// 6. 释放资源 和 提交事务//sqlSession.commit();sqlSession.close();}
2. 非自增长类型主键
新创建一个 表(不添加自动更新索引)
手动添加UUID
create TABLE teacher(t_id VARCHAR(64) PRIMARY KEY,t_name VARCHAR(20)
)
- mapper接口
int insertTeacher(Teacher teacher);
- xml
<mapper namespace="com.wake.mapper.TeacherMapper"><insert id="insertTeacher"><!--order="BEFORE|AFTER" 确定是在插入语句执行前还是后执行resultType="" 返回值类型keyProperty="" 查询结果是给哪个属性--><selectKey order="BEFORE" resultType="string" keyProperty="tId">select replace(UUID(),"-","");</selectKey>insert into teacher(t_id,t_name) values(#{tId},#{tName});</insert>
</mapper>
- 测试
@Testpublic void mybatisTest02() throws IOException {// 1.读取配置文件InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");// 2. 创建sqlSession 数据库连接工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);// 3. 开启sqlSession 数据库连接【自动开启JDBC】// 自动开启事务SqlSession sqlSession = sqlSessionFactory.openSession(true);// 4. 执行代理对象TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);// 5. 执行mapper方法Teacher teacher = new Teacher();teacher.setTName("维克");// 使用mybatis 在xml中定义uuid//String uuid = UUID.randomUUID().toString().replace("-", "");//teacher.setTId(uuid);System.out.println("UUID BEFORE:"+teacher.getTId());int i = teacherMapper.insertTeacher(teacher);System.out.println("UUID AFTER:"+teacher.getTId());System.out.println(i);// 6. 释放资源 和 提交事务//sqlSession.commit();sqlSession.close();}
- 结果:
2.3.6 实体类属性和数据库字段对应关系
- 别名对应
将字段的别名设置成和实体类属性一致。
<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.doug.mybatis.entity.Employee"><!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 --><!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}</select>
- 全局配置自动识别驼峰式命名规则
在Mybatis全局配置文件加入如下配置:
<!-- 使用settings对Mybatis全局进行设置 -->
<settings><!-- 将xxx_xxx这样的列名自动映射到xxXxx这样驼峰式命名的属性名 --><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
就可以不使用别名:
<!-- Employee selectEmployee(Integer empId); -->
<select id="selectEmployee" resultType="com.doug.mybatis.entity.Employee">select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}</select>
- 使用resultMap
使用resultMap标签定义对应关系,再在后面的SQL语句中引用这个对应关系
<!-- 专门声明一个resultMap设定column到property之间的对应关系 -->
<resultMap id="selectEmployeeByRMResultMap" type="com.doug.mybatis.entity.Employee"><!-- 使用id标签设置主键列和主键属性之间的对应关系 --><!-- column属性用于指定字段名;property属性用于指定Java实体类属性名 --><id column="emp_id" property="empId"/><!-- 使用result标签设置普通字段和Java实体类属性之间的关系 --><result column="emp_name" property="empName"/><result column="emp_salary" property="empSalary"/></resultMap><!-- Employee selectEmployeeByRM(Integer empId); -->
<select id="selectEmployeeByRM" resultMap="selectEmployeeByRMResultMap">select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}</select>
2.4 CRUD强化练习
- 数据库准备
CREATE TABLE `user` (`id` INT(11) NOT NULL AUTO_INCREMENT,`username` VARCHAR(50) NOT NULL,`password` VARCHAR(50) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
- 实体类准备
public class User {private int id;private String username;private String password;
- 接口Mapper
public interface UserMapper {/*** 增加* @param user* @return*/int insert(User user);/*** 修改* @param user* @return*/int update(User user);/*** 删除* @param id* @return*/int delete(Integer id);/*** 根据ID查询一条User数据* @param id* @return*/User selectById(Integer id);/*** 查询全部数据* @return*/List<User> selectAll();
}
- Mapper.xml
<mapper namespace="com.wake.mapper.UserMapper"><insert id="insert">insert into user(username,password) values(#{username},#{password});</insert><update id="update">update user set username = #{username},password = #{password} where id = #{id};</update><delete id="delete">delete from user where id = #{id};</delete><select id="selectById" resultType="user">select id,username,password from user where id = #{id};</select><select id="selectAll" resultType="user">select * from user;</select>
</mapper>
- 测试
@Testpublic void insert01() throws IOException {InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();user.setUsername("knell");user.setPassword("999");int insert = userMapper.insert(user);System.out.println(insert);sqlSession.commit();sqlSession.close();}@Testpublic void delete02() throws IOException {InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);int delete = userMapper.delete(3);System.out.println(delete);sqlSession.commit();sqlSession.close();}@Testpublic void update03() throws IOException {InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.selectById(4);user.setUsername("测试");user.setPassword("123456");int update = userMapper.update(user);System.out.println(update);sqlSession.commit();sqlSession.close();}@Testpublic void selectById04() throws IOException {InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.selectById(1);System.out.println(user);sqlSession.commit();sqlSession.close();}@Testpublic void selectAll05() throws IOException {InputStream ips = Resources.getResourceAsStream("Mybatis-Config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);List<User> users = userMapper.selectAll();System.out.println(users);sqlSession.commit();sqlSession.close();}
注意更新要先根据ID查找出对象数据
2.5 mapperXML标签总结
insert
– 映射插入语句。update
– 映射更新语句。delete
– 映射删除语句。select
– 映射查询语句。
属性 | 描述 |
---|---|
id | 在命名空间中唯一的标识符,可以被用来引用这条语句。 |
resultType | 期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。 |
resultMap | 对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultType 和 resultMap 之间只能同时使用一个。 |
timeout | 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。 |
statementType | 可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
总结
Mybatis操作流程:
ibatis 和 Mybatis :
Mybatis 文档:
Mybatis 中文官网
类型的别名:
别名 | 映射的类型 |
---|---|
_byte | byte |
_char (since 3.5.10) | char |
_character (since 3.5.10) | char |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
char (since 3.5.10) | Character |
character (since 3.5.10) | Character |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
biginteger | BigInteger |
object | Object |
object[] | Object[] |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
相关文章:

【Mybatis】快速入门 基本使用 第一期
文章目录 Mybatis是什么?一、快速入门(基于Mybatis3方式)二、MyBatis基本使用2.1 向SQL语句传参2.1.1 mybatis日志输出配置2.1.2 #{}形式2.1.3 ${}形式 2.2 数据输入2.2.1 Mybatis总体机制概括2.2.2 概念说明2.2.3 单个简单类型参数2.2.4 实体…...

在 Rust 中实现 TCP : 1. 联通内核与用户空间的桥梁
内核-用户空间鸿沟 构建自己的 TCP栈是一项极具挑战的任务。通常,当用户空间应用程序需要互联网连接时,它们会调用操作系统内核提供的高级 API。这些 API 帮助应用程序 连接网络创建、发送和接收数据,从而消除了直接处理原始数据包的复杂性。…...

STM32-ADC一步到位学习手册
1.按部就班陈述概念 ADC 是 Analog-to-Digital Converter 的缩写,指的是模拟/数字转换器。它将连续变量的模拟信号转换为离散的数字信号。在 STM32 中,ADC 具有高达 12 位的转换精度,有多达 18 个测量通道,其中 16 个为外部通道&…...
【文件管理】关于上传下载文件的设计
这里主要谈论的是产品设计里面的文件管理,比如文件的上传交互及背后影响到的前后端设计。 上传文件 场景:一条记录,比如个人信息,有姓名,出生年月,性别等一般的字段,还可以允许用户上传附件作为…...

微服务架构 SpringCloud
didi单体应用架构 将项目所有模块(功能)打成jar或者war,然后部署一个进程--医院挂号系统; > 优点: > 1:部署简单:由于是完整的结构体,可以直接部署在一个服务器上即可。 > 2:技术单一:项目不需要复杂的技术栈,往往一套熟…...

前端 css 实现标签的效果
效果如下图 直接上代码: <div class"label-child">NEW</div> // css样式 // 父元素 class .border-radius { position: relative; overflow: hidden; } .label-child { position: absolute; width: 150rpx; height: 27rpx; text-align: cente…...

SLAM基础知识-卡尔曼滤波
前言: 在SLAM系统中,后端优化部分有两大流派。一派是基于马尔科夫性假设的滤波器方法,认为当前时刻的状态只与上一时刻的状态有关。另一派是非线性优化方法,认为当前时刻状态应该结合之前所有时刻的状态一起考虑。 卡尔曼滤波是…...

云时代【6】—— 镜像 与 容器
云时代【6】—— 镜像 与 容器 四、Docker(三)镜像 与 容器1. 镜像(1)定义(2)相关指令(3)实战演习镜像容器基本操作离线迁移镜像镜像的压缩与共享 2. 容器(1)…...

【QT+QGIS跨平台编译】之五十三:【QGIS_CORE跨平台编译】—【qgssqlstatementparser.cpp生成】
文章目录 一、Bison二、生成来源三、构建过程一、Bison GNU Bison 是一个通用的解析器生成器,它可以将注释的无上下文语法转换为使用 LALR (1) 解析表的确定性 LR 或广义 LR (GLR) 解析器。Bison 还可以生成 IELR (1) 或规范 LR (1) 解析表。一旦您熟练使用 Bison,您可以使用…...

JMeter性能测试基本过程及示例
jmeter 为性能测试提供了一下特色: jmeter 可以对测试静态资源(例如 js、html 等)以及动态资源(例如 php、jsp、ajax 等等)进行性能测试 jmeter 可以挖掘出系统最大能处理的并发用户数 jmeter 提供了一系列各种形式的…...

你知道什么是回调函数吗?
c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行&am…...

mac苹果电脑c盘满了如何清理内存?2024最新操作教程分享
苹果电脑用户经常会遇到麻烦:内置存储器(即C盘)空间不断缩小,电脑运行缓慢。在这种情况下,苹果电脑c盘满了怎么清理?如何有效清理和优化存储空间,提高计算机性能?成了一个重要的问题。今天,我想给大家详细介…...

k8s-kubeapps图形化管理 21
结合harbor仓库 由于kubeapps不读取hosts解析,因此需要添加本地仓库域名解析(dns解析) 更改context为全局模式 添加repo仓库 复制ca证书 添加成功 图形化部署 更新部署应用版本 再次进行部署 上传nginx 每隔十分钟会自动进行刷新 在本地仓库…...
1_Springboot(一)入门
Springboot(一)——入门 本章重点: 1.什么是Springboot; 2.使用Springboot搭建web项目; 一、Springboot 1.Springboot产生的背景 Servlet->Struts2->Spring->SpringMVC,技术发展过程中,对使…...
Docker Machine简介
Docker Machine 是一种可以让您在虚拟主机上安装 Docker 的工具,并可以使用 docker-machine 命令来管理主机。 Docker Machine 也可以集中管理所有的 docker 主机,比如快速的给 100 台服务器安装上 docker。 Docker Machine 管理的虚拟主机可以是机上的…...

GWO优化高斯回归预测(matlab代码)
GWO-高斯回归预测matlab代码 GWO(Grey Wolf Optimizer,灰狼优化算法)是一种群智能优化算法,由澳大利亚格里菲斯大学的Mirjalili等人于2014年提出。这种算法的设计灵感来源于灰狼群体的捕食行为,其核心思想在于模仿灰狼…...

LaTeX-设置图像与表格位置
文章目录 LaTeX-设置图像与表格位置1.图像位置定位1.1 基本定位1.2 figure环境实现图像的位置定位(常用)1.3 一个图形中包含多个图像1.4在图形周围换行文本 2.表格位置定位2.1基本定位2.1 table环境实现表格的位置定位(常用)2.3在…...

STM32 DMA入门指导
什么是DMA DMA,全称直接存储器访问(Direct Memory Access),是一种允许硬件子系统直接读写系统内存的技术,无需中央处理单元(CPU)的介入。下面是DMA的工作原理概述: 数据传输触发&am…...

mysql根据指定顺序返回数据--order by field
在查询数据的时候,在in查询的时候,想返回的数据根据 in里的数据顺序返回,可以直接在orderby中通过 FIELD(字段名称逗号分隔的值的顺序) 进行指定;示例没有加 order by field添加 order by field效果...
IEEE SGL与NVMe SGL的区别?
在HBA(Host Bus Adapter)驱动程序中,IEEE SGL(Institute of Electrical and Electronics Engineers Scatter-Gather List)和NVMe SGL(Non-Volatile Memory Express Scatter-Gather List)是两种不…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...

Yolo11改进策略:Block改进|FCM,特征互补映射模块|AAAI 2025|即插即用
1 论文信息 FBRT-YOLO(Faster and Better for Real-Time Aerial Image Detection)是由北京理工大学团队提出的专用于航拍图像实时目标检测的创新框架,发表于AAAI 2025。论文针对航拍场景中小目标检测的核心难题展开研究,重点解决…...

多模态大语言模型arxiv论文略读(110)
CoVLA: Comprehensive Vision-Language-Action Dataset for Autonomous Driving ➡️ 论文标题:CoVLA: Comprehensive Vision-Language-Action Dataset for Autonomous Driving ➡️ 论文作者:Hidehisa Arai, Keita Miwa, Kento Sasaki, Yu Yamaguchi, …...

安宝特案例丨寻医不再长途跋涉?Vuzix再次以AR技术智能驱动远程医疗
加拿大领先科技公司TeleVU基于Vuzix智能眼镜打造远程医疗生态系统,彻底革新患者护理模式。 安宝特合作伙伴TeleVU成立30余年,沉淀医疗技术、计算机科学与人工智能经验,聚焦医疗保健领域,提供AR、AI、IoT解决方案。 该方案使医疗…...