- 一、ORM介绍
- 二、Mybatis框架介绍
- 三、Mybatis入门程序
- 设置
- 输出信息到控制抬
- 输出DEBUG 级别以上的日志到=E://logs/error.log
- log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
- log4j.appender.D.File = E://logs/log.log
- log4j.appender.D.Append = true
- log4j.appender.D.Threshold = DEBUG
- log4j.appender.D.layout = org.apache.log4j.PatternLayout
- log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
- log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
- log4j.appender.E.File =E://logs/error.log
- log4j.appender.E.Append = true
- log4j.appender.E.Threshold = ERROR
- log4j.appender.E.layout = org.apache.log4j.PatternLayout
- log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
mysql这种关系型数据库,具有强一致性,例如被外键关联的主键无法删除
一、ORM介绍
ORM即Object Relational Mapping:对象关系映射
指的是持久化数据和实体对象的映射模式,为了解决面向对象与关系型数据库存在的不匹配的现象的技术
二、Mybatis框架介绍
- Mybatis是一个基于java的持久层框架,它内部封装了JDBC,使开发者只需要关注SQL本身,而不需要花费精力去处理加载驱动,创建连接等
- 采用XML或者注解的方式将需要执行的各种Statement对象封装起来
- 采用ORM思想,将数据表数据封装到Java对像中
三、Mybatis入门程序
- 第一步:编写实体类 ```java package com.study.domain;
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data//这个注解会加上get/set/toString/equals/hashcode()这些方法 @AllArgsConstructor @NoArgsConstructor @Builder public class Student { private Integer id; private String username; private String password; }
- 第二步:编写映射配置文件(用来编写执行的SQL指定实体类和表之间的映射关系)
```xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="StudentMapper">
<select id="findAll" resultType="com.study.domain.Student">
SELECT * FROM jdbctest
</select>
</mapper>
第三步:编写核心配置文件,引入映射配置文件,配置相关连接信息和其他自定义配置等
<?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="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://182.92.71.236:3306/study"/> <property name="username" value="root"/> <property name="password" value="zhubowenmysql"/> </dataSource> </environment> </environments> <mappers> <mapper resource="studentMapper.xml"/> </mappers> </configuration>
第四步:编写Java代码引入核心配置文件 ```java package com.study;
import com.study.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.InputStream; import java.util.List;
//Mybatis入门测试 public class MybatisTest { public static void main(String[] args) throws Exception{ //org.apache.ibatis.io.Resources他就是Mybatis提供的一个读取配置文件的工具类 //底层也是调用的类加载器的getResourceAsStream,我们也可以自己写 // InputStream resourceAsStream = Resources.getResourceAsStream(“mybatisConfig.xml”); //自定义读取配置文件输入流 InputStream resourceAsStream =MybatisTest.class.getClassLoader().getResourceAsStream(“mybatisConfig.xml”);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<Student> students = sqlSession.selectList("StudentMapper.findAll");
for (Student student : students) {
System.out.println(student);
}
}
}
<a name="fqOjd"></a>
### 四、Mybatis相关API(入门程序中的)
<a name="NaY2l"></a>
#### 4.1Resources
这是Mybatis提供的一个工具类,用来加载配置文件的,底层是通过类加载器调用同样的getResourceAsStream()方法来获取配置文件的输入流<br />
<a name="QGulH"></a>
### 4.2、SqlSessionFactoryBuilder
它是获取SqlSessionFactory工厂类的功能类(通过这个类可以获取SessionFactory工厂),我们执行SQL需要使用的是SqlSession对象,这个对象需要SqlSessionFactory工厂对象获取

<a name="Fe0sd"></a>
#### 4.3、SqlSessionFactory对象
这个对象是用来获取SQLSession对象,类似于JDBC中的Connection对象,同时可以用来开启事务的提交方式<br />
<a name="BUubN"></a>
#### 4.4、SQLSession对象
这个对象是用来执行SQL,管理事务,进行接口代理<br />
<a name="UE0pC"></a>
### 五、Mybatis映射配置文件
**注意:映射配置文件就是用来执行相关SQL语句,并把执行结果封装到实体类中,所以所以映射配置文件需要配置需执行的SQL和表数据和实体类之间的映射关系**
<a name="fykdz"></a>
#### 5.1、映射配置文件介绍(增删改查)
**映射配置文件相关规则:**<br />映射配置文件包含了数据和对象之间的映射关系,以及要执行的SQL语句<br />在映射配置文件中:查询用select标签,新增用insert,修改用update,删除用delete标签<br />通过#{属性名来获取参数},即我们要传递参数到SQL语句中的那个属性名字,这种方式就是JDBC的预编译方式,SQL提前编译好,#{}作为参数传递,可以防止SQL注入攻击,缺点是实现模糊查询很麻烦,需要将参数拼接%<br />${属性名来获取参数},和#{}功能类似,也是取参数放入SQL语句中,但是这种方式是采用字符串拼接的方法,缺点会出现SQL注入攻击,优点是在进行模糊查询的时候,不需要将传递的参数拼接%,直接在SQL语句中拼接<br />我们通过#{}或者${}来获取参数时,一般都是通过${属性名}或者#{属性名},如果参数集是map集合,那么就通过#{key}或者${key}来获取,如果参数的属性是一个对象,那么就通过#{对象属性名.属性名},${...}例如#{user.age}<br />注意:我们在写动态SQL的修改时,需要使用<set>标签,它会自动去掉最后一个逗号
```java
<?xml version="1.0" encoding="utf-8"?><!--xml文件的约束头-->
<!--Mybatis配置文件的DTD约束:有了这个约束,可以进行相关的提示,例如标签写错了,就可以进行报错提示-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--mapper:它是跟标签
namespace:命名空间
-->
<mapper namespace="StudentMapper">
<!--
select标签表示这是查询的功能
id属性,是唯一标识通过namespace+id的方式来找到唯一的SQL语句
resultType:表示结果集对象,是用将查询结果封装到对象中
parameterType:用来执行参数类型
-->
<select id="findAll" resultType="com.study.domain.Student">
SELECT * FROM jdbctest
</select>
<!--查询单个,这里的结果集对象使用别名-->
<select id="findOne" resultType="student" parameterType="java.lang.Integer">
select * from jdbctest where id =#{id}
</select>
<!-- 新增操作-->
<insert id="insert" parameterType="com.study.domain.Student">
insert into jdbctest values(#{id},#{username},#{password})
</insert>
<!-- 修改功能-->
<update id="update" parameterType="com.study.domain.Student">
update jdbctest set username=#{username},password=#{password} where id=#{id}
</update>
<!--修改功能:还可以使用动态SQL写,不为null就修改,这里需要使用<set>标签,它会去掉最后一个逗号-->
<update id="update" parameterType="student">
update jdbctest
<set>
<if test="username!=null">
username=#{username},
</if>
<if test="password!=null">
password=#{password},
</if>
</set>
<where>
id =#{id}
</where>
</update>
<!-- 删除功能-->
<delete id="delete" parameterType="java.lang.Integer">
delete from jdbctest where id=#{id}
</delete>
</mapper>
package com.study;
import com.study.domain.Student;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
public class MybatisTestOne {
private SqlSession sqlSession;
@Before
public void getSqlSession(){
InputStream resourceAsStream = MybatisTestOne.class.getClassLoader().getResourceAsStream("mybatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void test(){
//加载核心配置文件
Student student = sqlSession.selectOne("StudentMapper.findOne", 1);
System.out.println(student);
sqlSession.close();
}
@Test
public void testInsert(){
Student student = new Student();
student.setId(9);
student.setUsername("mybatis");
student.setPassword("test");
int insert = sqlSession.insert("StudentMapper.insert", student);
//提交事务
sqlSession.commit();
System.out.println(insert);
sqlSession.close();
}
@Test
public void testUpdate(){
Student student = new Student();
student.setId(9);
student.setUsername("朱博文");
student.setPassword("你好");
sqlSession.update("StudentMapper.update",student);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testDeleteFrom(){
sqlSession.delete("StudentMapper.delete",9);
sqlSession.commit();
sqlSession.close();
}
}
5.2、核心配置文件的介绍
注意:Mybatis核心配置文件,不同的配置上下是有顺序的
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">
<!--mybatis的根标签:-->
<configuration>
<!-- 引入外部配置文件-->
<properties resource="dev/jdbc.properties"/>
<!-- typeAliases 起别名-->
<typeAliases>
<!-- typeAlias给单个类起别名,type表示给那个类起别名,alias表示别名 -->
<!-- <typeAlias type="com.study.domain.Student" alias="student"/>-->
<!-- package表示给指定路径下所有类起别名:name属性表示具体路径-->
<package name="com.study.domain"/>
<!---->
</typeAliases>
<!-- 用来指定数据库环境
数据库环境可以配置多个,通过default这个属性来引入使用那个环境
-->
<environments default="mysql">
<!--
environment:是用来配置数据环境的,可以配置多个,id就是唯一标识-->
<environment id="mysql">
<!--transactionManager:用来配置事务的管理,type=JDBC表示使用JDBC事务管理-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource代表数据源信息,是用来配置数据库连接的:type值为POOLED表示使用连接池)-->
<dataSource type="POOLED">
<!-- property:表示配置数据库连接信息-->
<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子标签来进行引入-->
<mappers>
<mapper resource="studentMapper.xml"/>
</mappers>
</configuration>
对于Mybatis也有自带的别名供我们使用
5.3mybatis整合log4j来打印执行的SQL
Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具:
SLF4J
Apache Commons Logging
Log4j 2
Log4j
JDK logging
具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序查找)。 如果一个都未找到,日志功能就会被禁用。
不少应用服务器的classpath中已经包含Commons Logging,如Tomcat和WebShpere, 所以MyBatis会把它作为具体的日志实现。记住这点非常重要。这将意味着,在诸如 WebSphere的环境中——WebSphere提供了Commons Logging的私有实现,你的Log4J配置将被忽略。 这种做法不免让人悲催,MyBatis怎么能忽略你的配置呢?事实上,因Commons Logging已经存 在了,按照优先级顺序,Log4J自然就被忽略了!
具体使用
- 导入log4j的jar包,
- 配置log4j的配置文件
```xml
设置
log4j.rootLogger = debug,stdout,D,E输出信息到控制抬
log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
输出DEBUG 级别以上的日志到=E://logs/error.log
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
输出ERROR 级别以上的日志到=E://logs/error.log
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
- 这核心配置文件中配置 加入settings配置,settings是用来配置Mybatis运行时行为 的,比如配置缓存,配置延迟加载等
```xml
<settings>
<!-- 配置日志打印-->
<setting name="logImpl" value="LOG4J"/>
</settings>
六、Mybatis接口代理方式开发dao层
对于传统的Dao层,我们需要写接口进行约束,然后在写实现类,对于Mybatis我们只写接口,具体的实现类由Mybatis提供
要想实现接口代理方式,必须实现以下规则:
- 映射配置文件中的命名空间必须和接口的全类名一致
- 映射配置文件中增删改查标签的id值必须和接口中的方法名相同
- 映射配置文件中的parameterType属性值必须和Dao层接口方法中的参数类型相同
- 映射配置文件中的ResultType属性必须和Dao层接口方法的返回值类型相同
代码演示:
映射配置文件(核心配置文件一定要引入映射配置文件)
<?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.study.dao.PersonDao">
<select id="findAll" resultType="com.study.domain.Person">
select * from jdbctest
</select>
<select id="findById" parameterType="java.lang.Integer" resultType="com.study.domain.Person">
select * from jdbctest where id =#{id}
</select>
</mapper>
dao层接口
package com.study.dao;
import com.study.domain.Student;
import java.util.List;
public interface PersonDao {
List<Student> findAll();
Student findById(Integer id);
}
测试类
package com.study;
import com.study.dao.PersonDao;
import com.study.domain.Person;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.InputStream;
//测试Mybatis接口代理方式开发Dao层
public class InterfaceProxyTest {
@Test
public void testFindAll(){
//加载核心配置文件
InputStream rs = InterfaceProxyTest.class.getClassLoader().getResourceAsStream("mybatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(rs);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取接口代理实现类对象
PersonDao mapper = sqlSession.getMapper(PersonDao.class);
mapper.findAll();
sqlSession.close();
}
}
我们在使用接口代理开发时,需要在核心配置文件通过
七、源码分析:动态代理对象时如何生成
Mybatis通过动态代理的方式产生代理对象,底层使用的JDK动态代理来产生代理对象
方法执行源码分析:
代理对象底层最终调用的是mapperMethod.excute()方来执行,这个方法里面通过switch语句更据操作的类型最终来判断是调用什么方法,最终调用还是JDBC中SqlSession中的原生方法来执行SQL
八、Mybatis实现动态SQL
有的时候我们查询条件不同,需要执行的SQL也不同,这个 时候针对不同的条件需要写不同的SQL很麻烦,我们可以使用动态SQL的方式实现,根据查询条件的不同,产生的查询SQL也不同
8.1动态SQL标签
1.
2.
查询条件拼接,
如果条件满足,那么就会将if标签里的条件拼接到SQL语句中
<select id="findByIds" parameterType="java.lang.Integer" resultType="com.study.domain.Person">
select * from jdbctest
<where>
<if test="id !=null">
id=#{id}
</if>
<if test="name !=null">
name=#{name}
</if>
</where>
</select>
3.foreach标签
如果条件是一个list集合或者数组是,需要遍历,将结果拼接到SQL语句中,这个时候需要Foreach标签
collection=参数的集合容器:如果参数在集合中用list,如果参数在数组中用array
open表示遍历之前拼接的SQL,必须使用 id in(1,2,3)那么open就需要填id in (
close表示遍历条件结束后需要拼接,一般拼接)
item表示集合中取出每个元素需要的变量,我们在
separator:表示分割符,即遍历集合中的元素在SQL中使用什么分隔符分割
select * from jdbctest
<where>
<foreach collection="list" open="id in(" close=")" item="param" separator="," >
#{param}
</foreach>
</where>
它就相当于select * from jdbctest where id in(1,2,3)
4.
通过
<sql id="test">select * from jdbctest</sql>
<include refid="test"/> where id =#{id}
九、MyBatis分页插件
Mybatis支持引入第三方的插件使用,需在核心配置文件中配置
步骤:
第一步:导入jar包(这是第三方提供的)
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.8</version> </dependency>
第二步:在核心配置文件中配置:这个配置需要在起别名下方配置
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
第三步:使用API进行分页操作
在需要执行分页的查询的SQL上面添加PageHelper.startPage(1,3)这个方法,这个分页不同于SQL语句的分页,这个分页第一页就是1,它是从1开始,
//查询第一页,每页显示3条数据
PageHelper.startPage(1,3);
mapper.findAll();
- 第四步:获取分页参数
通过上面的方法,我们执行SQL的查询结果就会被分页,我们通过创建PageInfo对象,可以获取相关的分页参数
//进行分页查询查询第一页,每页显示3条数据
PageHelper.startPage(1,3);
List<Person> list=mapper.findAll();
//分装分页结果:这个里的PageInfo泛型写我们查询结果的泛型,构造器传入查询的结果
//就可以创建我们的分页对象,通过分页对象就可以获取相关的分页参数了
PageInfo<Person> personPageInfo = new PageInfo<Person>(list);
十、Mybatis多表查询
Mybatis的多表查询,体现在查询结果的封装上,例如:我们进行一对一查询,一个类的对象作为另一个类的属性出现,那么这个属性我也需要将查询的结果封装进去,使用Mybatis就可以实现这一功能,也是就我们需要resultMap手动的配置映射关系即可
resultMap是用来配置映射关系,即当查询结果列名和对象属性名不一致时
10.1、多表关系的建立规则
一对一:在任意一方建立外键关联另一方主键,在Java中体现在一个类对象作为另一个类的属性出现
一对多:在多的一方建立外键关联一的一方主键,在java中体现在多的一方对象的List集合作为一的一方的属性
多对多:使用中间表,通过中间表外键关联两边主键
10.2一对一多表查询:
package com.study.domain;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private Integer id;
private String name;
private Card card;
}
public class Card {
private Integer id;
private Integer pid;//外键
}
<!--
resultMap:用来指定映射关系(当数据库了列名和类属性名不一致时需要使用resultMap)
id:表示唯一标识,供其他查询结果集进行引用,type表示封装的数据类型(即将结果封装成给那个类)
-->
<resultMap id="test" type="person">
<!--id标签用来指定主键映射关系,column表示查询结果中主键的列名,property表示封装给类的那个属性 -->
<id column="pid" property="id"/>
<!--result标签用来封装非主键的列,column表示查询结果的列名,property表示封装给类的那个属性-->
<result column="pname" property="name"/>
<!--association这个标签是用来给类的属性对象赋值,property表示对象的属性名,javaType表示对象的类型-->
<association property="card" javaType="com.study.Card">
<!-- 这里面的标签和resultMap里的用法相同-->
<id column="cid" property="id"/>
<result column="cname" property="name"/>
<result column="cid" property="cid"/>
</association>
</resultMap>
<!-- 由于结果既包含多个对象属性,他们之间有重名的,所以需要resultMap来指定映射关系
同时类的属性是个对象,我们需要resultMap里面进行对象的封装
-->
<select id="findById" parameterType="java.lang.Integer" resultMap="test">
select p.id pid,p.name pname,c.id cid,c.name cname from person p,card c where p.id=c.pid and p.id=#{id};
</select>
总结:一对一查询,由于查询结果的字段和对象属性名一致,所以我们需要resultMap进行执行映射关系,与此同时,我们还需要给查询结果的实体类的属性是对象类型的类赋值,这个时候就需要使用
10.3、一对多表查询
package com.study.domain;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private Integer id;
private String name;
private List<Sun> sunList;
}
public class Sun {
private Integer id;
private Integer pid;//外键
}
<!--
一对多的查询封装,和一对一的差不多,也是因为结果和属性值不同,需要使用resultMap指定映射关系
-->
<resultMap id="oneToMany" type="com.study.Person">
<id column="pid" property="id"/>
<result column="pname" property="name"/>
<!--这里封装对象的属性,但是这个属性是一个List集合,所以不能使用association标签,需要使用collection
标签,给属性是集合的对象进行封装结果
collection的属性1:property它是要封装的集合对象在类中的属性的变量名
属性2:ofType表示集合的泛型类型
-->
<collection property="sunList" ofType="sun">
<!-- 这里配置的映射关系就和resultMap里一样了-->
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="spid" property="pid"/>
</collection>
</resultMap>
<select id="selectAll" parameterType="java.lang.Integer" resultMap="oneToMany">
select p.id pid,p.name pname ,s.id sid,s.name sname,s.pid spid from person p,sun s where p.id=s.pid;
</select>
总结:一对多的封装和一对一的封装差不多,只是在给集合属性指定映射关系是使用的是
10.4、多对多
对于多对多,站在一方看还是一对多,所以他查询结果的封装和一对多是一样的
十一、mybatis注解开发
注意:我们使用注解开发多表操作时,都是使用单表查询,即我们mapper层接口上的查询都是查询单张表的数据,然后通过column这个属性来指定查询这个表的关联列(同时也会传递参数),然后通过one=@One或者many=@Many来应用其他mapper层接口的查询方法(这里的方法要写全路径),多表查询Mapper层接口上就是查询单张表一个中间表
11.1、常用的单表操作的注解
注解开发,SQL语句中使用EL表达式从方法形参中取值#{形参名}
基于注解开发步骤:
- 第一步:提供mapper层接口
在接口上通过注解写SQL语句 ```java public interface StudentMapper { //查询全部 @Select(“SELECT * FROM student”) public abstract List
selectAll(); //新增操作 @Insert(“INSERT INTO student VALUES (#{id},#{name},#{age})”) public abstract Integer insert(Student stu);
//修改操作 @Update(“UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}”) public abstract Integer update(Student stu);
//删除操作 @Delete(“DELETE FROM student WHERE id=#{id}”) public abstract Integer delete(Integer id); }
- 在核心配置文件中添加包扫描扫描到Mapper层接口
```xml
<mappers>
<!--这里原来是引入映射配置文件的,但是我们使用注解开发,这里添加的就是Mapper层接口路径-->
<package name="com.study.mapper"/>
</mappers>
11.2、多表操作常用注解
//一对一
@Results:封装映射关系的父注解。//用来封装结果集
Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。//用来执行映射关系
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
javaType 属性:被包含对象的数据类型
one 属性:一对一查询固定属性
@One:一对一查询的注解。
select 属性:指定调用某个接口中的方法
//一对多
@Results:封装映射关系的父注解。
Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
javaType 属性:被包含对象的数据类型
many 属性:一对多查询固定属性
@Many:一对多查询的注解。
select 属性:指定调用某个接口中的方法
//多对多:多对多和一对多是一样的
@Results:封装映射关系的父注解。
Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
javaType 属性:被包含对象的数据类型
many 属性:一对多查询固定属性
@Many:一对多查询的注解。
select 属性:指定调用某个接口中的方法
11.3注解开发多表操作—-一对一
public interface CardMapper {
//查询全部
@Select("SELECT * FROM card")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "number",property = "number"),
@Result(
property = "p", // 被包含对象的变量名
javaType = Person.class, // 被包含对象的实际数据类型
column = "pid", // 根据查询出的card表中的pid字段来查询person表
/*
one、@One 一对一固定写法
select属性:指定调用哪个接口中的哪个方法
*/
one = @One(select = "com.itheima.one_to_one.PersonMapper.selectById")
)
})
public abstract List<Card> selectAll();
}
11.4、注解开发多表操作—-一对多
public interface ClassesMapper {
//查询全部
@Select("SELECT * FROM classes")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(
property = "students", // 被包含对象的变量名
javaType = List.class, // 被包含对象的实际数据类型
column = "id", // 根据查询出的classes表的id字段来查询student表
/*
many、@Many 一对多查询的固定写法
select属性:指定调用哪个接口中的哪个查询方法
*/
many = @Many(select = "com.itheima.one_to_many.StudentMapper.selectByCid")
)
})
public abstract List<Classes> selectAll();
}
11.5、注解开发多表操作——多对多
public interface StudentMapper {
//查询全部
@Select("SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(column = "age",property = "age"),
@Result(
property = "courses", // 被包含对象的变量名
javaType = List.class, // 被包含对象的实际数据类型
column = "id", // 根据查询出student表的id来作为关联条件,去查询中间表和课程表
/*
many、@Many 一对多查询的固定写法
select属性:指定调用哪个接口中的哪个查询方法
*/
many = @Many(select = "com.itheima.many_to_many.CourseMapper.selectBySid")
)
})
public abstract List<Student> selectAll();
}
十二、Mybatis的构建SQL语句
对于注解开发,我们都是通过硬编码的形式写在注解里的,这是一种方式,mybatis还提供了一种构建SQL的方式,就是通过API的方式
即通过调用方法来拼接SQL语句,我们可以自定义拼接SQL的方法,然后通过注解来替换以前的注解
3.2 查询功能的实现
- 定义功能类并提供获取查询的 SQL 语句的方法。
@SelectProvider:生成查询用的 SQL 语句注解。//使用这个注解来替换@Select这个注解
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法3.3 新增功能的实现
定义功能类并提供获取新增的 SQL 语句的方法。
@InsertProvider:生成新增用的 SQL 语句注解。 //使用这个注解来替换@Insert注解
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法3.4 修改功能的实现
定义功能类并提供获取修改的 SQL 语句的方法。
@UpdateProvider:生成修改用的 SQL 语句注解。 //使用这个注解来替换@Update注解
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法3.5 删除功能的实现
定义功能类并提供获取删除的 SQL 语句的方法。
- @DeleteProvider:生成删除用的 SQL 语句注解。 //使用这个注解来替换@Delete注解
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法