1、本篇博客的背景和目的
目前我本人正在学习MyBatis框架,在原先了解并且懵懵懂懂使用的基础上,开始系统正式的学习。目前已经阐述了MVC架构模式和三层架构,明晰了在Web项目中的普遍编码层次,认识了框架,回顾了JDBC连接数据库,稍详细介绍了MyBatis框架,初步建立了一个使用MyBatis和MySQL的Maven项目,简单解释了STDOUT_LOGGING日志和INSERT语句手动提交事务。本篇博客记录一下MyBatis中#占位符的使用。
2、我的上一篇博文
我上一篇博文记录的是STDOUT_LOGGING日志和事务,感兴趣的读者可以前往阅读,链接如下:MyBatis学习:MyBatis中简单使用占位符#,STDOUT_LOGGING日志和INSERT语句手动提交事务_你是我的日月星河的博客-CSDN博客目前我本人正在学习MyBatis框架,在原先了解并且懵懵懂懂使用的基础上,开始系统正式的学习。目前已经阐述了MVC架构模式和三层架构,明晰了在Web项目中的普遍编码层次,认识了框架,回顾了JDBC连接数据库,稍详细介绍了MyBatis框架,初步建立了一个使用MyBatis和MySQL的Maven项目。本篇博文记录一下简单使用占位符#,STDOUT_LOGGING日志和INSERT语句手动提交事务。...https://blog.csdn.net/weixin_46281472/article/details/125934432
3、为什么要使用占位符
比方说我们有这样的一个场景:新用户注册。我们需要将用户注册的用户名和密码写到数据库中。那么就需要执行Insert语句。但是用户名和密码是用户提供的,需要从前端获得用户提供的用户名和密码,然后我们再写入到数据库中。
那么在我们的Insert语句中,用户名和密码就作为了参数。这两个参数就来自新用户,程序在先前肯定是不知道的,也就是说SQL语句不能写死,因为要插入的数据不确定是什么。
所以这时候就使用到了占位符:我们将获得的用户名和密码替换掉我们在XML配置文件中的SQL里面的占位符的位置。
4、java实体类Student代码(可以类比用户类)
代码如下所示:
package com.dcy.domain;
public class Student {
//这里我们的属性名和数据库表中的列名保持一致,如果不一致的话我们需要在mapper.XML文件中配置或者是使用注解配置
private Integer id;
private String name;
private String email;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "一个学生实体的信息{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
上面实体类的代码比较简单,我不多解释了。
5、mapper.XML配置文件代码
代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dcy.dao.StudentDao">
<!--
select标签表示的是查询操作,里面是查询语句。
id属性的值是SQL语句的唯一标识,是一个自定义的字符串。
按照编码规范,这里统一推荐使用dao接口中对应的方法名称。
resultType属性是表示执行SQL语句后,结果对应那个类型的JAVA对象。resultType的值是某个实体类的全限定名称。
比如:com.dcy.domain.Student
-->
<select id="selectStudentById" resultType="com.dcy.domain.Student">
<!--select id,name,email,age from student where id=1001-->
select id,name,email,age from student where id=#{studentId}
</select>
<!-- 下面的语句使用了占位符,因为我们传过来的是一个java对象,可以直接使用它的属性名,放在花括号里面,
前面配上#,这就相当于是传参了-->
<insert id="insertStudent">
insert into student values (#{id},#{name},#{email},#{age})
</insert>
</mapper>
<!--
最上面的四行代码是固定的。
1、http://mybatis.org/dtd/mybatis-3-mapper.dtd 这个是约束文件。
约束文件也就是规定了这个XML文件中可以使用那些标签,标签之间的嵌套顺序是什么,标签中可以有哪些属性。
这是一个约束文件的链接,我们可以在浏览器中访问,最后下载下来的。
2、<mapper>标签是根标签,其中的namespace属性是必须有的,不能为空,并且在整个项目中是唯一的。
推荐使用这个文件所对应Dao接口的全限定路径,也就是com.**.**.**这样的形式
它的作用是参与识别SQL语句的。
3、在mapper标签里面就可以写select,insert,update,delete标签,里面就写对应的SQL语句就可以了。
当然,里面还可以写resultMap标签,就是对应属性名和数据表列名的。这个后面详细说。
-->
上面的代码主要是最后的一个insert标签,里面使用的属性都是Student实体java类中的属性。
注意看里面的注释,不多解释了。
6、Main方法测试代码
代码如下:
package com.dcy;
import com.dcy.domain.Student;
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 Starter {
public static void main(String[] args) throws IOException {
/*
myBatis的核心类是SqlSessionFactory
就是需要我们加载一下主配置文件,有点像我们使用SpringMVC加载spring.xml配置文件或者BeanFactory对象一样。
这些在官网是有的。
*/
//定义主配置文件的目录,从类路径开始:com/**/**这样的,如果是在resources目录下,那就是 **/**/
String config="mybatis.xml";
//下面读取主配置文件,使用MyBatis框架中的Resources类
InputStream inputStream = Resources.getResourceAsStream(config);
//下面创建SqlSessionFactory对象,使用的是SqlSessionFactoryBuilder类,需要用到上面的inputStream参数
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//MyBatis最终执行SQL语句,使用的是SqlSession类中的方法。SqlSession实例的获得,依靠的是SqlSessionFactory类。
//下面获取SqlSession对象,SqlSession是接口
SqlSession session = sqlSessionFactory.openSession();
//指定要执行的SQL语句的id
//SQL语句的id=namespace+"."+SQL语句所在标签的id属性的值
String SQLID="com.dcy.dao.StudentDao"+"."+"insertStudent";
//通过SqlSession对象的方法执行SQL语句
// Student student = session.selectOne(SQLID); //这个是没有使用占位符,没有传参的
Student student=new Student();
student.setId(1006);
student.setAge(24);
student.setEmail("luoluo.163.com");
student.setName("洛洛");
Integer row=session.insert(SQLID,student);//将一个java对象传过去
session.commit();//提交一下事务
System.out.println("影响的行数是"+row);
//最后我们关闭SqlSession对象
session.close();
}
}
调用insert方法,将SQL语句的“地址”和需要插入的数据:一个java对象 传过去即可。
最后可以顺利插入数据。
7、总结一下
如果传入给MyBatis的是一个java对象,mapper.XML文件 使用 #{属性名} 获取此属性的值,属性值会放到 #{ }占位符的位置。 MyBatis在背后执行的是这个属性对应的get()方法。
所以,多说一下吧:实体类的set()和get()方法是必须有的,我有一次做项目就是一个实体类忘记了写get()方法,导致使用MyBatis框架出现问题,调试了很久,都是经验啊!!!很多框架内部都是要使用到set()和get()方法的。