Mybatis总结
Mybatis是一个通用的操作数据库的持久层框架,本质上就是对jdbc进行了封装,实现了一个更强的jdbc版本。
JDBC操作数据库
在学习Mybatis之前,回顾一下jdbc是如何操作数据库的。
下面是一张在数据库中的表,表上面有4个字段,分别是id,name,email和age,接下来使用jdbc来查询这张表。
jdbc操作数据库的步骤
1、注册驱动
2、获取连接
3、获取可执行对象
4、执行并获取结果
5、关闭资源
代码实现
package com.xxxx.mybatis.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Crud {
public static void main(String[] args) throws Exception {
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/student","root","123456");
//3、获取可执行对象
Statement st = con.createStatement();
//4、执行并得到结果
String sql = "select * from student";
ResultSet resultSet = st.executeQuery(sql);
while(resultSet.next()) {
//获取当前行内容
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String email = resultSet.getString(3);
int age = resultSet.getInt(4);
System.out.println(id+"\t"+name+"\t"+email+"\t"+age);
}
//5.关闭资源
resultSet.close();
st.close();
con.close();
}
}
查询结果如下
上面使用jdbc的方式来操作数据库,除了上诉的代码较多,开发效率低的原因外,还具有以下缺点:
1.需要关注Connection、Statement、ResultSet对象的创建和销毁
2.对 ResultSet查询的结果,需要自己封装为List
3.重复的代码比较多些5.业务代码和数据库的操作混在一起
Mybatis
Mybatis的存在就是为了解决jdbc的上诉缺点的,使用更少的步骤,实现更多的功能。
为了导入依赖方便,编写的代码都是在maven项目上运行的。
Mybatis环境搭建
导入相应的依赖
Mybatis在使用中需要导入mybatis依赖和mysql-connector依赖
mybatis依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
mysql-connector依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.8</version>
</dependency>
Mybatis主配置文件
主配置文件模板
主配置文件除了需要放在合适的位置,文件里面的内容也是有明确的规定,Mybatis提供了相应的文件模板,模板如下:
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
主配置文件详解
主配置文件的作用是配置数据库信息,加载映射文件。
<?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>
<!-- 配置环境,数据库的连接信息
default:必须和某个 environment的id值一样。
告诉 mybatis使用哪个数据库的连接信息。也就是访问哪个数据库
-->
<environments default="development">
<!--
environment:一个数据库信息的配置,环境
id:一个唯一值,自定义,表示环境的名称。
-->
<environment id="development">
<!--
transactionManager: mybatis的事务类型
type:JDBC(表示使用jdbc中的Connection对象的 commit,rollback做事务处理)
-->
<transactionManager type="JDBC"/>
<!-- 数据源,用来连接数据库的
type:表示数据源的类型,POOLED表示使用连接池
-->
<dataSource type="POOLED">
<!-- driver,username,password,url是固定的,不能自定义 -->
<!-- 数据库驱动类名 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 连接数据库的url字符串 -->
<property name="url" value="jdbc:mysql://localhost:3306/student"/>
<!-- 访问数据库的用户名称 -->
<property name="username" value="root"/>
<!-- 用户名密码 -->
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 一个mapper标签指定一个文件的位置,从类路径开始的路径信息。 -->
<mapper resource="com/xxxx/mybatis/dao/StudentDao.xml"/>
</mappers>
</configuration>
<!--
mybatis的主配置文件:主要定义了数据库的配置信息,sql映射文件的位置
1.约束文件
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
约束文件名称:mybatis-3-config.dtd
2.configuration 根标签
-->
Mybatis映射文件
Mybatis映射文件模板
mybatis在使用过程中,通常将映射文件和接口放在一起,并且映射文件名称和接口名称一致。mybatis同样提供了映射文件的模板,模板如下:
<?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="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
Mybatis映射文件详解
映射文件和接口放在一起,接口里面写的是操作数据库的方法,而映射文件里面是如何操作数据库的sql语句。
<?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.xxxx.mybatis.dao.StudentDao">
<select id="selectStudents" resultType="com.xxxx.mybatis.Student">
select id,name,email,age from student order by id
</select>
<!-- select:表示查询操作。
id:你要执行的sq1语法的唯一标识, mybatis会使用这个id的值来找到要执行的sq1语句可以自定义,但是要求你使用接口中的方法名称。
resultType:表示结果类型的,是sql语句执行后得到 Resultset,逼历这个Resultset得到java对象的类型。
值写的是类的全限定名称
-->
<!-- insert操作-->
<insert id="insertStudent" >
insert into student values(#{id},#{name},#{email},#{age})
</insert>
</mapper>
<!--
1.sql映射文件:写sql语句的, mybatis会执行这些sq1
2.指定约束文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3- mapper,dtd是约束文件的名称,扩展名是dtd的。
2.约束文件作用:限制,检查在当前文件中出现的标签,属性必须符合 mybatis的要求
3. mapper是当前文件的根标签,必须的。
namespace:叫做命名空间,唯一值的,可以是自定义的字符串。
要求你使用dao接口的全限定名称。
4.在当前文件中,可以使用特定的标签,表示数据库的特定操作。
< select>:表示执行查询, select语句
<update>:表示更新数据库的操作,就是在<update>标签中写的是update sql语句
<insert>:表示插入,放的是 insert语句
<delete>:表示删除,执行的 delete语句
-->
数据源属性文件
主配置文件中配置了数据源信息,可以将数据源信息写入到一个属性文件中,常见的就是jdbc.properties文件。这样以后需要修改数据源信息,只需要在属性文件中修改即可。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/student
jdbc.username=root
jdbc.password=123456
配置好属性文件后,在主配置文件中修改一下数据源的信息。
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
Mybatis常用类
Mybatis在使用过程中,主要使用四种对象,分别是:SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession和SqlMapper。
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder:加载主配置文件,创建SqlSessionFactory对象
//定义mybatis主配置文件的名称,从类路径开始
String config = "mybatis.xml";
//读取这个config表示的文件
InputStream in= Resources.getResourceAsStream(config);
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//创建SqlSessionFacory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
SqlSessionFactory
SqlSessionFactory:创建SqlSession(会话)对象。
//[重要]获取SqlSession对象,从SqlSessionFactory中获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
SqlSession
SqlSession:1.根据sqlId获取sql语句,执行sql语句,操作数据库2.调用getMapper对象获取SqlMapper对象
//[重要]指定要执行的sql语句标识。 sql映射文件中的namespace+"."+标签的id值
String sqlId = "com.xxxx.mybatis.dao.StudentDao"+"."+"selectStudents";
//执行sql语句,通过sqlId找到语句
List<Student> studentsList = sqlSession.selectList(sqlId);
注意:使用完要关闭SqlSession对象。
SqlMapper
SqlMapper:使用动态代理的方式操作数据库,代码量少,操作方便,推荐使用这种方式。
// 使用mybatis的动态代理机制,使用sqlSession.getMapper(dao接口)
// getMapper能获取dao接口的实现类对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = dao.selectStudents();
Mybatis工具类
在创建SqlSession对象的过程中,有很多代码是固定不动的,所以将获取SqlSessionFactory对象的方法封装为一个工具类
package com.xxxx.mybatis.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 MybatisUtils {
private static SqlSessionFactory sqlSessionFactory = null;
//使用一个静态块,因为静态块只执行一次
static {
//用来获取SqlSessionFactory
String config = "mybatis.xml";
try {
InputStream in = Resources.getResourceAsStream(config);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
if (sqlSessionFactory != null){
sqlSession = sqlSessionFactory.openSession();//非自动提交事务
}
return sqlSession;
}
}
Mybatis操作数据库
使用SqlSession方式
方式一:直接使用SqlSession
使用SqlSession的方式操作数据库,SqlSession对象所调用的方法不是接口中的,而是java内置写好的。
package com.xxxx.mybatis.Domain;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setEmail(String email) {
this.email = email;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
<mapper namespace="com.xxxx.mybatis.dao.StudentDao">
<select id="selectStudents" resultType="com.xxxx.mybatis.Student">
select id,name,email,age from student order by id
</select>
public static void main(String[] args) throws IOException {
//由工具类获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.xxxx.mybatis.dao.StudentDao"+"."+"selectStudents";
List<Student> students = sqlSession.selectList(sqlId);
for (Student student:students){
System.out.println(student.toString());
}
sqlSession.close();
}
方式二:在接口实现类中封装SqlSession
在接口实现中完成sqlId的拼接,获取Sqlsession对象,根据sqlId找到映射文件中的sql语句,进行数据库操作
package com.xxxx.mybatis.Domain;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setEmail(String email) {
this.email = email;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
package com.xxxx.mybatis.Dao;
import com.xxxx.mybatis.Domain.Student;
import java.util.List;
public interface StudentDao {
public List<Student> selectStudents();
public int insertStudent(Student student);
}
package com.xxxx.mybatis.Dao.Impl;
import com.xxxx.mybatis.Dao.StudentDao;
import com.xxxx.mybatis.Domain.Student;
import com.xxxx.mybatis.Utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudents() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.xxxx.mybatis.Dao.StudentDao.selectStudents";
List<Student> studentLists = sqlSession.selectList(sqlId);
sqlSession.close();
return studentLists;
}
@Override
public int insertStudent(Student student) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.xxxx.mybatis.Dao.StudentDao.insertStudent";
int updates = sqlSession.insert(sqlId, student);
sqlSession.commit();
sqlSession.close();
return updates;
}
}
<select id="selectStudents" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student order by id
</select>
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
package com.xxxx.mybatis;
import com.xxxx.mybatis.Dao.Impl.StudentDaoImpl;
import com.xxxx.mybatis.Domain.Student;
import org.junit.Test;
import java.util.List;
public class TestMybatis {
@Test
public void testStudents1() {
StudentDaoImpl studentDao = new StudentDaoImpl();
List<Student> students = studentDao.selectStudents();
for (Student student : students) {
System.out.println(student.toString());
}
}
@Test
public void testStudents2() {
StudentDaoImpl studentDao1 = new StudentDaoImpl();
Student student = new Student();
student.setId(1006);
student.setName("杜甫");
student.setEmail("dufu@qq.com");
student.setAge(20);
int update = studentDao1.insertStudent(student);
System.out.println(update);
}
}
动态代理方式
在实际工作中,主要用的还是动态代理的方式来操作数据库,使用动态代理,需要满足一些条件:
1.映射文件中的namespace属性值与接口全路径一致
<mapper namespace="com.xxxx.mybatis.Dao.StudentDao">
2.映射文件中的id属性值与接口中的方法名一致
<select id="selectStudents" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student order by id
</select>
3.映射文件与接口放在同一目录下,并且映射文件与接口名称一致
package com.xxxx.mybatis.Domain;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setEmail(String email) {
this.email = email;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
package com.xxxx.mybatis.Dao;
import com.xxxx.mybatis.Domain.Student;
import java.util.List;
public interface StudentDao {
public List<Student> selectStudents();
public int insertStudent(Student student);
}
<mapper namespace="com.xxxx.mybatis.Dao.StudentDao">
<select id="selectStudents" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student order by id
</select>
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
package com.xxxx.mybatis;
import com.xxxx.mybatis.Dao.Impl.StudentDaoImpl;
import com.xxxx.mybatis.Domain.Student;
import org.junit.Test;
import java.util.List;
public class TestMybatis {
@Test
public void testStudents1() {
StudentDaoImpl studentDao = new StudentDaoImpl();
List<Student> students = studentDao.selectStudents();
for (Student student : students) {
System.out.println(student.toString());
}
}
@Test
public void testStudents2() {
StudentDaoImpl studentDao1 = new StudentDaoImpl();
Student student = new Student();
student.setId(1006);
student.setName("杜甫");
student.setEmail("dufu@qq.com");
student.setAge(20);
int update = studentDao1.insertStudent(student);
System.out.println(update);
}
}
Mybatis中的参数传递
mybatis的参数传递指的是java代码的实参名字与数据库字段之间的映射。
在映射文件中,parmeterType属性值可以指定参数传递的类型,属性值可以使用类的全路径,也可以使用mybatis提供的别名,或者是自己自定义的别名。
<select id="selectStudentById" parameterType="int" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id = #{id};
</select>
Mybatis的参数传递指的是将java代码中的实参传递给映射文件中的sql语句,jdbc常用的方式是在sql语句上使用?
做占位符,将实参替代?
。
一个简单类型参数传递
mybatis把java的基本数据类型和 String都叫简单类型,简单类型参数传递在映射文件中使用#{任意字符}
做为占位符。下面就是用1002
替代#{id}
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = dao.selectStudentById(1002);
<select id="selectStudentById" parameterType="int" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id = #{id};
</select>
多个参数传递
使用@param注解传递
在接口方法的形参前面加上@param注解,来给形参起别名
public Student selectMultyParams(@Param("myId") Integer id, @Param("myName") String name);
<select id="selectMultyParams" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id = #{myId} or name =#{myName};
</select>
@Test
public void testStudents2() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = dao.selectMultyParams(1002, "张三");
System.out.println(student);
}
使用对象传递
创建一个类,类里面包含了相应的属性,将java对象作为接口中方法的参数
public List<Student> selectMultyObject(QueryParam queryParam);
package com.xxxx.mybatis.vo;
public class QueryParam {
private String paraName;
private Integer paraAge;
public String getParaName() {
return paraName;
}
public Integer getParaAge() {
return paraAge;
}
public void setParaName(String paraName) {
this.paraName = paraName;
}
public void setParaAge(Integer paraAge) {
this.paraAge = paraAge;
}
}
<!--
多个参数,使用java对象的属性值,作为参数实际值
使用对象语法:#{属性名,javaType = 类型名称,jdbcType = 数据类型}很少用
javaType:指的是java中属性数据类型
jdbccType:在数据库中的数据类型
例如:#{paraName,javaType = java.lang.String,jdbcType = VARCHAR}
使用简化的方式:#{属性名} javaType,jdbcType的值mybatis反射能够获取
-->
<select id="selectMultyObject" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id = #{paraName} or name =#{paraAge};
</select>
public void testStudents3() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
QueryParam queryParam = new QueryParam();
queryParam.setParaName("李白");
queryParam.setParaAge(11);
List<Student> students = dao.selectMultyObject(queryParam);
}
注意:接口中方法的参数只要是对象即可,不一定非用QueryParam对象,但是所传入的对象必须包含相应的属性。
public List<Student> selectObject(Object obj);
<select id="selectObject" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id = #{name} or name =#{age};
</select>
@Test
public void testStudents3() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("李白");
student.setAge(11);
List<Student> students = dao.selectObject(student);
System.out.println(students);
}
按位置传递(不推荐使用)
使用map传递(不推荐使用)
sql语句中${}和#{}的区别
${}在使用过程中会将java代码中的实参和sql语句进行拼接,存在sql注入的问题,如下代码:
<select id="selectMultyParams" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id = ${myId} or name =${myName};
</select>
@Test
public void testStudents2() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = dao.selectMultyParams(1002, "张三;drop database student");//会把数据库删掉
System.out.println(student);
}
#{}的作用是将#{}使用?替换,起
到一个占位的作用,不存在sql注入的风险。
C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210717103814332.png
Mybatis中的返回结果
返回结果指的是sql语句执行完,转为的ava对象的类型
在映射文件中,ResultType属性值可以指定参数传递的类型,属性值可以使用类的全路径,也可以使用mybatis提供的别名,或者是自己自定义的别名。
<select id="selectStudentById" parameterType="int" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id = #{id};
</select>
使用别名
在主配置文件中可以设置别名,不仅在参数传递过程中可以使用别名,在返回结果的时候也可以使用别名。使用别名有两种方式,一种是为类设置别名,另一种是为包设置别名。在实际开发不中,建议使用全限定名称。
为类设置别名
<typeAliases>
//type:要起别名的类 alias:别名
<typeAlias type="com.xxxx.mybatis.Domain.Student" alias="stu"></typeAlias>
</typeAliases>
<select id="selectStudentById" parameterType="int" resultType="stu">
select id,name,email,age from student where id = ${id};
</select>
为包设置别名
<typeAliases>
//package方式:别名不是自定义的,别名就是类名
<package name="com.xxxx.mybatis.Domain"/>
</typeAliases>
<select id="selectStudentById" parameterType="int" resultType="Student">
select id,name,email,age from student where id = ${id};
</select>
返回的类型
返回普通类型
public int countStudent();
<select id="countStudent" resultType="int">
select count(*) from student
</select>
@Test
public void testStudents5() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
int count = dao.countStudent();
System.out.println(count);
}
返回map类型
public Map<Object,Object> selectMap(Integer id);
<!--
返回map
1.列名是map的key,列值是map的value
2.只能返回一行记录。多余一行是错误的
-->
<select id="selectMap" resultType="java.util.HashMap">
select id,name from student where id = #{id};
</select>
@Test
public void testStudents6() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Map<Object, Object> objectObjectMap = dao.selectMap(1002);
System.out.println("Map = "+objectObjectMap);
}
数据库列名和属性名不相同
ResultMap解决方式
在sql映射文件中设置数据库列值和java属性值之间的映射关系,column
代表数据库列名,property
代表java属性名。
<resultMap id="myStudentMap" type="com.xxxx.mybatis.Domain.MyStudent">
<id column="id" property="stuId"></id>
<result column="name" property="stuName"></result>
<result column="email" property="stuEmail"></result>
<result column="age" property="stuAge"></result>
</resultMap>
<select id="selectMyStudent" resultMap="myStudentMap" >
select id,name,email,age from student
</select>
sql解决方式
在sql语句对列名进行起别名,将列名设置为属性名。
<select id="selectMyStudent2" resultType="com.xxxx.mybatis.Domain.MyStudent" >
select id as stuId, name as stuName, email as stuEmail,age as stuAge from student
</select>
模糊查询
java代码指定的like的内容
<!-- 第一种like java代码指定的like的内容 -->
<select id="selectLikeOne" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where name like #{name}
</select>
@Test
public void testStudents10() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
String name = "%李%";
List<Student> students = dao.selectLikeOne(name);
System.out.println(students);
sqlSession.close();
}
在映射文件中拼接like后的内容
<!-- 第二种方式 在映射文件中拼接like后的内容 -->
<select id="selectLikeTwo" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where name like "%" #{name} "%"
</select>
@Test
public void testStudents11() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
String name = "李";
List<Student> students = dao.selectLikeTwo(name);
System.out.println(students);
sqlSession.close();
}
动态sql语句
动态sql指的是在sql语句中加入一些标签,对数据库进行操作时,对数据进行筛选。
if标签
使用特点:判断条件为true,就会把if之间的sql加入到主sql之后。
注意:当存在多个if标签,、不执行上面的if标签,直接执行下面的if标签可能出现sql语法错误
<select id="selectStudentIf" parameterType="int" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student
where 1 = 1
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age > 0">
or age > #{age}
</if>
</select>
where标签
使用特点:where里面嵌套多个if标签,使用过程中会去掉无用的and、or字段。
<select id="selectStudentWhere" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student
<where>
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age > 0">
or age > #{age}
</if>
</where>
</select>
@Test
public void testStudents2() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
// student.setName("李四");
// student.setAge(18);
List<Student> students = dao.selectStudentWhere(student);
System.out.println(students);
sqlSession.close();
}
foreach标签
使用特点:主要用于数组、list集合中
<select id="selectStudentForOne" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id in
<foreach collection="list" item="myId" open="(" close=")" separator=",">
#{myId}
</foreach>
</select>
<select id="selectStudentForTwo" resultType="com.xxxx.mybatis.Domain.Student">
select id,name,email,age from student where id in
<foreach collection="list" item="student" open="(" close=")" separator=",">
#{student.id}
</foreach>
</select>
@Test
public void testStudents4() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
ArrayList<Student> studentList = new ArrayList<>();
Student s1 = new Student();
s1.setId(1002);
studentList.add(s1);
Student s2 = new Student();
s2.setId(1001);
List<Student> students = dao.selectStudentForTwo(studentList);
System.out.println(students);
sqlSession.close();
}
代码片段
代码片段指的是将一些sql语句保存起来复用,复用时使用include标签。
<!-- 定义sql片段 -->
<sql id="studentSql">
select id,name,email,age from student
</sql>
<select id="selectStudentWhere" resultType="com.xxxx.mybatis.Domain.Student">
<include refid="studentSql"></include>
<where>
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age > 0">
or age > #{age}
</if>
</where>
</select>
PageHelper插件
PageHelper插件的作用是将数据进行分页显示,可以指定一页显示的数据数目。
导入插件依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
配置插件信息
<!-- 配置pagehelper插件 注意:插件加在环境前面 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
使用插件
// 使用PageHeplper插件
public List<Student > selectAll();
<select id="selectAll" resultType="com.xxxx.mybatis.Domain.Student">
select * from student order by id
</select>
@Test
public void testStudents5() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
// 使用PageHelper插件
// pageNum:第几页,从1开始
// pageSize:一页中有多少行数据
PageHelper.startPage(3,3);
List<Student> students = dao.selectAll();
for (Student student:students){
System.out.println(student);
}
sqlSession.close();
}
= #{name}
or age > #{age}
### PageHelper插件
PageHelper插件的作用是将数据进行分页显示,可以指定一页显示的数据数目。
#### 导入插件依赖
```xml
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
配置插件信息
<!-- 配置pagehelper插件 注意:插件加在环境前面 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
使用插件
// 使用PageHeplper插件
public List<Student > selectAll();
<select id="selectAll" resultType="com.xxxx.mybatis.Domain.Student">
select * from student order by id
</select>
@Test
public void testStudents5() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
// 使用PageHelper插件
// pageNum:第几页,从1开始
// pageSize:一页中有多少行数据
PageHelper.startPage(3,3);
List<Student> students = dao.selectAll();
for (Student student:students){
System.out.println(student);
}
sqlSession.close();
}