Java mybatis day1015
ok了家人们,今天学习了mybatis这个框架,我们一起去看看吧
一.Mybatis简介
1.1 Mybatis概述
1.2 浅谈JDBC代码
public class DemoTest {public static void main(String[] args) {//1. 注册驱动Class.forName("com.mysql.jdbc.Driver");//2. 获取Connection连接String url = "jdbc:mysql:///db1? useSSL=false";String uname = "root";String pwd = "1234";Connection conn =DriverManager.getConnection(url, uname, pwd);// 接收输入的查询条件String gender = "男";// 定义sqlString sql = "select * from tb_user where gender = ?";// 获取pstmt对象PreparedStatement pstmt =conn.prepareStatement(sql);// 设置?的值pstmt.setString(1,gender);// 执行sqlResultSet rs = pstmt.executeQuery();// 遍历Result,获取数据User user = null;ArrayList<User> users = new ArrayList<>();while (rs.next()) {//获取数据int id = rs.getInt("id");String username =rs.getString(“username”);String password =rs.getString(“password”);//创建对象,设置属性值user = new User();user.setId(id);user.setUsername(username);user.setPassword(password);user.setGender(gender);//装入集合users.add(user);}//释放资源rs.colse();pstmt.colse();conn.close();}
}
- 硬编码
- 操作繁琐
1.3 框架名词解释
- 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
- 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展
二.快速入门(基于Mybatis3方式)
2.1 入门案例实现步骤
- 创建数据库和表
- 创建模块,导入坐标
- 实体类准备
- 编写Mybatis核心配置文件
- 编写Mapper接口
- 编写 SQL 映射文件
- 测试
创建数据库和表
CREATE TABLE t_emp(
emp_id INT primary key AUTO_INCREMENT,
emp_name CHAR(100),
emp_salary DOUBLE(10,5)
);
INSERT INTO t_emp(emp_name,emp_salary)
VALUES("张三",200.33);
INSERT INTO t_emp(emp_name,emp_salary)
VALUES("李四",200.44);
INSERT INTO t_emp(emp_name,emp_salary)
VALUES("王五",200.55);
<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-connectorjava</artifactId>
<version>8.0.25</version>
</dependency><!--junit5测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiterapi</artifactId>
<version>5.3.1</version>
</dependency>
</dependencies>
public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Double getEmpSalary() {
return empSalary;
}
public void setEmpSalary(Double empSalary) {
this.empSalary = empSalary;
}
@Override
public String toString() {
return "Employee{" +
"empId=" + empId +
", empName='" + empName + '\'' +
", empSalary=" + empSalary +
'}';
}
}
- 替换连接信息 解决硬编码问题
- 在模块下的 resources 目录下创建 mybatis 的配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config
3.0//EN"
"https://mybatis.org/dtd/mybatis-3-
config.dtd">
<!--configuration表示mybatis框架的核心配置文件的根标
签,配置-->
<configuration>
<!--
environments:表示当前mybatis框架的环境:开发
测试环境等
一个environments标签下面可以书写多个
environment
一个environment标签代表一个环境
-->
<environments default="development">
<environment id="development">
<!--
事务管理,这里先使用mybatis框架的默认
管理type="JDBC",实际开发中
mybatis框架的事务由spring框架
-->
<transactionManager type="JDBC">
</transactionManager>
<!---->
<dataSource type="POOLED">
<property name="driver"
value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/ssm_01"/><property name="username"
value="root"/>
<property name="password"
value="123456"/>
</dataSource>
</environment>
</environments>
<!--加载映射配置文件-->
<mappers>
<mapper resource="EmployeeMapper.xml">
</mapper>
</mappers>
</configuration>
编写Mapper接口
package com.lzw.mapper;
import com.lzw.pojo.Employee;
import java.util.List;
//接口只规定方法,参数和返回值!映射配置文件中编写具体SQL
语句!
public interface EmployeeMapper {
public List<Employee> findAll();
}
- 统一管理sql语句,解决硬编码问题
- 在模块的 resources 目录下创建映射配置文件EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper
3.0//EN"
"https://mybatis.org/dtd/mybatis-3-
mapper.dtd">
<!--namespace:名称空间 该映射配置文件和哪个Mapper接口
进行映射绑定-->
<mapper
namespace="com.lzw.mapper.EmployeeMapper">
<!--
id:唯一标识,映射接口的方法
resultType:输出的参数类型
-->
<select id="findAll"
resultType="com.lzw.pojo.Employee">
select emp_id empId,emp_name
empName,emp_salary empSalary from t_emp
</select>
</mapper>
public class DemoTest {
//入门案例
@Test
public void test01() throws IOException {
//读取核心配置文件
InputStream in =
Resources.getResourceAsStream("mybatisconfig.xml");
//构建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(in);
//通过SqlSessionFactory工厂对象获取SqlSession对象(就是connection)
SqlSession sqlSession =
sqlSessionFactory.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
List<Employee> employeeList =
employeeMapper.findAll();
//处理结果
for (Employee employee : employeeList) {
System.out.println(employee);
}
//释放资源
sqlSession.close();
}
}
2.2 Lombok插件的使用(简化代码)

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency>
注解 | 作用 |
@Data | 生成 getXxx() 方法、 setXxx() 方 法、 toString() 、 equals() 、 canEqual() 、 hashCode() 方法 |
@AllArgsConstructor | 生成全参构造器 |
@NoArgsConstructor | 生成无参构造器 |
@Slf4j | 生成日志对象 |
@Getter | 生成 getXxx() 方法 |
@Setter | 生成 setXxx() 方法 |
@ToString | 生成 toString() 方法 |
package com.cjx.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {private Integer empId;private String empName;private Double empSalary;
}
2.3 日志框架(便于调试)
2.3.1 用日志打印替代sout
2.3.2 Java日志体系演变
门面:类似于标准层、接口层
名称 | 说明 |
JCL ( Jakarta Commons Logging ) | 陈旧 |
SLF4J ( Simple Logging Facade for Java) | 适合( 同一作 者 ) |
jboss-logging | 特殊专业领域使用 |
名称 | 说明 |
log4j | 最初版( 同一作者 ) |
JUL ( java.util.logging ) | JDK 自带 |
log4j2 | Apache 收购 log4j 后全面重构, 内部实现和 log4j 完全不同 |
logback | 优雅、强大( 同一作者 ) |
- 门面:SLF4J
- 实现:logback
2.3.3 日志用法
- 依赖导入
<!-- 日志 会自动传递slf4j门面-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
- 引入配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<!-- 指定日志输出的位置,ConsoleAppender表示输出
到控制台 -->
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 日志输出的格式 -->
<!-- 按照顺序分别是:时间、日志级别、线程
名称、打印日志的类、日志主体内容、换行 -->
<pattern>[%d{HH:mm:ss.SSS}]
[%-5level] [%thread] [%logger]
[%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
2.4 工具类抽取(简化代码)
</appender>
<!-- 设置全局日志级别。日志级别按顺序分别是:
TRACE、DEBUG、INFO、WARN、ERROR -->
<!-- 指定任何一个日志级别都只打印当前级别和后面级别
的日志。 -->
<root level="DEBUG">
<!-- 指定打印日志的appender,这里通
过“STDOUT”引用了前面配置的appender -->
<appender-ref ref="STDOUT" />
</root>
<!-- 根据特殊需求指定局部日志级别,可也是包名或全类
名。 -->
<logger name="com.lzw.mapper" level="DEBUG"
/>
</configuration>
2.4 工具类抽取(简化代码)
package com.cjx.utils;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 SqlSessionUtil {private static SqlSessionFactory sqlSessionFactory=null;static {try {//读取核心配置文件InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//构建SqlSessionFactory工厂对象sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);} catch (IOException e) {e.printStackTrace();}}public static SqlSession openSession(){//通过SqlSessionFactory工厂对象获取SqlSession对象(就是connection)SqlSession sqlSession = sqlSessionFactory.openSession();return sqlSession;}
}
package com.cjx.test;import com.cjx.mapper.EmployeeMapper;
import com.cjx.pojo.Employee;
import com.cjx.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class DemoTest {//查询所有@Testpublic void test01(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法List<Employee> employeeList = employeeMapper.findAll();//处理结果for (Employee employee : employeeList) {System.out.println(employee);}//释放资源sqlSession.close();}
2.5 增删改查
- Mapper接口
package com.cjx.mapper;import com.cjx.pojo.Employee;
import org.apache.ibatis.annotations.Param;import java.util.List;
import java.util.Map;public interface EmployeeMapper {//查询所有数据List<Employee> findAll();//查询单个数据Employee findEmpById(Integer empId);//添加一条数据public Integer insertEmp(Employee employee);//修改一条数据public Integer updateEmp(Employee employee);//删除一条数据public Integer deleteEmpById(Integer empId);//修改一条数据 零散的简单类型数据public Integer updateEmpById(@Param("empName") String empName,@Param("empSalary") double empSalary,@Param("empId") Integer empId);//修改一条数据public Integer update(Map<String,Object> map);
}
- 映射配置文件
<?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 namespace="com.cjx.mapper.EmployeeMapper"><!--id:唯一标识 接口的方法名保持一致--><!--结果类型:如果是集合 写集合的元素的类型--><select id="findAll" resultType="Employee">select * from t_emp</select><select id="findEmpById" parameterType="int" resultType="Employee">select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}</select><insert id="insertEmp">insert into t_emp values(null,#{empName},#{empSalary})</insert><update id="updateEmp">update t_emp set emp_name=#{empName},emp_salary=#{empSalary} where emp_id=#{empId}</update><delete id="deleteEmpById" parameterType="int">delete from t_emp where emp_id=#{empId}</delete><update id="updateEmpById">update t_emp set emp_name=#{empName},emp_salary=#{empSalary} where emp_id=#{empId}</update><update id="update" parameterType="Map">update t_emp set emp_name=#{empName},emp_salary=#{empSalary} where emp_id=#{empId}</update>
</mapper>
- 测试
package com.cjx.test;import com.cjx.mapper.EmployeeMapper;
import com.cjx.pojo.Employee;
import com.cjx.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class DemoTest {//查询所有@Testpublic void test01(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法List<Employee> employeeList = employeeMapper.findAll();//处理结果for (Employee employee : employeeList) {System.out.println(employee);}//释放资源sqlSession.close();}//通过Id查询数据@Testpublic void test02(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法Employee emp = employeeMapper.findEmpById(1);//处理结果System.out.println(emp);//释放资源sqlSession.close();}//新增一条数据@Testpublic void test03(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法Employee employee = new Employee(null,"赵六",260.0);Integer emp = employeeMapper.insertEmp(employee);//处理结果System.out.println(emp);//提交事务sqlSession.commit();//释放资源sqlSession.close();}//修改一条数据根据Id@Testpublic void test04(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法Employee employee = new Employee(1,"zs",230.0);Integer emp = employeeMapper.updateEmp(employee);//处理结果System.out.println(emp);//提交事务sqlSession.commit();//释放资源sqlSession.close();}//删除一条数据根据Id@Testpublic void test05(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法Integer emp = employeeMapper.deleteEmpById(4);//处理结果System.out.println(emp);//提交事务sqlSession.commit();//释放资源sqlSession.close();}//修改一条数据根据Id@Testpublic void test07(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法Integer emp = employeeMapper.updateEmpById("ww",255.55,3);//处理结果System.out.println(emp);//提交事务sqlSession.commit();//释放资源sqlSession.close();}//修改一条数据根据Id@Testpublic void test06(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法Map<String,Object> map = new HashMap<>();map.put("empName","ls");map.put("empSalary",244.44);map.put("empId",2);Integer emp = employeeMapper.update(map);//处理结果System.out.println(emp);//提交事务sqlSession.commit();//释放资源sqlSession.close();}
}
- 注意事项
三. MyBatis核心配置文件
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
3.1 properties(属性)
- db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_01
jdbc.username=root
jdbc.password=123456
- mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!--加载外部properties--><properties resource="db.properties"></properties><!--开启自动映射 驼峰命名--><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings><!--起别名--><typeAliases><package name="com.cjx.pojo"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--8.x--><property name="driver" value="${jdbc.driver}"/><!--5.x--><!-- <property name="driver" value="com.mysql.jdbc.Driver"/>--><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!--核心配置文件加载映射配置文件--><mappers><mapper resource="EmployeeMapper.xml"/></mappers>
</configuration>
3.2 settings(设置)
设置名 | 描述 |
mapUnderscoreToCamelCase | 是否开启驼峰命名自动 映射,即从经典数据库 列名 A_COLUMN 映射 到经典 Java 属性名 aColumn 。 取值: true | false 默认值: false |
<!--开启驼峰映射-->
<settings>
<setting name="mapUnderscoreToCamelCase"
value="true"/>
</settings>
3.3 typeAliases(类型别名)
<typeAliases><package name="com.cjx.pojo"/></typeAliases>
3.4 environments(环境配置)
<environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--8.x--><property name="driver" value="${jdbc.driver}"/><!--5.x--><!-- <property name="driver" value="com.mysql.jdbc.Driver"/>--><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments>
四.数据输入
- 简单类型:只包含一个值的数据类型
- 基本数据类型:int、byte、short、double、……
- 基本数据类型的包装类型:Integer、Character、Double、……
- 字符串类型:String
- 复杂类型:包含多个值的数据类型
- 实体类类型:Employee、Department、……
- 集合类型:List、Set、Map、……
- 数组类型:int[]、String[]、……
- 复合类型:List<Employee>、实体类中包含集合……
4.1 参数占位符
public interface EmployeeMapper {
//查询单个数据
public Employee findEmpById01(Integer
empId);
}
<select id="findEmpById01" parameterType="int"
resultType="Employee">
select * from t_emp where emp_id = #{empId}
</select>
public interface EmployeeMapper {
//查询单个数据
public Employee findEmpById02(Integer
empId);
}
<select id="findEmpById02" parameterType="int"
resultType="Employee">
select * from t_emp where emp_id = ${empId}
</select>
4.2 parameterType使用
<insert id="insertEmp" parameterType="Employee">
insert into t_emp values(null,#{empName},#
{empSalary})
</insert>
4.3 单个简单类型参数
4.3.1 编写接口方法
public interface EmployeeMapper {
//删除一条数据
public Integer deleteEmpById(Integer empId);
}
4.3.2 编写SQL语句
<delete id="deleteEmpById"
parameterType="java.lang.Integer">
delete from t_emp where emp_id = #{empId}
</delete>
- 增删改接口的返回值是 Integer, 表示返回影响的行数 , 在映射配置文件中不需要设置 resultType
- 单个简单类型参数,在 #{} 中可以随意命名,但是没有必要。通常还是使用和接口方法参数同名。
4.3.3 编写测试方法
//删除一条数据根据Id@Testpublic void test05(){//获取SqlSessionSqlSession sqlSession = SqlSessionUtil.openSession();//基于接口获取实现类对象(代理对象)EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//通过多态调用方法Integer emp = employeeMapper.deleteEmpById(4);//处理结果System.out.println(emp);//提交事务sqlSession.commit();//释放资源sqlSession.close();}
4.4 实体类类型参数
4.4.1 编写接口方法
public interface EmployeeMapper {
//添加一条数据
public Integer insertEmp(Employee employee);
}
4.4.2 编写SQL语句
<!--实体传参,在映射配置文件中取值,直接写对象的属性名-->
<insert id="insertEmp" parameterType="Employee">
insert into t_emp values(null,#{empName},#
{empSalary})
</insert>
4.4.3 编写测试方法
@Test
public void testInsert(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
Employee employee=new Employee(null,"王五",555.22);
Integer row = employeeMapper.insertEmp(employee);
//输出结果
System.out.println(row);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
4.5 零散的简单类型数据
4.5.1 编写接口方法
public interface EmployeeMapper {
//根据ID修改员工姓名
public Integer updateNameById(String
empName,Integer empId);
}
4.5.2 编写SQL语句
<update id="updateNameById">
update t_emp set emp_name = #{empName} where
emp_id = #{empId}
</update>
4.5.3 编写测试方法
@Test
public void testupdateNameById(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
Integer row =
employeeMapper.updateNameById("zs",1);
//输出结果
System.out.println(row);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
4.5.4 解决方案
- 修改配置文件取值方式
<update id="updateNameById">
update t_emp set emp_name = #{param1} where
emp_id = #{param2}
</update>
- 使用 @Param(" 参数名称 ") 标记每一个参数,在映射配置文件中就需要使用 #{ 参数名称 } 进行占位
public interface EmployeeMapper {
//根据ID修改员工姓名
public Integer
updateNameById(@Param("empName") String empName,
@Param("empId") Integer empId);
}
<update id="updateNameById">
update t_emp set emp_name = #{empName} where
emp_id = #{empId}
</update>
4.6 Map类型参数
4.6.1 编写接口方法
public interface EmployeeMapper {
//修改一条数据
public Integer updateEmp(Map<String,Object>
map);
}
4.6.2 编写SQL语句
<!--通过key获取value的值-->
<update id="updateEmp" parameterType="Employee">
update t_emp set emp_name = #
{empName},emp_salary = #{empSalary} where
emp_id = #{empId}
</update>
4.6.3 编写测试代码
@Test
public void testUpdate(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
Map<String,Object> map=new HashMap<>();
map.put("empId",3);
map.put("empName","ww");
map.put("empSalary",55.33);
Integer row = employeeMapper.updateEmp(map);
//输出结果
System.out.println(row);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
五.数据输出
5.1 输出概述
- 增删改操作返回受影响行数:直接在接口方法中使用 int或 long 类型接收即可
- 查询操作的查询结果
5.2 返回单个简单类型
5.2.1 编写接口方法
public interface EmployeeMapper {
//查询总条数
public Integer findTotalCount();
}
5.2.2 编写SQL语句
<select id="findTotalCount" resultType="int">
select count(*) from t_emp
</select>
5.2.3 编写测试代码
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
Integer totalCount =
employeeMapper.findTotalCount();
//输出结果
System.out.println(totalCount);
//释放资源
sqlSession.close();
}
5.3 返回实体类对象
5.3.1 编写接口方法
public interface EmployeeMapper {
//根据ID查询用户信息
public Employee findEmpById(Integer empId);
}
5.3.2 编写SQL语句
<select id="findEmpById" parameterType="int"
resultType="Employee">
select * from t_emp where emp_id = #{empId}
</select>
5.3.3 编写测试代码
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
Employee employee =
employeeMapper.findEmpById(1);
//输出结果
System.out.println(employee);
//释放资源
sqlSession.close();
}
5.4 返回List类型
public interface EmployeeMapper {
//查询所有数据
public List<Employee> findAll();
}
<select id="findAll" resultType="Employee">
select * from t_emp
</select>
5.4.3 编写测试代码
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
List<Employee> employeeList =
employeeMapper.findAll();
//输出结果
for (Employee employee : employeeList) {
System.out.println(employee);
}
//释放资源
sqlSession.close();
}
5.5 返回Map类型
5.5.1 编写接口方法
public interface EmployeeMapper {
//查询所有员工的最高工资,最低工资,平均工资
public Map<String,Object> findSalary();
}
5.5.2 编写SQL语句
<select id="findSalary" resultType="Map">
select max(emp_salary) 最高工资,min(emp_salary) 最低工资,avg(emp_salary) 平局工资 from t_emp
</select>
5.5.3 编写测试代码
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
Map<String, Object> map =
employeeMapper.findSalary();
//输出结果
Set<Map.Entry<String, Object>> entrySet =
map.entrySet();
for (Map.Entry<String, Object> entry :
entrySet) {
System.out.println(entry.getKey()+"..."+entry.g
etValue());
}
//释放资源
sqlSession.close();
}
5.6 主键回填
5.6.1 自增长类型主键
public interface EmployeeMapper {
//添加数据
public Integer insertEmp(Employee employee);
}
<!--
主键回填:当Mybatis执行新增后,会将数据库中该
条数据新增后的主键回填到实体的属性上
useGeneratedKeys:是否启用主键回填
keyProperty:指定主键回填到实体的哪个属性上
keyColumn:指定数据库中哪一列是主键(可选)
-->
<insert id="insertEmp" parameterType="Employee"
useGeneratedKeys="true" keyProperty="empId">
insert into t_emp values(null,#{empName},#
{empSalary})
</insert>
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
Employee employee=new Employee(null,"赵
六",11.22);
Integer integer =
employeeMapper.insertEmp(employee);
//输出结果
System.out.println(integer);
//后续需要完善员工信息
System.out.println(employee);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
5.6.2 非自增长类型主键
CREATE TABLE t_user (
id varchar(64) primary key,
username varchar(50),
password varchar(50)
)
public interface UserMapper {
//添加数据
public Integer insertUser(User user);
}
<mapper namespace="com.lzw.mapper.UserMapper">
<insert id="insertUser"
parameterType="user">
<!--
keyProperty:设置为实体的哪个属性,
resultType:设置返回值类型,
order:值为after和before
after: sql之后执行,before: sql之前执行
-->
<selectKey order="BEFORE"
resultType="string" keyProperty="id">
select replace(UUID(),'-','')
</selectKey>
insert into t_user values(#{id},#
{username},#{password})
</insert>
</mapper>
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
UserMapper userMapper =
sqlSession.getMapper(UserMapper.class);
//通过多态调用方法
//String id=
UUID.randomUUID().toString().replace("-","");
User user=new User(null,"zs","123456");
Integer integer =
userMapper.insertUser(user);
//输出结果
System.out.println(integer);
//后续需要完善用户信息
System.out.println(user);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
see you later!!!
相关文章:

Java mybatis day1015
ok了家人们,今天学习了mybatis这个框架,我们一起去看看吧 一.Mybatis简介 1.1 Mybatis概述 MyBatis 最初是 Apache 的一个开源项目 iBatis, 2010 年 6 月 这个项目由 Apache Software Foundation 迁移到了 Google Code 。随着开发团队转投 Google Cod…...

音乐播放器项目专栏介绍
1.简介 本专栏使用Qt QWidget作为显示界面,你将会学习到以下内容: 1.大量ui美化的实例。 2.各种复杂ui布局。 3.常见显示效果实现。 4.大量QSS实例。 5.Qt音频播放,音乐歌词文件加载,展示。 6.播放器界面换肤。 相信学习了本专栏…...
如何修改SpringBoot内置容器默认上下文
引言 默认情况下,Spring boot 应用程序通过上下文路径“/”访问,这是嵌入式服务器的默认设置,即我们可以直接通过http://localhost:8080/访问该应用程序。 但是在生产环境中部署 Spring Boot 应用程序时,指定上下文路径是一个常…...

R语言详解predict函数
R语言中predict函数在建立模型,研究关系时常用。但是不同type得到的结果常常被混为一谈,接下来,探讨predict得到的不同结果。 #数据 set.seed(123) n<-1000 age<-rnorm(n,mean50,sd10) gender<-rbinom(n,1,0.5) disease<-rbinom…...

QT 实现随机码验证
1.界面实现效果 以下是具体的项目需要用到的效果展示,用于验证字母。 2.简介 自定义CaptchaMovableLabel,继承自QLabel类: 中间的4个字母,就是CaptchaMovableLabel类来实例化的对象。 主要功能如下: 1.显示字母&am…...

集合框架12:Set集合概述、Set接口使用
视频链接:13.24 Set接口使用_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1zD4y1Q7Fw?spm_id_from333.788.videopod.episodes&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5&p24 1、Set集合概述 特点:无序、无下标,元素不可…...
如何打开荣耀手机的调试模式?
问题描述: 最近用荣耀手机进行测试,打开开发者选项,打开USB调试,在选择USB配置时,发现仅有选择USB以太网才可以连接Android Studio,也就是打开ADB调试模式。 但是,打开USB以太网后,…...

Meta新模型Dualformer:融合快慢思维,推理能力媲美人脑
Meta 的 FAIR 团队最近推出了一款名为 Dualformer 的全新 Transformer 模型,该模型模仿人类的双重认知系统,能够无缝整合快速和慢速推理模式,在推理能力和计算效率上取得了显著突破。 人类的思维过程通常被认为是由两种系统控制的:系统1快速…...

CDGA|数据治理:如何让传统行业实现数据智能
在当今这个数字化时代,数据已成为推动各行各业转型升级的关键力量。对于传统行业而言,如何从海量、复杂的数据中挖掘价值,实现“数据智能”,成为了提升竞争力、优化运营效率、创新业务模式的重要途径。本文将探讨数据治理如何助力…...

Spring源码5.2.9 编译踩坑
源码编译踩坑 拉取源码 我这块以5.2.9版本为例 spring-projects/spring-framework at v5.2.9.RELEASE (github.com) 版本分析 确定版本 这块将Gradle升级到了5.6.4 ,我们去官网下载即可 Gradle安装 Gradle | Releases 解压 将其解压到你想存放的文件夹 配置环…...

【前端】如何制作一个自己的网页(5)
上节课我们学习了以下知识: 1、网页中常见的文本元素,如标题元素与段落元素; 2、两个通用属性id与class; 3、元素的两种类型——块级元素与行内元素。 其实除了文本内容外,网页还可以包含图片、超链接等各类信息&a…...

Unity实战案例全解析 类宝可梦回合制的初级案例 源码分析(加了注释和流程图)
这是一个老教程了,但是对于没有写过回合制的初级程序同学来讲是比较适合的,也可以直接看源码,半小时内可以解决战斗 当然,我也没写过回合制系统所以就到处找,思路明白了就能自己修改了 视频教程 - 油管链接 Turn-Bas…...
AI绘图大模型 Stable Diffusion 使用详解
近年来,生成式 AI 技术,特别是 AI 绘图模型的进展令人瞩目。Stable Diffusion 是其中一款开源的大规模图像生成模型,它能够根据文本描述生成高质量的图像,支持从写实风格到卡通、幻想等各种不同的视觉效果。本文将深入介绍如何使用…...

es索引库操作和使用RestHignLevelClient客户端操作es
目录 es索引库操作 mapping映射操作 索引库的CURD操作 1.创建索引库和映射 编辑 2.查询索引库 3.删除索引库 4.修改索引库 5.总结 文档的CURD操作 1.新增文档 2.查询文档 3.删除文档 4.修改文档 全量修改 增量修改 5.总结 RestAPI 使用API例子 需要的数…...
安卓数据共享
在 Android 中,数据共享是指不同应用之间共享数据或同一应用不同组件之间共享数据的机制。SQLite 数据库、内容提供者(Content Provider)、共享偏好(Shared Preferences)和文件存储等方式可以实现数据共享。下面将详细…...

Gin框架操作指南02:JSON渲染
官方文档地址(中文):https://gin-gonic.com/zh-cn/docs/ 注:本教程采用工作区机制,所以一个项目下载了Gin框架,其余项目就无需重复下载,想了解的读者可阅读第一节:Gin操作指南&#…...
【随手记】MySQL单表访问方法
在MySQL查询优化器中,单表访问方法(Access Method)指的是查询时数据库如何从一个表中访问所需的数据。不同的访问方法适用于不同的查询场景,主要包括 const、ref、ref_or_null、range、index 和 all。这些方法从效率上依次递减&am…...
机器学习:情感分析的原理、应用场景及优缺点介绍
一、情感分析算法概述 情感分析是自然语言处理中的一个重要任务,主要用于判断文本中所包含的情感倾向,如正面、负面或中性。 二、基于词典的情感分析算法 原理 词典构建:首先需要构建一个情感词典。这个词典包含了一系列带有情感倾向的词汇…...

基于SSM的医院药品管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...

特征融合篇 | YOLOv10 引入动态上采样模块 | 超过了其他上采样器
本改进已集成到YOLOv8-Magic 框架 论文名称:《Learning to Upsample by Learning to Sample》 论文地址:https://arxiv.org/abs/2308.15085 代码地址:https://github.com/tiny-smart/dysample 我们提出了 DySample,一种超轻量级且有效的动态上采样器。尽管最近基于内核的…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...

前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...