Mybatis学习笔记(详细)
介绍
- 三层架构:视图层、业务逻辑层、持久层
- mybatis框架:
- 执行数据库操作,完成对数据库的增删改查,封装了jdbc
- mapper映射,将表中数据转为一个Java对象,一个表对应一个接口
Mybatis实战
- 使用方式:
- 直接获取SqlSession,根据sql id执行sql
- 自定义dao接口实现类,使用接口实现类对象操作(会有大量重复代码)
- 使用mybatis的代理对象:使用getMapper()获取dao对象,直接执行方法访问数据库。
- mybatis框架使用步骤:
- 定义实体类
- 定义接口
- 定义mapper文件
- 定义主配置文件:1.数据源,2.mapper文件位置
- 使用SqlSessionFactoryBuild创建SqlSessionFactory并传入xml配置文件,通过Factory创建SqlSession,通过SqlSession执行一系列数据库操作
- mybatis传递参数
- dao方法有一个简单类型,直接使用#{任意字符}
- 多个参数:使用@Param("xx")指明xml解析的名字
- 使用Java对象,mapper中使用对象的属性
- #和$的区别
- #是占位符,使用PreparedStatement执行sql,效率高
- 表示列的值,一般放在等号右侧使用
- $是字符串连接,使用Statement,效率低,有sql注入的风险
- $一般是替换表名、列名
- mybatis封装sql的执行结果
- 标签中的resultType,指明封装结果的对象,可以使用别名(需要定义,可以复用)
- 标签中的resultMap,指明数据库列名与Java对象属性的对应关系(需要定义,可以复用),或者使用sql语句的as给列取别名
- like:直接使用#{xxx},传递参数给mapper
- 动态sql
- <where>:里面是if,条件满足加入where,并去除多余的and,or等关键字
- <if>:如果条件满足,加入后面的sql语句
- <foreach>:list或array
- mybatis主配置文件:配置项有顺序
- <properties resource=xxx>配置.properties:,使用${}引用
- <settings>中可以配置日志
- <typeAliases>配置别名:<typeAlias>给某个类型,<package>把一个包中的类作为别名(如果有名称相同的类会有冲突)
- <plugins>配置插件
- <environments>配置<dataSource>
- mapper文件的位置:<mapper resource>单个指定,<package name>指定某个包(要求名称与接口名相同,并在同一个包下)
- PageHelper分页插件
- 加入依赖
- 在执行查询前调用PageHelper的静态方法即可
代码
- pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bingmous</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--postgresql驱动-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.19</version>
</dependency>
<!--mybatis分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.1</version>
</dependency>
<!--其他开发插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!--把src目录下的文件复制到target目录-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
- 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>
<!--读取别的地方的配置文件-->
<properties resource="jdbc.properties"></properties>
<!--全局配置-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/><!--加入日志配置,可以在控制台输出执行的sql-->
</settings>
<!--定义别名
1 指定某个类型
2 指定某个包,该包下的类都是别名,不区分大小写(如果有名字相同的类则报错)
建议不使用别名,使用全限定名
-->
<typeAliases>
<!-- <typeAlias type="com.bingmous.beans.Student" alias="stu"></typeAlias>-->
<!-- <package name="com.bingmous.beans"/>-->
</typeAliases>
<!--使用page插件,在environments之前插入-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<environments default="development"><!--默认的数据库连接信息-->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.drive}"/>
<property name="url"
value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/bingmous/dao/StudentDao.xml"/>
<!-- <mapper resource="mapper/StudentDao.xml"/>-->
<!--指定包下的所有接口
注意:必须mapper名与dao名相同,且在同一个包下
-->
<!-- <package name="com.bingmous.dao"/>-->
</mappers>
</configuration>
- jdbc配置文件
jdbc.drive=org.postgresql.Driver
jdbc.url=jdbc:postgresql://10.194.227.212:5432/zztest
jdbc.username=postgres
jdbc.password=hik12345+
- 操作student表的接口
/**
* 操作student表的接口
* created by Bingmous on 2021/7/6 9:59
*/
public interface StudentDao {
List<Student> selectStudents();
//单个简单参数
Student selectStudentById(Integer id);
//多个简单参数
List<Student> selectStudentByNameAndAge(@Param("name") String name,
@Param("age") Integer age);
//使用对象传递参数
List<Student> selectStudentByNameAndAge2(Student student);
//like
List<Student> selectStudentLike(String name);
int insertStudent(Student student); //插入数据
// List<Student> selectDynamicSQL(Student student);
// List<Student> selectDynamicSQL(@Param("name") String name,
// @Param("age") Integer age);
List<Student> selectDynamicSQL(@Param("age") Integer age);
List<Student> selectDynamicSQL2(ArrayList<Student> list);
}
- 对应的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"><!--文档约束文件-->
<!--
namespace:命名空间,写表的Dao的全限定名
select:执行select语句
id:sql语句的唯一表示
resultType:查询结果的类型
-->
<mapper namespace="com.bingmous.dao.StudentDao">
<!--1 使用resultMap指定列与java对象的对应关系(可以复用)
2 sql语句中使用别名
-->
<resultMap id="studentMap" type="com.bingmous.beans.Student">
<id column="id" property="id"></id><!--主键-->
<result column="name" property="name"></result><!--非主键-->
<result column="email" property="email"></result>
<result column="age" property="age"></result>
</resultMap>
<select id="selectStudents" resultMap="studentMap">
select id, name, email, age from student order by id
</select>
<!--单个简单参数:可以不写-->
<select id="selectStudentById" resultType="com.bingmous.beans.Student">
select id, name, email, age from student where id = #{id}
</select>
<!--多个参数:使用@Param-->
<select id="selectStudentByNameAndAge" resultType="com.bingmous.beans.Student">
select id, name, email, age from student where name = #{name} or age = #{age}
</select>
<!--使用对象传递参数:使用对象的属性-->
<select id="selectStudentByNameAndAge2" resultType="com.bingmous.beans.Student">
select id, name, email, age from student where name = #{name} or age = #{age}
</select>
<select id="selectStudentLike" resultType="com.bingmous.beans.Student">
<include refid="selectFragment"></include> where name like #{name}
</select>
<insert id="insertStudent">
insert into student(id, name, email, age)
values (#{id}, #{name}, #{email}, #{age})
</insert>
<!--动态sql-->
<select id="selectDynamicSQL" resultType="com.bingmous.beans.Student">
select id, name, email, age from student
<where>
<!-- <if test="name=''">/*null和""都会解析成空字符串*/
id=1001
</if>-->
<if test="age > 0">
or age > 0
</if>
</where>
</select>
<select id="selectDynamicSQL2" resultType="com.bingmous.beans.Student">
<include refid="selectFragment"></include> where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
<!--sql片段,可以复用-->
<sql id="selectFragment">
select id, name, email, age from student
</sql>
</mapper>
- 接口实现类测试
/**
* created by Bingmous on 2021/7/6 14:14
*/
//public class StudentDaoImpl implements StudentDao {
// @Override
// public List<Student> selectStudents() {
// SqlSession sqlSession = MybatisUtils.getSqlSession();
// List<Student> list = sqlSession.selectList("com.bingmous.dao.StudentDao.selectStudents");
// sqlSession.commit();
// sqlSession.close();
// return list;
// }
//
// @Override
// public int insertStudent(Student student) {
// SqlSession sqlSession = MybatisUtils.getSqlSession();
// int nums = sqlSession.insert("com.bingmous.dao.StudentDao.insertStudent", student);
// sqlSession.commit();
// sqlSession.close();
// return nums;
// }
//
//}
- 获取连接的工具类
/**
* created by Bingmous on 2021/7/6 13:51
*/
public class MybatisUtils {
private static SqlSessionFactory factory = null; //重量级对象,一个项目只有一份就可以了
static {
InputStream is = null;
try {
is = Resources.getResourceAsStream("mybatis.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取session
public static SqlSession getSqlSession(){
if (factory != null) {
return factory.openSession();
}
return null;
}
}
- student实体类
/**
* created by Bingmous on 2021/7/6 9:56
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
/**
* 如果没有无参构造方法,Mybatis会调用全参构造方法
* 如果没有无参,没有全参,会调用其他有参,但必须只有一个
*/
// public Student(Integer id, String name) {
// this.id = id;
// this.name = name;
// System.out.println("构造方法被调用了。。。。" + id + " " + name);
// }
// public Student() {
// System.out.println("无参构造方法被调用了。。。");
// }
// public Student(Integer id, String name, String email, Integer age) {
// this.id = id;
// this.name = name;
// this.email = email;
// System.out.println("全参构造方法:" + id + " " + name + " " + email + " " + age);
// }
}
- 主方法
/**
* created by Bingmous on 2021/7/6 9:56
*/
public class MainApplication {
public static void main(String[] args) throws IOException {
// //获取配置文件
// InputStream is = Resources.getResourceAsStream("mybatis.xml");
// //获取SqlSessionFactory
// SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// //获取session
// SqlSession sqlSession = factory.openSession();
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行配置文件中的sql语句
List<Student> list = sqlSession.selectList("com.bingmous.dao.StudentDao.selectStudents");
list.forEach(System.out::println);
//关闭session
sqlSession.close();
}
}
- 测试方法
/**
* created by Bingmous on 2021/7/6 11:13
*/
public class TestMybatis {
/**
* like
*/
@Test
public void test06Like(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
List<Student> students = studentDao.selectStudentLike("%a%");
students.forEach(System.out::println);
}
/**
* Dao方法传入的参数类型,多个参数:使用@Param()
* Dao方法传入的参数类型,使用对象:使用对象的属性
*/
@Test
public void test05ParameterType(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
List<Student> students = studentDao.selectStudentByNameAndAge("aa", 20);
//使用对象传递参数
// Student student = new Student();
// student.setAge(20);
// student.setName("bb");
// List<Student> students = studentDao.selectStudentByNameAndAge2(student);
students.forEach(System.out::println);
}
/**
* Dao方法传入的参数类型,单个简单参数
*/
@Test
public void test04ParameterType(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
Student student = studentDao.selectStudentById(1001);
System.out.println(student);
}
/**
* 使用Mybatis 的getMapper(),自动创建接口实现类的对象
*/
@Test
public void test03Mapper(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class); //自动创建接口实现类对象
List<Student> students = studentDao.selectStudents();
students.forEach(System.out::println);
}
/**
* 使用Dao实现类
*/
@Test
public void test02DaoImpl() {
// StudentDao studentDao = new StudentDaoImpl();
// List<Student> students = studentDao.selectStudents();
// students.forEach(System.out::println);
//
// int num = studentDao.insertStudent(new Student(1005, "ee", "ee@xx", 22));
// System.out.println("insert num: " + num);
}
//首次使用
@Test
public void test01() throws IOException {
//获取session
// InputStream is = Resources.getResourceAsStream("mybatis.xml");
// SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// SqlSession sqlSession = factory.openSession();
// //执行sql
// Student student = new Student(1004,"dd","dd@123.com",21);
// int nums = sqlSession.insert("com.bingmous.dao.StudentDao.insertStudent",student);
// System.out.println(nums);
// //提交事务,mybatis默认不提交
// sqlSession.commit();
// sqlSession.close();
}
}
- 测试动态sql方法
/**
* created by Bingmous on 2021/7/6 20:27
*/
public class TestDynamicSQL {
/**
* <where></where> <if></if>标签的使用
* 注意:null值会被解析成空字符串,在标签中,空字符串用单引号表示
* Dao中即使是单个简单参数也必须使用@Param,或者使用对象参数
*/
@Test
public void test01() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("");
// List<Student> students = studentDao.selectDynamicSQL(student);
// List<Student> students = studentDao.selectDynamicSQL(null,10);
// List<Student> students = studentDao.selectDynamicSQL(10);
var student1 = new Student();
student1.setId(1001);
var student2 = new Student();
student2.setId(1002);
var list = new ArrayList<Student>();
list.add(student1);
list.add(student2);
List<Student> students = studentDao.selectDynamicSQL2(list);
students.forEach(System.out::println);
sqlSession.commit();
sqlSession.close();
}
}
- 测试pagehelper
/**
* created by Bingmous on 2021/7/6 22:46
*/
public class TestPageHelper {
@Test
public void testPageHelper() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
PageHelper.startPage(2,2); //在查询之前调用即可
List<Student> students = studentDao.selectStudents();
students.forEach(System.out::println);
PageHelper.startPage(3,2);
List<Student> students2 = studentDao.selectStudents();
students2.forEach(System.out::println);
sqlSession.commit();
sqlSession.close();
}
}
---
本文来自博客园,作者:Bingmous,转载请注明原文链接:https://www.cnblogs.com/bingmous/p/15643675.html