一.动态SQL
1.foreach标签
修改映射文件
<?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=接口的全路径 -->
<mapper namespace="cn.tedu.dao.DeptMapper">
<!-- 提取SQL片段,提高SQL片段复用性 -->
<sql id="cols">
id,dname,loc
</sql>
<!-- delete from dept where id in(1,2,3)-->
<delete id="delete">
delete from dept where id in(
/*foreach用来完成遍历
collection表示要遍历哪种集合里的数据,值是固定值:array/list/Map.key
item表示即将遍历到的数据,separator是分隔符,#{ids}获取遍历到的数据
*/
<foreach collection="array" item="ids" separator=",">
#{ids}
</foreach>
)
</delete>
<!-- 引用SQL片段 -->
<select id="getByName" resultType="Dept">
select
<include refid="cols"></include>
from dept
<if test="dname != null">
where dname=#{dname}
</if>
</select>
<!--id=接口里的方法名-->
<select id="getById" resultType="Dept">
select
<include refid="cols"></include>
from dept where id=1
</select>
<!--新增部门记录-->
<insert id="save">
insert into dept values(#{id},#{dname},#{loc})
</insert>
</mapper>
修改接口文件
package cn.tedu.dao;
import cn.tedu.pojo.Dept;
import java.util.List;
//接口的全路径=映射文件中namespace的值
//接口的方法名=映射文件中id的值
public interface DeptMapper {
Dept getById(); //根据id查
List<Dept> getByName(String dname);//根据名字查
void save(Dept dept);//新增部门记录
void delete(int[] a);//删除
}
修改测试类
package cn.tedu.test;
import cn.tedu.dao.DeptMapper;
import cn.tedu.pojo.Dept;
import cn.tedu.pojo.User;
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 org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Test1 {
@Test
public void get() throws IOException {
//读取配置文件
InputStream in = Resources.getResourceAsStream(
"mybatis-config.xml");
//创建会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(in);
//开启会话,准备执行SQL
SqlSession session = factory.openSession();
//定位SQL(namespace的值.id的值),并执行
//selectOne执行查询的SQL,并只会返回一个结果
Object o = session.selectOne("userMapper.getById",2);
//User(id=1, name=hanmeimei, addr=北京, age=28)
System.out.println(o);
//定位SQL(namespace的值.id的值),并执行
//selectList执行查询的SQL,并返回多个结果
List<User> list = session.selectList("userMapper.getAll");
for(User u : list){
System.out.println(u);
}
//定位SQL(namespace的值.id的值),并执行,并给SQL传入参数
User u = session.selectOne(
"userMapper.getByName","xiongda");
System.out.println(u);
//定位SQL(namespace的值.id的值)
// Dept d = session.selectOne("deptMapper.getById");
// System.out.println(d);
//获取了指定的接口
DeptMapper mapper = session.getMapper(DeptMapper.class);
//调用接口里的方法
Dept dd = mapper.getById();
System.out.println(dd);
List<Dept> ds = mapper.getByName(null);
for (Dept d : ds) {
System.out.println(d+"=================");
}
Dept dept = new Dept();
dept.setId(null).setDname("ios开发部").setLoc("上海");
mapper.save(dept);
//mybatis不会自动提交事务,增删改需要自己提交事务
session.commit();
mapper.delete(new int[]{103,104});
session.commit();
}
}
总结
二.ResultMap
1.概述
resultType只能完成简单的ORM,只能完成那些字段名和属性名一致的情况
字段名和属性名不一样的情况,resultType必须换成resultMap,否则无法ORM
2.测试
项目结构
创建了表,加了记录
CREATE TABLE `user_info` (
`id` int(11) NOT NULL auto_increment,
`user_name` varchar(20) default NULL,
`user_addr` varchar(20) default NULL,
`user_age` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
修改pom.xml,添加mybatis的jar包
<?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">
<parent>
<artifactId>cgb2106boot03</artifactId>
<groupId>cn.tedu</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>day19</artifactId>
<dependencies>
<!--mybatis依赖包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--jdbc依赖包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
</dependencies>
</project>
创建核心配置文件
<?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">
<!-- mybatis的核心配置文件,配置了事务管理,数据源 -->
<configuration>
<!--environments可以配置多个数据库的连接信息,default指定默认的环境-->
<environments default="test">
<environment id="test">
<!--使用的事务管理器-->
<transactionManager type="JDBC"></transactionManager>
<!--配置了数据源-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb2?characterEncoding=utf8&serverTimezone=Asia/Shanghai" />
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--引入映射文件-->
<mappers>
<mapper resource="userInfoMapper.xml"></mapper>
</mappers>
</configuration>
创建映射文件
<?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="cn.tedu.dao.UserInfoMapper">
<!-- 查询所有 ,字段名和属性名不一样,resultType换成resultMap
resultType="cn.tedu.pojo.UserInfo"
-->
<!-- ORM:是指把字段的值查到以后 交给 同名属性保存
使用resultMap: 字段名 和 属性名 不一样
id是唯一标识 type是类的全路径
-->
<resultMap id="abc" type="cn.tedu.pojo.UserInfo">
<result column="user_name" property="userName"></result>
<result column="user_addr" property="userAddr"></result>
<result column="user_age" property="userAge"></result>
</resultMap>
<!--resultMap属性是解决了resultType解决不了的问题,引用指定的resultMap-->
<select id="selectList" resultMap="abc">
select * from user_info
</select>
</mapper>
创建接口类
package cn.tedu.dao;
import cn.tedu.pojo.UserInfo;
import java.util.List;
public interface UserInfoMapper {
List<UserInfo> selectList();//查询所有
}
创建pojo类
package cn.tedu.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class UserInfo {
private Integer id;
private String userName;
private String userAddr;
private Integer userAge;
}
测试
package cn.tedu.test;
import cn.tedu.dao.UserInfoMapper;
import cn.tedu.pojo.UserInfo;
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 org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Test1 {
@Test
public void all() throws IOException {
InputStream in = Resources.getResourceAsStream(
"mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(in);
//true表示自动提交事务
SqlSession session = factory.openSession(true);
//获取指定接口
UserInfoMapper mapper = session.getMapper(UserInfoMapper.class);
//调用方法
List<UserInfo> list = mapper.selectList();
for (UserInfo uf : list) {
//UserInfo(id=1, userName=null, userAddr=null, userAge=null)
System.out.println(uf);
}
}
}
总结
3.优化假话resultmap
第一步:在核心配置文件中开启驼峰规则:
<?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">
<!-- mybatis的核心配置文件,配置了事务管理,数据源 -->
<configuration>
<settings>
<!--开启驼峰规则,简化resultMap的编写-->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<!--environments可以配置多个数据库的连接信息,default指定默认的环境-->
<environments default="test">
<environment id="test">
<!--使用的事务管理器-->
<transactionManager type="JDBC"></transactionManager>
<!--配置了数据源-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb2?characterEncoding=utf8&serverTimezone=Asia/Shanghai" />
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--引入映射文件-->
<mappers>
<mapper resource="userInfoMapper.xml"></mapper>
</mappers>
</configuration>
第二步:resultMap标签中天剑新属性 autoMapping = "true"
<?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="cn.tedu.dao.UserInfoMapper">
<!-- 查询所有 ,字段名和属性名不一样,resultType换成resultMap
resultType="cn.tedu.pojo.UserInfo"
-->
<!-- ORM:是指把字段的值查到以后 交给 同名属性保存
使用resultMap: 字段名 和 属性名 不一样
id是唯一标识 type是类的全路径
autoMapping="true"是开启了自动驼峰规则的匹配
-->
<resultMap autoMapping="true" id="abc" type="cn.tedu.pojo.UserInfo">
<!-- <result column="user_name" property="userName"></result>
<result column="user_addr" property="userAddr"></result>
<result column="user_age" property="userAge"></result>-->
</resultMap>
<!--resultMap属性是解决了resultType解决不了的问题,引用指定的resultMap-->
<select id="selectList" resultMap="abc">
select * from user_info
</select>
</mapper>
三.SSM整合
0.准备mybatis的jar包
<?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">
<parent>
<artifactId>cgb2106boot03</artifactId>
<groupId>cn.tedu</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>SSM01</artifactId>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
1.创建前端HTML网页
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ssm</title>
</head>
<body>
<a href="http://localhost:8080/car/get">点我请求服务器的资源</a>
</body>
</html>
2.创建启动类RunApp
package cn.tedu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//扫描dao层接口文件所在的包,框架自动生成实现类
@MapperScan("cn.tedu.dao")
public class RunApp {
public static void main(String[] args) {
SpringApplication.run(RunApp.class);
}
}
3.创建配置文件application.yml
#是一个特殊的文件,特殊在这个文件将被springboot框架自动加载-开箱即用
#格式非常严格,k: v
#SpringBoot配置mysql信息
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///mybatisdb?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: root
#SpringBoot整合Mybatis配置
mybatis:
#指定UserMapper.xml文件的位置
mapper-locations: classpath:*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
4.创建pojo类
package cn.tedu.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.stereotype.Component;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)//lombok的链式编程
@Component //ioc
public class Car {
private Integer id;
private String name;
private String color;
private Double price;
}
5.创建CarMapper接口
package cn.tedu.dao;
import cn.tedu.pojo.Car;
import java.util.List;
@Component//没有啥意义
public interface CarMapper {
List<Car> selectList(); //查询所有数据
}
6.创建映射文件CarMapper.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">
<!--namespace的值=dao层接口的全路径-->
<mapper namespace="cn.tedu.dao.CarMapper">
<!--查询所有数据 id=接口中的方法名-->
<select id="selectList" resultType="cn.tedu.pojo.Car">
select * from car
</select>
</mapper>
7.创建CarService接口
package cn.tedu.service;
import cn.tedu.pojo.Car;
import java.util.List;
public interface CarService {
List<Car> selectList(); //查询所有数据
}
8.创建CarServiceImpl实现类
package cn.tedu.service;
import cn.tedu.dao.CarMapper;
import cn.tedu.pojo.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service //ioc
public class CarServiceImpl implements CarService{
@Autowired //di依赖注解dao层,为了使用dao的功能
private CarMapper mapper;
@Override //查询所有数据
public List<Car> selectList() {
return mapper.selectList();
}
}
9.创建CarController类
package cn.tedu.controller;
import cn.tedu.pojo.Car;
import cn.tedu.service.CarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController//相当于@Controller+@ResponseBody
@RequestMapping("car")
public class CarController {
@Autowired //di
private CarService carService ;
//查询所有数据
@RequestMapping("get")
public List<Car> selectList(){
return carService.selectList() ;
}
}
10.测试
打开浏览器,访问服务器
11.总结