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,一种超轻量级且有效的动态上采样器。尽管最近基于内核的…...

【Linux系列】写入文本到文件
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【踩坑随笔】Tensorflow-GPU训练踩坑
一个无语的坑,4060单卡训练,8G内存本来就不够,还没开始训练就已经爆内存了,但是居然正常跑完了训练,然后一推理发现结果就是一坨。。。往回翻日志才发现原来中间有异常。 首先解决第一个问题:Could not lo…...

【云岚到家】-day07-4-实战项目-优惠券活动-项目准备
【云岚到家-即刻体检】-day07-4-实战项目-优惠券活动-活动管理 1 模块需求分析1.1 业务流程1.2 界面原型1.3 业务模块 2 模块设计2.1 数据流2.2 表结构设计2.2.1 优惠券活动表设计2.2.2 优惠券表设计2.2.3 优惠券核销表2.2.4 优惠券退回表 2.3 创建数据库2.4 创建工程 1 模块需…...

axios的使用
在 Vue 项目中,封装 Axios 并实现加密、重复请求优化、请求取消、页面切换时取消未完成的请求、以及区分上传和下载操作是非常常见的需求。下面将逐一讲解这些需求的实现方式。 1. Axios 的基本封装 首先,我们可以将 Axios 封装到一个服务层中…...

Ubuntu 使用命令克隆和恢复SD卡
因为平常我需要做很多张开发板的出货卡,测试卡,那么我需要将备份下来文件,方便后续管理,这里时候需要用到Ubuntu上面的命令来克隆镜像和恢复镜像到SD卡上 先查询自己的SD卡是在sdx,以我的为例子,为sdb 备…...

Java 小游戏《超级马里奥》
文章目录 一、效果展示二、代码编写1. 素材准备2. 创建窗口类3. 创建常量类4. 创建动作类5. 创建关卡类6. 创建障碍物类7. 创建马里奥类8. 编写程序入口 一、效果展示 二、代码编写 1. 素材准备 首先创建一个基本的 java 项目,并将本游戏需要用到的图片素材 image…...

go语言defer详解
什么是defer?为什么需要defer?怎样合理使用defer?defer进阶 defer的底层原理是什么?利用defer原理defer命令的拆解defer语句的参数闭包是什么?defer配合recover后记参考资料 什么是defer? defer是Go语言提供的一种用…...

【C语言】循环中断break
在循环使用过程中,可能遇到某些情况需要终止循环。比如按座位查找一位学生,循环查找,找到时可以直接停止。后续的循环将不再执行。 break;只跳出一层循环 例子中的素数判断,查找到根号n停止:一个合数等于两个数的乘积…...

centos ping能通但是wget超时-解决
问题截图: 域名解析地址为IPV6地址,建议您调整IPV4优先级之后,再尝试访问,请参考Linux系统IPv4/IPv6双栈接入优先使用IPv4设置:移动云帮助中心 实操截图:...

SDIO - DWC MSHC 电压切换和频率切换
背景 我们的sdio访问sd card过去一直跑在低频上,HS50M。前段时间给eMMc添加了HS200模式,eMMc的总线模式定义是这样的: 可以看到1.8V的IO 电压可以支持所有模式,我们过去的芯片,由硬件部门放到evb上,其IO …...