要学的内容
1.mybatis-CRUD 2.MyBatis配置文件 3.结果集映射 (重点难点) 4.分页 5.使用注解开发 (重点) 6.一对多、多对一的处理 (难点) 7.动态SQL (重点) 8.缓存 (十分重要,极其重要) 9.MyBatis- Plus 10.Log4j 11.通用Mapper
以后学任何思路:配环境——导入框架(mybatis)——编写代码——测试
这次学练习没多少,都是跟着视频来的,重复的不多,会容易遗忘。
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
mybatis用来用去还是,设置接口userMapper.java,配置文件userMapper.xml,测试
持久化和持久层
持久化:数据持久化,持久化就是将程序的数据在持久状态和瞬时状态转化的过程 ·内存:断电即失 ·数据库(Jdbc),io文件持久化。
**为什么需要需要持久化?**有一些对象,不能让他丢掉。内存太贵了
持久层:Dao层 , Service层, Controller层..是完成持久化工作的代码块,层界限十分明显。
为什么用Mybatis
1.帮助程序猿将数据存入到数据库中。 2.方便 3.传统的JDBC代码太复杂了。简化。框架。自动化。 4.不用Mybatis也可以。更容易上手。技术没有高低之分
优点: 。 简单易学 。 灵活 。 sql和代码的分离,提高了可维护性。 。提供映射标签,支持对象与数据库的orm字段关系映射 。提供对象关系映射标签,支持对象关系组建维护 。 提供xml标签,支持编写动态sql。
最重要的一点:使用的人多!
1.配置环境
src
└── main
├── java
│ └── com.littlespark
│ ├── myMapper
│ │ ├── userMapper
│ │ └── userMapper.xml
│ ├── pojo
│ │ └── User
│ └── utils
│ └── myUtils
├── resources
│ └── mybatis-config.xml
└── webapp
└── test
└── java
└── com.littlesaprk.mapper
└── userMapperTest
八个东西:
com/littlespark/myMapper/userMapper.java;com/littlespark/myMapper/userMapper.xml ;com/littlespark/pojo/User.java;com/littlespark/utils/myUtils.java ;
mybatis-config.xml;userMapperTest.java
Utils方法类
pom.xml
创建数据库
CREATE DATABASE `mybatis`;
use `mybatis`;
CREATE TABLE `user`(
`id` INT(20) not null PRIMARY KEY,
`name` VARCHAR(30) DEFAULT NULL,
`pwd` VARCHAR(20) DEFAULT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;
INSERT into `user`(`id`,`name`,`pwd`) VALUES
(1,'kobe','123123'),
(2,'durant','123123'),
(3,'lebron','123123');
pom.xml因为下载的MYSQL服务器是8.0+,所以这里的配置也要到8.0之后的。
<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/maven-v4_0_0.xsd>">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.littlespark</groupId>
<artifactId>first</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>son</artifactId>
<packaging>war</packaging>
<name>son Maven Webapp</name>
<url><http://maven.apache.org></url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- <scope>java</scope>-->
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>**8.0.24**</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
</dependencies>
<build>
<finalName>son</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<!--
若 <filtering>true</filtering>,Maven 会替换资源文件中的 ${},
可能导致 db.properties 中的 ${driver} 被错误替换。
-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
mybatis-config.xml 因为MYSQL是8.0所以driver要改为com.mysql.cj.jdbc.Driver
<?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="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true" />
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 每一个mapper.xml都需要再mybatis核心配置文件中注册-->
<mappers>
<mapper resource="com/littlespark/myMapper/userMapper.xml"/>
</mappers>
</configuration>
userMapper.xml
namespace="com.littlespark.myMapper.userMapper是为了联系接口userMapper,userMapper接口的方法名getUserList(),
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.userMapper">
<select id="getUserList" resultType="com.littlespark.pojo.User">
select * from mybatis.user
</select>
</mapper>
userMapper 接口
package com.littlespark.myMapper;
import com.littlespark.pojo.User;
import java.util.List;
public interface userMapper {
List<User> getUserList();
}
User实体类
package com.littlespark.pojo;
public class User {
private int id;
private String name;
private int pwd;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPwd() {
return pwd;
}
public void setPwd(int pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\\'' +
", pwd=" + pwd +
'}';
}
}
Utils方法类
package com.littlespark.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 myUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 第一步,获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 有了SqlSessionFactory 就可以获得SqlSession的实例
// SqlSession 完全包含了面向数据可执行的SQL命令的所有方法
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
2.CRUD
namespace="com.littlespark.myMapper.userMapper"
namespace的包名要和接口的包名一致。
之前配置的内容,变得不多,变四处,还真的服一直报错,重启就又好了
Process finished with exit code 1
Class not found: "com.littlesaprk.mapper.userMapperTest"
userMapper.java;userMapper.xml;userMapperTest.java
userMapper.java 接口添加 User getUserById(int id);
package com.littlespark.myMapper;
import com.littlespark.pojo.User;
import java.util.List;
public interface userMapper {
List<User> getUserList();
User getUserById(int id);
int addUser(User user);
int updateUser(User user);
int deleteUser(int id);
}
userMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.userMapper">
<select id="getUserList" resultType="com.littlespark.pojo.User">
select * from mybatis.user
</select>
<select id="getUserById" resultType="com.littlespark.pojo.User" parameterType="int">
select * from mybatis.user where id = #{id}
</select>
<insert id="addUser" parameterType="com.littlespark.pojo.User" >
insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd});
</insert>
<update id="updateUser" parameterType="com.littlespark.pojo.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
</update>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id = #{id};
</delete>
</mapper>
userMapperTest.java
package com.littlesaprk.mapper;
import com.littlespark.myMapper.userMapper;
import com.littlespark.pojo.User;
import com.littlespark.utils.myUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class userMapperTest {
@Test
public void test() {
SqlSession sqlSession = myUtils.getSqlSession();// 获取sqlSession对象
userMapper mapper = sqlSession.getMapper(userMapper.class);
for (User user : mapper.getUserList()) {
System.out.println(user);
}
sqlSession.close();
}
@Test
public void getUserById(){
SqlSession sqlSession = myUtils.getSqlSession();
userMapper mapper = sqlSession.getMapper(userMapper.class);
User user = mapper.getUserById(4);
sqlSession.close();
}
@Test
public void addUser(){
SqlSession sqlSession = myUtils.getSqlSession();
userMapper mapper = sqlSession.getMapper(userMapper.class);
mapper.addUser(new User(4,"lll","1231231"));
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUser(){
SqlSession sqlSession = myUtils.getSqlSession();
userMapper mapper = sqlSession.getMapper(userMapper.class);
mapper.updateUser(new User(4,"lll","123112312331"));
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser(){
SqlSession sqlSession = myUtils.getSqlSession();
userMapper mapper = sqlSession.getMapper(userMapper.class);
mapper.deleteUser(4);
sqlSession.commit();
sqlSession.close();
}
}
3.万能的map
因为userMapper.xml也需要写很多的sql语句,每一条对应一个函数,也很多,优化方案就是这个map。
当实体类或数据库表,字段的参数过度,就可以用map。因为如果不用,那就要把所有的参数都列出来,但是有了这个map修改啥就可以列啥。
动四个地方:userMapper.java;userMapper.xml;userMapperTest.java;userMapper.java
package com.littlespark.myMapper;
import com.littlespark.pojo.User;
import java.util.List;
public interface userMapper {
int addUser2(Map map);
}
userMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.userMapper">
<!-- 这里的values的数据就直接可以变,不需要跟User实体类对应,而且只插入一部分也行-->
<insert id="addUser2" parameterType="map" >
insert into mybatis.user(id,name) values(#{adsadasd},#{namesdsadad});
</insert>
</mapper>
userMapperTest.java
package com.littlesaprk.mapper;
import com.littlespark.myMapper.userMapper;
import com.littlespark.pojo.User;
import com.littlespark.utils.myUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class userMapperTest {
@Test
public void addUser2(){
SqlSession sqlSession = myUtils.getSqlSession();
userMapper mapper = sqlSession.getMapper(userMapper.class);
Map<String, Object> map = new HashMap<String, Object>();
// 只为了说明,有了map,不需要对应User属性名字也行
map.put("adsadasd",1111);
map.put("namesdsadad","lll");
mapper.addUser2(map);
sqlSession.commit();
sqlSession.close();
}
}
4.配置解析
My Batis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 configuration (配置) properties (属性) settings (设置) typeAliases (类型别名) typeHandlers (类型处理器) objectFactory (对象工厂) plugins (插件) environments (环境配置) environment ( 环境变量) transactionManager (事务管理器) dataSource (数据源) databaseIdProvider (数据库厂商标识) mappers(映射器)
db.properties配mybatis-config.xml
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
<?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="db.properties"/>
<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>
<!-- 每一个mapper.xml都需要再mybatis核心配置文件中注册-->
<mappers>
<mapper resource="com/littlespark/myMapper/userMapper.xml"/>
</mappers>
</configuration>
pom.xml有一个问题。若 <filtering>true</filtering>,Maven 会替换资源文件中的 ${},可能导致 db.properties 中的 ${driver} 被错误替换。所以**/*.properties的过滤器改为 <filtering>false</filtering>
<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/maven-v4_0_0.xsd>">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.littlespark</groupId>
<artifactId>first</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>son</artifactId>
<packaging>war</packaging>
<name>son Maven Webapp</name>
<url><http://maven.apache.org></url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- <scope>java</scope>-->
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.24</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
</dependencies>
<build>
<finalName>son</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<!--
若 <filtering>true</filtering>,Maven 会替换资源文件中的 ${},
可能导致 db.properties 中的 ${driver} 被错误替换。
-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
5.类型别名
在mybatis-config.xml注册别名,然后在userMapper.xml就可以在parameterType直接用这个别名就不需要把完成的包名写出来了。
**<typeAliases>
<typeAlias type="com.littlespark.pojo.User" alias="User"/>
</typeAliases>**
pom.xml有一个问题。这个<filtering>true</filtering>有很多问题,直接注释掉就好了
两个地方:mybatis-config.xml,userMapper.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>
<!--引入配置文件写最上面 -->
<properties resource="db.properties"/>
**<typeAliases>
<typeAlias type="com.littlespark.pojo.User" alias="User"/>
</typeAliases>**
<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>
<!-- 每一个mapper.xml都需要再mybatis核心配置文件中注册-->
<mappers>
<mapper resource="com/littlespark/myMapper/userMapper.xml"/>
</mappers>
</configuration>
userMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.userMapper">
<select id="getUserList" resultType="**User**">
select * from mybatis.user
</select>
</mapper>
第二种配置的方法,在mybatis-config.xml配置换成这个就行了,其他不变
<typeAliases>
<package name="com.littlespark.pojo"/>
</typeAliases>
在实体类比较少的时候,使用第一种方式。因为一条对应一个实体类。
如果实体类十分多,建议使用第二种。一下子对应一个包里的所有实体类。
第一种可以DIY别名,第二种则不行,如果非要改,需要在实体上增加注解
也就是在pojo/User.java这个实体类最上面添上注解@Alias(”dddd”),这样userMapper.xml的resultType也就可以根据这个注解@Alias(”dddd”)写成,resultType=“dddd”,实现了自定义别名的功能。
6.不太理解 SqlSessionBuilder SqlSessionFactory SqlSession之前的区别。
7.日志
SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING
很简单,添加一句话,注意在mybatis-config.xml的位置
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<?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="db.properties"/>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.littlespark.pojo"/>
</typeAliases>
<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>
<!-- 每一个mapper.xml都需要再mybatis核心配置文件中注册-->
<mappers>
<mapper resource="com/littlespark/myMapper/userMapper.xml"/>
</mappers>
</configuration>
如果用log4j的话,两个地方,pom.xml要导包,mybatis-config.xml配置为setting
<settings>
<setting name="logImpl" value="log4j"/>
</settings>
pom.xml的dependence导一个log4j的包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
8.注解
为什么都需要写一个接口,然后再来实现这个接口?就是为了解耦。
练习注解,这时候就不需要userMapper.xml了。
注意原本的是/ 现在变**.**
在这里还有个问题,如果userMapper.xml没有被删除,但是mybatis-config.xml只有class的mapper就会出问题,就算把userMapper.xml注释掉,也不行。
src
└── main
├── java
│ └── com.littlespark
│ ├── myMapper
│ │ ├── userMapper
│ │ └── userMapper.xml
│ ├── pojo
│ │ └── User
│ └── utils
│ └── myUtils
├── resources
│ └── mybatis-config.xml
└── webapp
└── test
└── java
└── com.littlesaprk.mapper
└── userMapperTest
修改两个东西:mybatis-config.xml,userMapper.java接口
mybatis-config.xml要由原本的 <mapper resource="com/littlespark/myMapper/userMapper.xml"/>改为<mapper class="com.littlespark.myMapper.userMapper"/>
<?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="db.properties"/>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.littlespark.pojo"/>
</typeAliases>
<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 class="com.littlespark.myMapper.userMapper"/>
</mappers>
</configuration>
userMapper.java接口
package com.littlespark.myMapper;
import com.littlespark.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
public interface userMapper {
@Select("select * from user")
List<User> getUserList();
@Select("select * from user where id=${idiiiiiiiii}")
User getUserById(@Param("idiiiiiiiii") int id);
@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);
int addUser2(Map<String,Object> map);
@Update("update user set name=#{name},pwd=#{pwd} where id=#{id}")
int updateUser(User user);
@Delete("delete from user where id= #{eqweqweqweqwe}")
int deleteUser(@Param("eqweqweqweqwe") int id);
}
其他不需要变,测试类直接测试就可以了
Lombok偷懒神器
可用可不用,没啥东西
多对一
src
└── main
├── java
│ └── com.littlespark
│ ├── myMapper
│ │ ├── studentMapper
│ │ └── teacherMapper
│ ├── pojo
│ │ ├── Student
│ │ └── Teacher
│ └── utils
│ └── myUtils
├── resources
│ ├── com.littlespark.myMapper
│ │ ├── studentMapper.xml
│ │ └── teacherMapper.xml
│ ├── db.properties
│ └── mybatis-config.xml
└── webapp
└── test
└── java
└── com.littlesaprk.mapper
├── studentMapperTest
└── teacherMapperTest
要实现这个功能:
select s.id ,s.name,t.name from student s,teacher t where s.tid=t.id;
根据student的外键tid找到老师的id
修改九个地方:mybatis-config.xml,studentMapper.java,Student.java,studentMapper.xml,teacherMapper.java,Teacher.java, teacherMapper.xml,studentMapperTest.java,teacherMapperTest.java
**create table teacher(
`id` int(20) not null primary key ,
`name` varchar(30) default null
);
insert into teacher(`id`,`name`) values
(1,'hh'),(2,'kobe');
create table student(
`id` int(20) not null,
`name` varchar(30) default null,
`tid` int(10) default null,
primary key (`id`),
key `fktid`(`tid`),
constraint `fktid` foreign key (`tid`) references `teacher`(`id`)
);
insert into student(`id`,`name`,`tid`) values
(1,'ivring','1'),(2,'nay','2'),(3,'yao','2'),(4,'wang','2');**
mybatis-config.xml就这两句话
<mapper resource="com/littlespark/myMapper/teacherMapper.xml"/> <mapper resource="com/littlespark/myMapper/studentMapper.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>
<!--引入配置文件写最上面 -->
<properties resource="db.properties"/>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.littlespark.pojo"/>
</typeAliases>
<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="com/littlespark/myMapper/teacherMapper.xml"/>
<mapper resource="com/littlespark/myMapper/studentMapper.xml"/>
</mappers>
</configuration>
studentMapper.java,Student.java,studentMapper.xml 写一个就行了很像
teacherMapper.java,Teacher.java, teacherMapper.xml
package com.littlespark.myMapper;
import com.littlespark.pojo.Student;
import java.util.List;
public interface studentMapper {
List<Student> getStudentList();
}
无参构造必须有
package com.littlespark.pojo;
public class Student {
private int id;
private String name;
private Teacher teacher;
public Student(){}
public Student(int id, String name, Teacher teacher) {
this.id = id;
this.name = name;
this.teacher = teacher;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\\'' +
", teacher=" + teacher +
'}';
}
}
*****studentMapper.xml,因为要根据student表里的tid找到teacher表里的name,但在studentMapper.xml里一次只能查一个表。就用到了这三条语句,最上面最下面都是简单的查student,teacher表的语句。
查getStudentList的时候,返回值是resultMap="studentTeacher",而这个studentTeacher就注册为中间的地方resultMap。
property是数据库里的字段名,column是实体类的字段名。而result只能针对单个属性,复杂的属性就只能用association(对象)或collection (集合),这里返回的是一个单个对象所以association
association 里也有property对应的是student实例的第三个字段也就是Teacher,学生表第三个内容是tid 。返回的内容因为是复杂的类型,这里写javaType="Teacher" 。
如何得到tid对应的teacher呢?就是通过嵌套查询select="getTeacherList",对应的就是第三个语句的<select id="getTeacherList" resultType="Teacher">,通过这个查询得到的teacher数据。
有个疑问:这里的是studentMapper.xml如何能找到com.littlespark.myMapper.teacherMapper的方法?
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
<select id="getStudentList" resultMap="studentTeacher">
select * from mybatis.student
</select>
<resultMap id="studentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="Teacher" select="getTeacherList"/>
</resultMap>
<select id="getTeacherList" resultType="Teacher">
select * from mybatis.teacher where id = #{id}
</select>
</mapper>
上面的方法是按照查询嵌套,下面的第二种方法是按照结果嵌套
动两个东西:studentMapper.java studentMapper.xml
package com.littlespark.myMapper;
import com.littlespark.pojo.Student;
import java.util.List;
public interface studentMapper {
List<Student> getStudentList();
}
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
<select id="getStudentList2" resultMap="studentTeacher2">
select s.id sid,s.name sname,t.name tname
from student s, teacher t
where s.tid = t.id;
</select>
<resultMap id="studentTeacher2" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
</mapper>
一对多
根据一个老师的tid找到对应的学生有哪些?(感觉跟多对一很像,也不太一样)
动四个东西:teacherMapper.java,teacherMapper.xml,Teacher.java,Student.java
package com.littlespark.myMapper;
import com.littlespark.pojo.Teacher;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface teacherMapper {
Teacher getTeacherById(@Param("teacherMapperParam") int id);
}
Teacher.java 和Student.java写在一块了,可以看看对比一下
package com.littlespark.pojo;
import java.util.List;
public class Teacher {
private int id;
private String name;
private List<Student> students;
}
package com.littlespark.pojo;
public class Student {
private int id;
private String name;
private int studentPojoTeacherId;
}
teacherMapper.xml,写的很详细了。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
<select id="getTeacherById" resultMap="TeacherSelectHowManyStudents">
select s.id sid, s.name sname,t.name tname,t.id tid
from student s,teacher t
where s.tid=t.id and t.id=#{teacherMapperParam}
</select>
<resultMap id="TeacherSelectHowManyStudents" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!--
1.因为这次返回的是List<Student>是集合,所以用collection
之前返回的是Teacher 是对象 所以用的是association
2.上面俩属性是返回的是teacher的名字,为啥column是tid?因为查询的语句改名字了
3.这个collection是对应的集合,自然property属性就是Student的属性。
第一个property根据的是teacher里的 private List<Student> students;
4.javaType指定属性的类型,集合当中泛型信息List<>都是用ofType
-->
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="studentPojoTeacherId" column="tid"/>
</collection>
</resultMap>
</mapper>
动态SQL
可以实现SQL的复用,本质上还是Sql的语句.
什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句
利用动态SQL这一特性可以彻底摆脱这种痛苦。动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。 MyBatis大大精简了元素种类,现在只需学习原来一半的元素便可。 MyBatis 采用功能强大的基于 OGNL的表达式来淘汰其它大部分元素。 if choose (when, otherwise) trim (where, set) I foreach
if
三个地方:studentMapper.java,studentMapper.xml,studentMapperTest.java
studentMapper.java,这里传递的Map map,就是对应的id ,name
package com.littlespark.myMapper;
import com.littlespark.pojo.Student;
import java.util.List;
import java.util.Map;
public interface studentMapper {
List<Student> getStudentList3(Map map);
}
studentMapper.xml,语法就是IF
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
<select id="getStudentList3" parameterType="map" resultType="Student">
select * from student where 1=1
<if test="id != null">
and id = #{id}
</if>
<if test="name != null">
and name = #{name}
</if>
</select>
</mapper>
studentMapperTest.java,hashMap.put("id", "1");如果注释掉这句话,那么就是查全部,也就是两个if语句都失效,那就是where 1=1 全查,这里的id也就是传进去的#{id},要变都同时变。
变三处
hashMap.put("idddd
", "1");
<if test="idddd != null">
and id = #{idddd}</if>
public class studentMapperTest {
@Test
public void testStudentMapper() {
SqlSession sqlSession = myUtils.getSqlSession();
studentMapper mapper = sqlSession.getMapper(studentMapper.class);
HashMap hashMap = new HashMap<>();
hashMap.put("id", "1");
for(Student student:mapper.getStudentList3(hashMap)){
System.out.println(student);
}
sqlSession.commit();
sqlSession.close();
}
}
choose(when ,otherwise)
只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
<select id="getStudentList3" parameterType="map" resultType="Student">
select * from student
<where>
<choose>
<when test="idddd != null">
id = #{idddd}
</when>
<when test="name != null">
and name = #{name}
</when>
<otherwise>
and id = 1
</otherwise>
</choose>
</where>
</select>
where保证当 and在开始的时候,会自动去掉,choose就是switch选择,otherwise就是如果前两个都没匹配上就默认查最后这句话。
trim(where,set)
<select id="getStudentList3" parameterType="map" resultType="Student">
select * from student where
<if test="id != null">
id = #{id}
</if>
<if test="name != null">
and name = #{name}
</if>
</select>
这里有个问题,如果只是配test="name != null" 这个if,上面test="id != null"没有匹配成功,那么翻译过来的sql语句就是 select * from student where and name = #{name};
这个是错误的,所以where就起作用了
<select id="getStudentList3" parameterType="map" resultType="Student">
select * from student
<where>
<if test="id != null">
id = #{id}
</if>
<if test="name != null">
and name = #{name}
</if>
</where>
</select>
如果只匹配第二句这种and或or开头的,会自动消除and 或者or
翻译过来的sql语句就是 select * from student where name = #{name};
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号
原本更新语句
<update id="updateStudent" parameterType="map">
update student set name = #{name} where id = #{idddd}
</update>
使用set之后
<update id="updateStudent" parameterType="map">
update student
<set>
<if test="idddd != null" >id = #{idddd},</if>
<if test="name != null" >name = #{name}</if>
</set>
where tid = #{tid}
</update>
对应
public class studentMapperTest {
@Test
public void testStudentMapper() {
SqlSession sqlSession = myUtils.getSqlSession();
studentMapper mapper = sqlSession.getMapper(studentMapper.class);
HashMap hashMap = new HashMap<>();
hashMap.put("idddd", "1010");
hashMap.put("name", "crazy");
hashMap.put("tid", "1");
mapper.updateStudent(hashMap);
sqlSession.commit();
sqlSession.close();
}
}
foreach
你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach
当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。
当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。 open="(" separator="," close=")" 这句话的意思 是把 collection="list"集合里的元素提取出来,按照
( , , , , , )的格式获取,每个,之间的内容就是list的数据
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach collection="list" item="item" index="index" open="(" separator="," close=")">
#{item}
</foreach>
</select>
举个例子:select * from student where 1=1 and( id=1 or id=2 or id=3)
动三个地方:studentMapper.java,studentMapper.xml,studentMapperTest.java
studentMapper.xml
parameterType="map" 传递进来的是Map map
resultType="student" 要返回的数值类型是Student
collection="integers" 对应的是前面传递的map的K V里的V(values值)。
item="idssss" 取每一个values值的别名idssss
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
<select id="selectByIds" parameterType="map" resultType="student">
select * from student
<where>
1=1
<foreach collection="integers" item="idssss" open="and(" close=")" separator="or">
id = #{idssss}
</foreach>
</where>
</select>
</mapper>
studentMapperTest.java
public class studentMapperTest {
@Test
public void testStudentMapper() {
SqlSession sqlSession = myUtils.getSqlSession();
studentMapper mapper = sqlSession.getMapper(studentMapper.class);
HashMap hashMap = new HashMap<>();
ArrayList<Integer> integers = new ArrayList<>();
integers.add(1);
integers.add(2);
hashMap.put("integers", integers);
for(Student student:mapper.selectByIds(hashMap)){
System.out.println(student);
}
sqlSession.commit();
sqlSession.close();
}
}
studentMapper.java
package com.littlespark.myMapper;
import com.littlespark.pojo.Student;
import java.util.List;
import java.util.Map;
public interface studentMapper {
List<Student> selectByIds(Map map);
}
动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了 建议:在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可!
缓存
查询,连接数据库 ,耗资源! 一次查询的结果,给他暂存在一个可以直接取到的地方!--> 内存 : 缓存 我们再次查询相同数据的时候,直接走缓存,就不用走数据库了
为什么使用缓存?减少和数据库的交互次数,减少系统开销,提高系统效率。
什么样的数据能使用缓存?经常查询并且不经常改变的数据。【可以使用缓存】
MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 默认情况下,只有一级缓存开启。(SqISession级别的缓存,也称为本地缓存) 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。(也就是写的那么多次的mapper配置) 为了提高扩展性, MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
第一次查询是存放在一级缓存里,当SqlSession关闭的时候,会把以及缓存的数据放到Mapper的二级缓存里,当新的查询又来的时候,会先从二级缓存里找,找不到再去一级缓存里????再找不到再去数据库找
是这样吗?