MyBatis安装配置以及实现增删改查
安装
这里我创建的是maven项目,需要在pom.xml导入依赖,导入之前要注意maven的仓库和配置是不是你自己下的那个,由于idea自带一个maven,因此需要修改:
pom文件导入的依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--开源日志组件-->
<!--log4j日志门面-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
除了上面,还需要创建配置:logback.xml文件放在main下面的resources目录下面
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 配置自定义日志输出格式 -->
<pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="Console"/>
</root>
</configuration>
并且在此目录下面,创建mybatis-config.xml的配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--加载数据库key-value配置文件-->
<properties resource="jdbc.properties"></properties>
<!-- Mybatis全局配置 -->
<settings>
<!-- 设置当前Mybatis的日志输出,可在控制台显示sql语句 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="true"></setting>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///study_db?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
配置映射文件,创建一个要用的:表名Mapper.xml,这里使用tb_student表,创建的就是StudentMapper.xml,这里要注意数据库表中的列名和Java类中的字段名,数据库是下划线,java是驼峰,因此当名称有区别的时候需要将查询的结果映射到map集合中,在sql映射文件中添加以下内容:
<resultMap id="empResultMap" type="Employee">
<!--数据库的列与实体类的变量相对应-->
<!--id为主键的映射,result为普通列名的映射,column为表的列名,property为类中映射的字段名-->
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
</resultMap>
并且在查询结果返回类型的时候选择返回map:
<sql id="all">
uid,uname, upwd, uemail, phone, create_time, update_time, deleted, rid
</sql>
<select id="selectAll" resultType="com.liku.entity.Sysuser">
select <include refid="all"/> from sysuser;
</select>
映射文件配置好之后需要修改mybatis-config.xml的mapper resource
路径:因为都在resources目录下面,所以我这里直接使用文件名:
下面操作跟jdbc中操作差不多:创建实体类-->创建对应类型的变量【注意变量名的映射】
获取SqlSessionFactory
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
由于等会需要输出对象,我们导入lombok,用注解tostring
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
创建查询demo【注意路径!!!】 :
public class MyBatisDemo {
public static void main(String[] args) {
//加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//它在命名空间 “namespace” 中定义了一个名为 “selectList” 的映射语句,这样你就可以用全限定名 “test.selectStudent” 来调用映射语句了
List<Student> student = sqlSession.selectList("test.selectStudent");
student.forEach(System.out::println);
sqlSession.close();
}
}
Mapper代理开发
第一步:mapper接口的名称要和sql映射文件的名字相同,并且需要和sql映射文件【StudentMapper.xml】放置在同一目录下,但是一般配置文件和Java文件不放一块,因此可以按照下面的方式:
在resources文件里面创建跟mapper接口层次相同的目录【创建包的时候是com.exercise.mapper,那么创建目录的时候需要将.换成/】,将sql映射文件剪切进去,如图:
注意将之前的mybatis-config.xml加载sql映射文件的mapper路径改为现在的路径,下载MavenHelper插件,我们编译一下,打开编译完的路径,像这样子就可以了:
第二步:设置SQL映射文件的namespace属性为Mapper接口全限定名
<mapper namespace="com.exercise.mapper.StudentMapper">
第三步:在mapper接口中定义方法,方法名就是sql映射文件中的sql语句的id,并保持参数类型和返回值类型一致:
通过下面步骤:
-
通过sqlSession的getMapper方法获取接口的代理对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
-
调用对应的方法完成sql的执行
mapper.selectAllStudent().forEach(System.out::println);
上面完整的代码:
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlsession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取接口的代理对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
mapper.selectAllStudent().forEach(System.out::println);
}
tips:
在mybatis-config里面为某个包配置别名
<configuration>
<typeAliases>
<package name="com.exercise.pojo"></package>
</typeAliases>
之后sql映射文件中的返回结果可以直接通过类名的方式来获取:
<select id="selectAllStudent" resultType="Student">
使用修改配置文件实现数据的增删改查
查询
如果要查询单个学生,在接口中定义一个跟当前select的id属性名相同的方法,形参int id,将select中的sql语句换成:
select * from tb_student where id=#{id}
这里#{id}表示sql中的?占位符,还有一种是${id}直接将这个变量值放入到sql语句中,之前学jdbc的时候说过?占位符可以防止sql注入,因此以后参数我这边都是用的#{}
假如需要使用小于号<,由于是xml文件,所以需要转义<或者CD回车,把小于号写进去
</select>
<select id="selectStudentById" resultType="com.exercise.pojo.Student">
select * from tb_student where stu_id
<![CDATA[
<
]]>
#{id}
</select>
如果要查询多条件的,需要在接口方法中的形参中表明该参数为什么映射的参数:
public interface EmpMapper {
List<Employee> selectAll();
List<Employee> selectByMgrAndJob(@Param("mgr")int mgr,@Param("job")String job);
}
如果查询结果有另外一个表的字段的,可以在resultMap中添加映射:column为关联列,select方法为另一个mapper的全限定名并且定位到该方法
<association property="sysrole" javaType="com.liku.entity.Sysrole" column="rid" select="com.liku.mapper.SysroleMapper.selectById"></association>
然后在sql映射文件中添加查询语句:
<select id="selectByMgrAndJob" resultMap="empResultMap">
select * from emp where mgr=#{mgr} and job=#{job};
</select>
调用方法:
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper2 = sqlSession.getMapper(EmpMapper.class);
mapper2.selectByMgrAndJob(1006,"销售员").forEach(System.out::println);
也可以通过传入对象的方法查询:
EmpMapper mapper2 = sqlSession.getMapper(EmpMapper.class);
Employee employee=new Employee();
employee.setMgr(1006);
employee.setJob("销售员");
mapper2.selectByMgrAndJob(employee).forEach(System.out::println);
可以通过传入map的方式:注意传入的map集合中的元素名称需要跟sql映射文件中的查询名称相同
Map<Object, Object> emps = new HashMap<>(16);
emps.put("mgr",1006);
emps.put("job","销售员");
mapper2.selectByMgrAndJob(emps).forEach(System.out::println);
但是上面的条件查询是有缺点的,如果输入的条件不满足sql语句中的参数的时候会查询不到结果,因此当有条件多选框的时候我们选择动态查询
动态查询
修改sql映射配置文件中的查询语句,比如:
<select id="selectByMgrAndJob" resultMap="empResultMap">
select * from emp where mgr=#{mgr}
<if test="job!=null">
and job=#{job};
</if>
</select>
test表示用于接收的字段,也就是你类里面的字段,但是当第一个条件为空,但是后面的条件不为空,则会出现这种结果:
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
模糊查询拼接:
uname like '%'#{uname}'%',
uname like concat('%',concat(#{uname},'%'))
这样肯定会报错,对这种情况,使用where元素来控制
<select id="selectByCond" resultMap="empResultMap">
select * from emp
<where>
<if test="mgr != null">
mgr = #{mgr}
</if>
<if test="job != null">
AND job like #{job}
</if>
<if test="empName != null">
AND emp_name like #{empName}
</if>
<if test="sal != null">
AND sal = #{sal}
</if>
</where>
</select>
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
假如是在多选一的情况下,使用choose元素来控制sql语句:
</select>
<select id="selectByCond" resultMap="empResultMap">
select * from emp where mgr=#{mgr}
<choose>
<when test="job!=null">
and job=#{job}
</when>
<when test="sal!=null">
and sal=#{sal}
</when>
</choose>
</select>
添加
mapper接口中定义方法:
int add(Employee employee);
sql映射文件中添加对应的内容,并且返回受影响的行数:
<insert id="add" useGeneratedKeys="true" keyProperty="empId">
insert into emp values (#{empId},#{empName},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno});
</insert>
useGeneratedKeys="true" keyProperty="empId"用于添加成功之后获取添加成功之后的id值,然后在外面调用该方法,得到:
再刷新一下表,但是没有数据添加进去,为什么呢?查看日志,可以看到:
这是由于mybatis在创建sqlsession对象的时候默认创建了一个事务,但是没有自动提交,也就是事务回滚,此时需要处理这种情况,在添加完成之后添加下面代码:
sqlSession.commit();
或者在创建sqlSession对象的时候传入true:
SqlSession sqlSession = sqlSessionFactory.openSession(true);
设为自动提交事务,然后刷新数据库,数据添加成功,完整代码:
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
EmpMapper mapper2 = sqlSession.getMapper(EmpMapper.class);
Employee employee = new Employee(1018,"王五","保洁员",1001,"2010-03-23","5000",null,"50");
mapper2.add(employee);
Integer empId = employee.getEmpId();
System.out.println(empId);
修改
修改全部信息
有了JDBC的基础,感觉这个还挺简单,mapper接口添加方法:
int update(Employee employee);
,sql映射文件添加映射内容:
<update id="update">
update emp set
emp_name=#{empName},
job=#{job},mgr=#{mgr},
hiredate=#{hiredate},
sal=#{sal},
comm=#{comm},
deptno=#{deptno} where emp_id=#{empId};
</update>
传入employee信息,修改,成功!
修改部分信息
这个感觉会更有用,因为一般修改我都是修改某些信息而不会全部修改,在这修改sql映射文件里面的内容:
<update id="update">
update emp
<set>
<if test="empName != null">emp_name=#{empName},</if>
<if test="job != null">job=#{job},</if>
<if test="hiredate != null">hiredate=#{hiredate},</if>
<if test="sal != null">sal=#{sal}</if>
<if test="comm != null">comm=#{comm}</if>
<if test="deptno != null">deptno=#{deptno}</if>
</set>
where emp_id=#{empId}
</update>
注意test的值是跟类中的字段一样..
删除
单个删除不记录了,记录一下批量删除,根据一堆id值来进行批量删除:
mapper中创建方法:
int deleteByIds(@Param("empIds")Integer[] ids);
EmpMapper.xml文件【映射文件】中添加内容:
<delete id="deleteByIds">
delete from emp where emp_id in
<foreach item="id" index="index" collection="empIds"
open="(" separator="," close=")">
#{id}
</foreach>
</delete>
collection:遍历的数组,index:遍历的索引值,item:数组中遍历的每个变量
使用注解的方式实现增删改查
在mapper接口中的方法上加上响应的注解:
@Select("select * from tb_student where stu_id=#{id}")
Student selectById(int id);
@Insert("insert into tb_student values(#{stuId},#{stuName},#{stuSex},#{stuBirth},#{stuDepartment},#{stuAddress})")
int add(Student student);
@Delete("delete from tb_student where stu_id=#{id}")
int deleteById(int id);
@Update("update tb_student set stu_name=#{arg0} where stu_id=#{arg1}")
int updateById(String name,int id);
注解用于简单的增删改查会方便点,但是这要注意数据库的名称和Java类中的字段名,复杂操作的还是在配置文件中添加sql语句会不容易出错
参考内容:入门_MyBatis中文网
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?