Mybatis3-入门 [toc]
0、资料 视频:
书:
博客:
1、Mybatis 概述 Mybaits3 也就是 ibatis3。Mybatis是一个持久层的框架。
为什么使用 Mybatis ?
Mybatis 是半自动的持久层框架
JDBC硬编码,耦合度高
Hibernate 和 JPA,全自动框架,对复杂的SQL语句也不好处理
Mybatis 官网地址: MyBatis 3 -官方文档-中文
Mybatis 下载地址: https://github.com/mybatis/mybatis-3/releases
原生的接口式编程:Dao =》 DaoImpl
Mybatis口式编程: Dao =》 dao接口的XML映射配置文件
注意:
配置文件的提示:XML中引入DTD约束
SqlSession使用完后必须手动关闭
SqlSession 和 Connection 一样,都是 非线程安全 的,每次使用都应该重新获取对象
Mybatis不用写Dao的实现类,Mybatis会根据XML映射配置文件 生成代理对象
SqlSession.getMapper(UserDao.class) 得到的是代理对象
1.1、 初次使用Mybatis-案例 实体类-User:
1 2 3 4 5 6 7 8 9 package com.beans;public class User { private int uid; private String username; private String pwd; private int money; }
Dao接口-UserDao:
1 2 3 4 5 6 7 8 9 10 11 package com.dao;import org.apache.ibatis.annotations.Select;import com.beans.User;public interface UserDao { public User getUser (int uid) ; }
全局配置文件:app.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?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.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/springstudy" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </dataSource > </environment > </environments > // 注册Dao接口的映射配置文件 <mappers > <mapper resource ="com/conf/UserMapper.xml" /> </mappers > </configuration >
Dao接口的映射配置文件【注解版】:UserMapper
1 2 3 4 5 6 7 8 9 10 <?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 标签内,如果使用注解来执行SQL,则不用写SQL语句的标签;否则,写 <mapper namespace ="com.dao.UserDao" > </mapper >
Dao接口的映射配置文件【XML版】:UserMapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?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 标签内,如果使用注解来执行SQL,则不用写SQL语句的标签;否则,写 // select标签中, // - id :方法名, // - resultType :返回值类型 // - #{} :形参,SQL语句的占位符 <mapper namespace ="com.dao.UserDao" > <select id ="getUser" resultType ="com.beans.User" > select * from user where uid = #{uid} </select > </mapper >
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import java.io.*;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.*;import com.beans.User;import com.dao.UserDao;public class Test { public static void main (String[] args) { try { InputStream in = Resources.getResourceAsStream("app.xml" ); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); SqlSession session = sqlSessionFactory.openSession(); UserDao dao = session.getMapper(UserDao.class); User user = dao.getUser(1 ); System.out.println(user); } catch (IOException e) { e.printStackTrace(); }finally { session.close(); } } }
1.2、Maven-POM配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <?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.cyw</groupId > <artifactId > SSM-01</artifactId > <version > 1.0-SNAPSHOT</version > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > <scope > test</scope > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.26</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.9</version > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > 1.16.14</version > </dependency > </dependencies > <properties > <maven.compiler.source > 8</maven.compiler.source > <maven.compiler.target > 8</maven.compiler.target > </properties > <build > <plugins > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-surefire-plugin</artifactId > <configuration > <testFailureIgnore > true</testFailureIgnore > </configuration > </plugin > </plugins > </build > </project >
1.3、Mybatis 的几个对象
SqlSessionFactoryBuilder对象:创建完SqlSessionFactory对象后就没用了。
SqlSessionFactory对象:一般设为单例模式
SqlSession对象:线程不安全,每次用完要手动关闭。
2、Mybatis 全局配置文件 Mybatis 全局XML配置文件是为了注册信息【也可以通过new配置对象的方法】,包括:
环境信息【数据库、事务管理器】
dao接口的映射配置文件的信息
Mybatis 全局XML配置文件中的标签顺序是有规定的,具体顺序见官网。
mybatis-config.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?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属性:指定当前使用哪种环境 <environments default ="development" > <environment id ="development" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="com.mysql.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/springstudy" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </dataSource > </environment > </environments > // 指定Dao接口的映射配置文件的路径【必选】 <mappers > <mapper resource ="com/conf/UserMapper.xml" /> // 或者直接在DAO接口上使用注解写SQL,然后再全局配置中注册接口 // <mapper class ="com.dao.UserDao" /> </mappers > </configuration >
2.1、 properties标签 Mybatis可以使用properties标签
来引入外部的properties文件 中的配置【一般是数据库配置信息】。
一般配置文件由Spring来导入,所以Mybatis的数据库配置不常用。
properties标签
的两个属性:
resource:引入类路径 下的配置
url:引入网络路径 下的配置
例如:
外部properties配置文件-db.properties:
1 2 3 4 jdbc.driver =com.mysql.jdbc.Driver jdbc.url =jdbc:mysql://localhost:3306/springstudy jdbc.username =root jdbc.password =root
全局配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?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 ="com/conf/db.properties" > </properties > // 配置信息 <environments default ="development" > <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 > </environment > </environments > <mappers > <mapper class ="com.dao.UserDao" /> </mappers > </configuration >
2.2、数据表的属性名由下划线转驼峰 在Mybatis的全局配置文件中,使用mapUnderscoreToCamelCase
,该配置是在 settings 标签
的setting子标签
中设置的。【 settings 标签 中只能放 setting 标签 】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?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 > // 全局设置 <settings > // 开启:自动将数据库的属性名由 下划线 转 驼峰 <setting name ="mapUnderscoreToCamelCase" value ="true" /> </settings > // 配置信息 <environments default ="development" > <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 > </environment > </environments > // dao接口的映射配置文件 <mappers > <mapper class ="com.dao.UserDao" /> </mappers > </configuration >
2.3、配置全类名的别名 注意:
别名不区分大小写
Mybatis内置了一部分别名【基本数据类型、包装类、集合类型、日期类型】
typeAliases
标签可以用来设置多个类的别名。
给单个类取别名(1):
<typeAlias alias="别名" type="全类名"/>
是一个别名处理器,可以给全类名设置别名,方便程序员写全类名.
typeAliases标签
的alias属性
默认就是类名的小写
。
给单个类取别名(2):
在dao接口上(或者某个需要设置别名的类上)使用注解(@Alias("别名")
)。
此方式可以在批量取别名 的方式出现别名冲突时 使用。
给一个包中的全部类取别名(批量取别名):
<package name="包名"/>
可以给当前包以及子包 的全部类取一个默认别名 (默认别名格式:类名小写)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <?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 > // 给全类名取别名 <typeAliases > <typeAlias type ="com.entity.User" /> <typeAlias alias ="Book" type ="com.entity.Book" /> <package name ="包名" /> </typeAliases > // 全局设置 <settings > // 开启:自动将数据库的属性名由 下划线 转 驼峰 <setting name ="mapUnderscoreToCamelCase" value ="true" /> </settings > // 配置信息 <environments default ="development" > <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 > </environment > </environments > // dao接口的映射配置文件 <mappers > <mapper class ="com.dao.UserDao" /> </mappers > </configuration >
2.4、类型处理器 typeHandlers
的作用:建立Java类型 与数据库类型 的桥梁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <?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 > <typeHandlers > <package name ="com.cyw.Example" /> </typeHandlers > // 给全类名取别名 <typeAliases > <typeAlias type ="com.entity.User" /> <typeAlias alias ="Book" type ="com.entity.Book" /> <package name ="包名" /> </typeAliases > // 全局设置 <settings > // 开启:自动将数据库的属性名由 下划线 转 驼峰 <setting name ="mapUnderscoreToCamelCase" value ="true" /> </settings > // 配置信息 <environments default ="development" > <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 > </environment > </environments > // dao接口的映射配置文件 <mappers > <mapper class ="com.dao.UserDao" /> </mappers > </configuration >
2.4、插件简介 插件可以拦截以下Mybatis的四大对象的一些方法。
四个对象:
StatementHandler
ParamterHandler
ResultSetlHandler
Executor
2.5、多个环境的配置 environments
标签,可以包括多个environment
标签,并利用id属性
指定一个默认使用的环境,每个环境必须要配置事务管理器 和数据源 。
一般使用Spring来做事务控制,所以Mybatis的事务管理器仅做了解 。
transactionManager
的type属性的取值:【jdbc
| managed
| 自定义的事务管理器】
dataSource
的type属性的取值:【pooled
| unpooled
| jndi
| 自定义的数据源】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <?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.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/springstudy" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </dataSource > </environment > <environment id ="test" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="com.mysql.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/springstudy" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </dataSource > </environment > </environments > <mappers > <mapper class ="com.dao.UserDao" /> </mappers > </configuration >
2.6、支持不同厂商的数据库 databaseIdProvider
标签,可以让 Mybatis 支持不同厂商的数据库。
步骤:
在全局配置文件
中,配置databaseIdProvider
标签
在dao接口的映射配置文件
中,SQL语句标签的databaseId属性
设为全局配置文件中厂商property标签的value属性的值
全局配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <?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 > // 数据库厂商 <databaseIdProvider type ="DB_VENDER" > <property name ="MySQL" value ="mysql" /> <property name ="Oracle" value ="oracle" /> <property name ="SQL Server" value ="sqlserver" /> </databaseIdProvider > // 环境 <environments default ="development" > <environment id ="development" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="com.mysql.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/springstudy" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </dataSource > </environment > </environments > <mappers > <mapper class ="com.dao.UserDao" /> </mappers > </configuration >
映射配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?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.dao.UserDao" > <select id ="getUser1" resultType ="com.beans.User" databaseId ="mysql" > select * from user where uid = #{uid} </select > <select id ="getUser1" resultType ="com.beans.User" databaseId ="sqlserver" > select * from user_tb where uid = #{uid} </select > </mapper >
3、Mybatis 映射配置文件 Mybatis 映射配置文件【必须要有,除非使用注解方式且已在mapper标签中注册接口】
映射配置文件中,方法的返回值:
Mybatis的增删改 方法要想由返回值可直接在方法的返回值,无需像查询一样单独定义返回值属性。
映射配置文件中,方法传参:
方法传参可以直接使用全类名,SQL语句中的参数占位符可以使用#{JavaBean中的属性名}
1 2 3 <select id ="getUserByUid" resultType ="com.entity.User" > select * from user where uid = #{uid} </select >
映射配置文件中,主键自增:
MySQL支持自增主键,Mybatis利用了原生JDBC中的Statement对象的statement.getGeneratedKeys()方法,
制作了一个属性useGeneratedKeys
,默认值为false(关闭主键自增策略),配合keyProperty
属性使用(指定Mybatis获取自增主键后,赋值给JavaBean的哪个属性)
UserMapper.xml:
1 2 3 4 <insert id ="addUser" parameterType ="com.entity.User" useGeneratedKeys ="true" keyProperty ="uid" > insert into user values(#{uid},#{username},#{pwd},#{money}); </insert >
Oracle不支持自增主键,则使用序列来模拟自增,每次插入的数据的主键是从序列中拿到的值,insert标签内配合selectKey
标签。
3.1、增删改查-案例 bean:
1 2 3 4 5 6 7 package com.entity;public class User { private int uid; private String username; private String pwd; private int money; }
mybatis-conf.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?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.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/springstudy" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="com/conf/UserMapper.xml" /> </mappers > </configuration >
UserMapper.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?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.dao.UserDao" > // 查询 <select id ="getUserByUid" resultType ="com.entity.User" > select * from user where uid = #{uid} </select > // 插入 <insert id ="addUser" parameterType ="com.entity.User" > insert into user values(#{uid},#{username},#{pwd},#{money}); </insert > // 更新 <update id ="updateUser" parameterType ="com.entity.User" > update user set username=#{username},pwd=#{pwd},money=#{money} where uid=#{uid} </update > // 删除 <delete id ="delUser" > delete from user where uid=#{uid} </delete > </mapper >
3.2、方法参数的处理
单个参数:
#{}
,不会做任何处理,直接传值(参数名随便写都一样)
例如:public User getUser(int uid)
多个参数:【待定,测试时无法使用】
会做处理,多个参数会被封装为一个Map集合,#{}
就是取Map中指定的Key的值。
在封装参数Map
时,key就是 param1
到 paramn
(或参数的索引号),value才是用户真正传入的参数值。
public User getUser(int uid,String username)
命名参数:
需要明确封装参数Map的Key,即:在接口的方法的参数前使用注解@Param("参数Map的键名")
1 2 3 4 5 6 7 8 9 package com.dao;import org.apache.ibatis.annotations.Param;import com.entity.User;public interface UserDao { public User getUserByUid (int uid) ; public User getUser (@Param("uid") int uid,@Param("username") String username) ; }
参数为Collcetion集合或数组的处理:
参数为Collcetion集合或数组时,即使只有一个参数,也会将参数封装为Map。
参数Map的Key键为:
Collection:collection
List:list
数组:array
1 2 3 #{list[0]} #{collection[0]} #{array[0]}
小结1(应用场景):
但参数时,参数命名无所谓。
如果传入的参数很多,且是业务数据模型 ,可以用传入JavaBean对象 的方式来代替。
如果传入的参数很多,但不是业务数据模型 ,不经常使用,可以用传入Map集合 的方式来代替。
如果传入的参数很多,但不是业务数据模型 ,经常使用,可以用传入TO数据传输对象 的方式来代替(如:分页对象)。
小结2(应用方式):
当参数过多时,为了不混乱,可以在dao接口的参数前加上@Param("map参数名")
来封装使用的参数map的key,使用#{key名}
就可以取出参数map中指定的key所对应的value。
${}
与#{}
来取值的区别:
#{}
:采用预编译的形式,将参数设置到SQL语句中,类似JDBC中的 preparedStatement
${}
:直接取值,类似JDBC中的Statement
大多数情况下应该使用#{}
,但在原生JDBC不支持占位符的地方 可以使用${}
(如:sql语句中的表名、排序的字段名、排序顺序)
#{}
取值方式的丰富的规则:
规定了参数的一些规则:
javaType、jdbcType、mode(存储过程)、numericScale、resultMap、typeHandler、jdbcTypeName、expression
javaType通常在数据为null的情况下被设置【有些数据库,如Oracle无法识别mybatis对null值的默认处理】
1 2 // 在映射配置文件中的SQL语句处 #{email,jdbcType=NULL}
3.3、resultMap 标签(关系映射) resultMap标签的作用 :定义结果集的封装规则。
步骤:
1、先在映射配置文件中利用 resultMap
标签自定义JavaBean的封装规则,resultMap
标签的type
属性用来绑定某个已知的JavaBean的全类名,id
属性作为唯一标识。
2、resultMap
标签指定主键(标签内)<id column="数据表的列名" property="javabean的属性名"/>
,<result column="数据表的列名" property="javabean的属性名"/>
指定数据表的普通属性的封装,如果没有手动指定result 子标签,则自动封装。
3、association、collection
两个子标签用于指定关联属性(类型为类的属性),property
的值为JavaBean的属性名,javaType
的值为类型的全类名(association 子标签
),select
属性的值为另一个Dao接口中的方法的全类名,column
属性的值为数据表中将值传给方法的列,ofType
属性的值为集合中元素的类型的全类名(collection 子标签
)。
discriminator
子标签:鉴别器,属性column
的值为数据表的列,属性javaType
的值为列所对应的 java类型
关系映射:
一对一(association 子标签
):【类A有一个类B的属性】类A的映射配置文件中,association子标签的select属性绑定类B的Dao接口的查询方法,该查询方法的返回值为一个对象。(两个类的关联属性是一个2 类型)
一对多(collection 子标签
):【类A有一个类B的属性,且是集合类型】类A的映射配置文件中,association子标签的select属性绑定类B的Dao接口的查询方法,该查询方法的返回值为一个集合。(两个类的关联属性是一个集合 类型)
多对多(两个实体类都使用collection 子标签
):【类A有一个类B的属性,且是集合类型,类B有一个类A的属性,且是集合类型】类A的映射配置文件中,association子标签的select属性绑定类B的Dao接口的查询方法,该查询方法的返回值为一个集合。类B的映射配置文件中,association子标签的select属性绑定类A的Dao接口的查询方法,该查询方法的返回值为一个集合。(两个类各自有一个关联属性,且各自是一个集合 类型)
关系映射在编写 association 标签的时候主要有 嵌套结果 和 嵌套查询 两种:
嵌套结果【多表关联的语句在SQL里写】:property + javaType
嵌套查询【多表关联的语句在各自的接口里写】:property + javaType + column + select
小结:
通用:
column : 数据表的列名
property:javabean的属性名
javaType: javabean的全类名(javaBean属性的类型)
fetch-Type: 懒加载【lazy(默认) | eager】
【嵌套查询】:
id子标签:用于定义主键的映射关系
result子标签:用于定义其他属性的映射关系
discriminator子标签:使用结果值来决定使用哪个resultMap
【嵌套结果】:
select: “查询”方法的全类名
column: 数据表的列名
property : select 属性的查询结果传给property属性绑定的 javaBean属性
【一对一】:association
标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // 【嵌套结果的方式】 // com.cyw.dao.StuMapper接口 <resultMap id ="StuRst" type ="com.cyw.po.Stu" > <id property ="sid" column ="id" /> <result property ="name" column ="name" /> <result property ="sex" column ="sex" /> <association property ="card" column ="cardId" javaType ="com.cyw.po.StuCard" > <id property ="id" column ="id" /> <result property ="code" column ="code" /> </association > </resultMap > <select id ="getStuBySid" resultMap ="StuRst" > select stu.* ,stuIdCard.code from stu,stuIdCard where stu.id = #{sid} and stu.id = stuIdCard.id; </select >
【一对多】:collection
标签(在一 的那方的映射配置文件中使用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // 【嵌套结果的方式】 // com.cyw.dao.ClassesMapper <resultMap id ="classesRst" type ="com.cyw.po.Classes" > <id property ="cid" column ="cid" /> <result property ="cname" column ="cname" /> <collection property ="stuList" javaType ="list" ofType ="com.cyw.po.Stu" > <id property ="sid" column ="id" /> <result property ="name" column ="name" /> <result property ="sex" column ="sex" /> <association property ="card" column ="cardId" javaType ="com.cyw.po.StuCard" > <id property ="id" column ="id" /> <result property ="code" column ="code" /> </association > </collection > </resultMap > <select id ="getClassesByCid" resultMap ="classesRst" > select classes.*,stu.*,stuIdCard.`code` from classes,stu,stuIdCard where classes.id = #{cid} and stu.cid = classes.id and stu.cardId = stuIdCard.id; </select >
【多对多】:collection
标签(在双方 的映射配置文件中都要使用,用法类似一对多)
一对一_示例::
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 <?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.dao.UserDao" > // 自定义JavaBean类型【嵌套查询】 <resultMap id ="myUser" javaType ="com.entity.User" > // column : 数据表的列名 // property:javabean的属性名 // javaType: javabean的全类名(javaBean属性的类型) // fetch-Type: 懒加载【lazy(默认) | eager】 <id column ="uid" property ="uid" /> <result column ="username" property ="username" /> <result column ="pwd" property ="pwd" /> <result column ="money" property ="money" /> <association property ="dept" javaType ="com.entity.Dept" > <id column ="deptId" property ="deptId" /> <result column ="deptName" property ="deptName" /> </association > <discriminator javaType ="string" column ="sex" > <case value ="0" resultType ="myUser" > // ... </case > <case value ="1" resultType ="myUser" > // ... </case > </discriminator > </resultMap > // 自定义JavaBean类型【嵌套结果】 <resultMap id ="myUser" javaType ="com.entity.User" > <id column ="uid" property ="uid" /> <result column ="username" property ="username" /> <result column ="pwd" property ="pwd" /> <result column ="money" property ="money" /> // select: “查询”方法的全类名 // column: 数据表的列名 // property: select属性的查询结果交给property指定的javaBean属性 <association property ="dept" select ="com.entity.DeptDao.getDeptByDeptId" column ="dept" > </association > </resultMap > <select id ="getUserByUid1" resultMap ="myUser" > select * from user where uid = #{uid} </select > </mapper >
一对多_示例::
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <resultMap type ="com.entity.User" id ="myUser" > // column : 数据表的列名 // property:javabean的属性名 // javaType: javabean的全类名(javaBean属性的类型) // fetch-Type: 懒加载【lazy(默认) | eager】 <id column ="uid" property ="uid" /> <result column ="username" property ="username" /> <result column ="pwd" property ="pwd" /> <result column ="money" property ="money" /> <collection property ="deptList" ofType ="com.entity.Dept" > <id column ="deptId" property ="deptId" /> <result column ="deptName" property ="deptName" /> </collection > </resultMap >
3.4、select标签 1、返回值类型(resultType属性) 一般情况下:
使用 别名 或 全类名。
返回 List 时:
如果方法的返回值为List
集合,则 select
标签的 resultType
类型应该写List集合中元素的类型
1 2 3 4 5 6 7 8 9 10 11 // dao接口中的方法: public List getUserLikeName(@Param("username") String username); // UserMapper.xml <select id ="getUserLikeName" resultType ="com.entity.User" > select * from user where username like #{username} </select > // 测试 List<User > </User > users = dao.getUserLikeName("%李%"); System.out.println(users);
返回Map 时:
如果方法的返回值为Map
集合,则 select
标签的 resultType
类型应该写map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 // dao接口中的方法:【一条记录封装为map】 public Map getUserByUid(@Param("uid") int uid); // UserMapper.xml <select id ="getUserByUid" resultType ="map" > select * from user where uid = #{uid} </select > // 测试 Map user = dao.getUserByUid(1); System.out.println(user); =================================================== // dao接口中的方法:【多条记录封装为map】 // 告诉Mybatis使用哪个属性作为主键 @MapKey("uid") public Map<Integer,User> getUserLike(@Param("username") String username); // UserMapper.xml <select id ="getUserLike" resultType ="map" > select * from user where username like #{uid} </select > // 测试 Map user = dao.getUserLike("%李%"); System.out.println(users);
2、返回值类型(resultMap属性) 引用 resultMap 标签
所定义的结果集映射规则,具体见上面的3.3小节
的 ResultMap 标签。
3.5、insert、update、delete标签 用法与select标签类型,见上面的select标签的笔记和官方文档的示例:
insert、update标签中,主键相关的属性:
属性useGeneratedKeys="true | false"
属性keyProperty="主键的属性名"
属性keyColumn="主键是第几列"
3.6、SQL标签 sql 标签
可以定义一些SQL语句中可以复用的一部分内容,然后在select、insert、update、delte
标签中利用<include refid=""></include>
标签和property
标签来引用 该SQL标签。
映射配置文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // ${alias}是占位符,在select语句中,通过property标签传入具体的值 <sql id ="userColumns" > ${alias}.id,${alias}.username,${alias}.password </sql > // 查询 <select id ="selectUsers" resultType ="map" > select <include refid ="userColumns" > <property name ="alias" value ="t1" /> </include > <include refid ="userColumns" > <property name ="alias" value ="t2" /> </include > from some_table t1 cross join some_table t2 </select >
3.7、懒加载 懒加载就是在类A中,有一个类B的属性,当Mybatis查询类A时,不会自动查询类B,只有手动调用查询类B的方法时,才查询类B【即:延迟加载】。
Mybatis默认关闭了懒加载
。
如何启用懒加载:
在mybatis的全局配置文件 中的settings
标签中,编写配置。
1 2 3 <settings > <setting name ="lazyLoadingEnabled" value ="flase" /> </settings >
加载方式
lazyLoadingEnabled
aggressiveLazyLoading
直接加载
必须是false,默认是false
不管是什么,只要lazyLoadingEnabled是false就是直接加载
侵入式延迟加载
必须是true
必须是true
深度延迟
必须是true
必须是false,默认是false
4、Mybatis 动态SQL 动态SQL:解决传统SQL语句的拼接繁琐的问题。
传统的SQL拼接时,where子句后面有多个多个条件那么就需要在一开始写where 1=1
,然后开始拼接。使用动态SQL标签后,则可以不用写where 1=1
。
动态SQL的标签:
以下标签的使用方式类似JSP中的JSTL标签库的用法:
if
choose
(when
, otherwise
)
trim
(where
【SQL中的where子句】, set
【update操作时的set子句】)
foreach
4.1、if 标签:
语法: <if test="拼接的条件"> 拼接的SQL语句 </if>
test 属性 中可以使用and
、or
等逻辑关键字组合多个条件
test 属性 中的字符串的判断:abc !=null and abc != ''
test 属性 中的数字的判断【需要使用转义字符】:abc <= 2
(大于等于)、abc >= 2
(小于等于)
if 标签的示例(1):
1 2 3 4 5 6 7 8 9 10 11 12 <select id ="findActiveBlogLike" resultType ="Blog" > select * from BLOG where state = ‘ACTIVE’ <if test ="title != null" > AND title like #{title} </if > <if test ="author != null and author.name != null" > AND author_name like #{author.name} </if > </select >
if 标签的示例(2)-【可能因条件不成立而报错】:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <select id ="findActiveBlogLike" resultType ="Blog" > // 条件不成立时:SELECT * FROM BLOG WHERE SELECT * FROM BLOG WHERE <if test ="state != null" > state = #{state} </if > <if test ="title != null" > AND title like #{title} </if > <if test ="author != null and author.name != null" > AND author_name like #{author.name} </if > </select >
if 标签的示例(2)-【改进】:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <select id ="findActiveBlogLike" resultType ="Blog" > SELECT * FROM BLOG <where > <if test ="state != null" > state = #{state} </if > <if test ="title != null and title != ‘’ " > AND title like #{title} </if > <if test ="author != null and author.name != null" > AND author_name like #{author.name} </if > </where > </select >
4.2、choose-when-otherwise 标签: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <select id ="findActiveBlogLike" resultType ="Blog" > SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose > <when test ="title != null" > AND title like #{title} </when > <when test ="author != null and author.name != null" > AND author_name like #{author.name} </when > <otherwise > AND featured = 1 </otherwise > </choose > </select >
4.3、where 标签:
注意:该标签解决了可能因条件全部不成立而导致的 SQL语句问题,where标签只会去掉前面的and 或者 or,因此 SQL语句的and 要放开头。
and | or 写在前面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <select id ="findActiveBlogLike" resultType ="Blog" > SELECT * FROM BLOG <where > <if test ="state != null" > state = #{state} </if > <if test ="title != null" > AND title like #{title} </if > <if test ="author != null and author.name != null" > AND author_name like #{author.name} </if > </where > </select >
4.4、trim标签:
trim 标签可以定制SQL语句,类似于where标签的功能【可解决:where标签只能去除前面的and | or的问题】
and | or 写在后面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // 从where字符开始,如果标签内部的条件不成立,则去掉最终的SQL语句中多余的 and 或 or 字符 // prefix: 给整条SQL语句拼接后的条件部分加一个前缀【相当于不写where关键字,而让前缀自动写where关键字】 // prefixOverrides: 可以去除哪种多余的连接符 // suffix: 加一个后缀 // suffixOverrides: 去掉拼接后的SQL语句后面多余的后缀 <trim prefix ="where" prefixOverrides ="and | or" > <if test ="state != null" > <if test ="state != null" > state = #{state} </if > <if test ="title != null" > AND title like #{title} </if > <if test ="author != null and author.name != null" > AND author_name like #{author.name} </if > </trim >
4.5、set 标签 set 标签是用于 update 标签内部的,其作用类似与 update 语句的 set 子句。
1 2 3 4 5 6 7 8 9 10 <update id ="updateAuthorIfNecessary" > update Author <set > <if test ="username != null" > username=#{username},</if > <if test ="password != null" > password=#{password},</if > <if test ="email != null" > email=#{email},</if > <if test ="bio != null" > bio=#{bio}</if > </set > where id=#{id} </update >
4.6、foreach 标签 foreach 标签,用于遍历某个数组、集合。
常用的属性:
item:当前元素
index:当前元素的迭代次数 、map集合的key
collcection:被迭代的数组、集合
open:数组、集合的开始分隔符
separator:数组、集合的中间分隔符
close:数组、集合的闭合分隔符
1 2 3 4 5 6 7 8 9 10 11 <select id ="selectPostIn" resultType ="domain.blog.Post" > SELECT * FROM POST P <where > <foreach item ="item" index ="index" collection ="list" open ="ID in (" separator ="," close =")" nullable ="true" > #{item} </foreach > </where > </select >
4.7、bind 标签 bind 标签:用于在 select 标签内部
设置模糊查询 的条件。
使用 bind 标签的原因:不同的数据库使用模糊查询的语法不同 。
使用步骤:
用于在 select 标签内部
拼接模糊查询的条件。
在SQL语句中使用
1 2 3 4 5 6 7 8 9 <select id ="selectBlogsLike" resultType ="Blog" > // title为参数变量名,也可替换成 _parameter.getTitle() <bind name ="pattern" value ="'%' + title + '%'" /> SELECT * FROM BLOG WHERE title LIKE #{pattern} </select >
4.8、两个内置的参数
_paramater
:单个参数时,就是该参数;多个参数时,会封装为 map。
_databaseId
:若在全局配置文件中设置了databaseProvider
,则该内置参数代表当前数据库的别名。
5、Mybatis 缓存
5.1、一级缓存 Mybatis 中的SQL语句执行后会有缓存,再次执行相同的语句时,无需编译SQL语句,直接执行缓存中的SQL。
Mybatis 缓存包括了一级缓存 和二级缓存 ,默认开启了一级缓存 【一级缓存关不了】。
一级缓存 :是 SqlSession
级别【查询缓存、本地缓存】的,每次进行增删改 操作时,一级缓存失效。
二级缓存 :是 Mapper(dao)【namespace】
级别【表级缓存、全局缓存】的,多个一级缓存 可以共享同一个二级缓存 ,二级缓存是事务性的。
手动清理一级缓存:sqlSession.clearCache();
Mybatis的缓存在底层使用 Map
封装。
一级缓存失效(不起作用)的四种情况:
SqlSession 不同。
SqlSession 相同,但查询条件不同 。
SqlSession 相同,查询条件相同,但执行了增删改 操作。
SqlSession 相同,手动清除 了一级缓存。
5.2、二级缓存 二级缓存 默认是不开启的,需要手动开启二级缓存。
二级缓存的运行机制:
一个SqlSession,查询数据后,数据保存到了一级缓存
关闭SqlSession,一级缓存保存到了二级缓存,新的SqlSession就可以共享之前的数据。
不同 namespace(dao)的数据会放在自己的的map里。
映射配置文件的每个增删改标签若使用了flushCache=“true”
,则增删改操作执行后会清理缓存(一、二级全清理)
二级缓存的使用步骤:
JavaBean 可序列化
MyBatis 的全局配置文件 中设置setting
标签
(1)实现二级缓存的时候,MyBatis 要求返回的POJO必须是可序列化 的。开启二级缓存的条件也是比较简单,通过直接在 MyBatis 的全局配置文件 中(全局生效)通过:
1 2 3 <settings > <setting name = "cacheEnabled" value = "true" /> </settings >
或在Mapper映射配置文件的select标签中使用useCache
属性配置(单个语句生效)
(2)然后,dao接口的映射配置文件 中通过<cache />
标签:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?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.dao.DeptDao" > // eviction:清除策略, // - LRU(默认):按使用频率移除,优先删除不常用的缓存 // - FIFO :按缓存产生时的顺序来删除 // - SOFT :按 GC的状态 和 软引用规则 来删除 // - WEAK :按 GC的状态 和 弱引用规则 来删除 // flushInterval: 缓存的刷新时间的间隔(毫秒),默认不清空 // size:缓存区的大小【“引用”的个数】,默认1024 // readOnly: // - true:只读,不安全,速度快 // - false:缓存数据可能被修改,利用序列化和反序列化技术clone一份新的缓存 <cache eviction ="FIFO" flushInterval ="60000" size ="512" readOnly ="true" /> </mapper >
(3)最后,POJO实现序列化接口。
6、Mybatis 整合 Spring 所需的 JAR包:
spring-webmvc
spring-tx
spring-jdbc
aspectjweaver
junit
mysql-connector-java
druid
mybatis
mybatis-spring
lombok(使用注解@Data
来代替Getter、setter等方法)
maven导入jar包:
pom.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 <?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.cyw</groupId > <artifactId > SSM-02</artifactId > <version > 1.0-SNAPSHOT</version > <packaging > war</packaging > <name > SSM-02 Maven Webapp</name > <url > http://www.example.com</url > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <maven.compiler.source > 1.7</maven.compiler.source > <maven.compiler.target > 1.7</maven.compiler.target > </properties > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.11</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 4.1.2.RELEASE</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-jdbc</artifactId > <version > 4.1.2.RELEASE</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-tx</artifactId > <version > 4.1.2.RELEASE</version > </dependency > <dependency > <groupId > org.aspectj</groupId > <artifactId > aspectjweaver</artifactId > <version > 1.8.7</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.9</version > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > 1.16.14</version > </dependency > <dependency > <groupId > org.singledog</groupId > <artifactId > mybatis-spring</artifactId > <version > 1.3.3</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.0.4</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.0.9</version > </dependency > </dependencies > <build > <finalName > SSM-02</finalName > <pluginManagement > <plugins > <plugin > <artifactId > maven-clean-plugin</artifactId > <version > 3.1.0</version > </plugin > <plugin > <artifactId > maven-resources-plugin</artifactId > <version > 3.0.2</version > </plugin > <plugin > <artifactId > maven-compiler-plugin</artifactId > <version > 3.8.0</version > </plugin > <plugin > <artifactId > maven-surefire-plugin</artifactId > <version > 2.22.1</version > </plugin > <plugin > <artifactId > maven-war-plugin</artifactId > <version > 3.2.2</version > </plugin > <plugin > <artifactId > maven-install-plugin</artifactId > <version > 2.5.2</version > </plugin > <plugin > <artifactId > maven-deploy-plugin</artifactId > <version > 2.8.2</version > </plugin > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-surefire-plugin</artifactId > <configuration > <testFailureIgnore > true</testFailureIgnore > </configuration > </plugin > </plugins > </pluginManagement > </build > </project >
6.1、整合的步骤:
1、编写:数据库(数据源)的配置:druid.properties
1 2 3 4 5 6 7 driverClassName =com.mysql.jdbc.Driver url =jdbc:mysql://localhost:3306/ssm01?useUnicode=true&characterEncoding=utf-8 user =root # 由于spring中${username}默认取的是系统的用户名,会覆盖掉配置文件的内容,所以改配置的属性名 pwd =root initialSize =5 maxActive =100 maxWait =5000
2、编写:Spring 的全局配置文件:applicationContext.xml
2-1、引入命名空间和约束:
applicationContext.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context" xmlns:aop ="http://www.springframework.org/schema/aop" xmlns:tx ="http://www.springframework.org/schema/tx" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd " > </beans >
2-2、在applicationContext.xml
中的beans标签内读取 数据库配置文件:
1 2 3 <context:property-placeholder location ="classpath:conf/druid-conf.properties" />
2-3、在applicationContext.xml
中的 开启组件扫件、AOP代理:
1 2 3 4 // 扫描com.cyw包(包括子包)下的所有组件 <context:component-scan base-package ="com.cyw" /> <aop:aspectj-autoproxy />
2-4、在applicationContext.xml
中的 配置数据源:
1 2 3 4 5 6 7 8 9 10 11 <bean id ="dataSource" class ="com.alibaba.druid.pool.DruidDataSource" > <property name ="driverClassName" value ="${driverClassName}" /> <property name ="url" value ="${url}" /> <property name ="username" value ="${user}" /> <property name ="password" value ="${password}" /> <property name ="initialSize" value ="1" /> <property name ="maxActive" value ="50" /> <property name ="maxWait" value ="30000" /> </bean >
2-5、在applicationContext.xml
中的 配置事务管理器:
1 2 3 4 5 6 <bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name ="dataSource" ref ="dataSource" /> </bean > <tx:annotation-driven transaction-manager ="transactionManager" />
2-6、在applicationContext.xml
中的 配置Mybatis的sqlSessionFactory:
1 2 3 4 5 6 7 8 <bean id ="sqlSessionFactory" class ="org.mybatis.spring.SqlSessionFactoryBean" > <property name ="dataSource" ref ="dataSource" /> <property name ="configLocation" value ="classpath:conf/mybatis-conf.xml" /> </bean >
2-7、在applicationContext.xml
中的 配置Dao接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <bean class ="org.mybatis.spring.mapper.MapperScannerConfigurer" > <property name ="basePackage" value ="com.cyw.dao" /> </bean >
3、编写:Mybatis 的全局配置文件:mybatis-conf.xml
1 2 3 4 5 6 7 8 9 10 11 12 <?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 > // 批量注册com.cyw.dao中的接口【可省略】 <mappers > <package name ="com.cyw.dao" /> </mappers > </configuration >
4、编写:Mybatis 的映射配置文件:StuMapper.xml
、StuIdCardMapper.xml
、ClassesMapper.xml
注意:
mapper 标签的 namespace
属性的值为 Dao接口的全类名
增删改查标签的 id
属性:为Dao接口的方法名
增删改查标签的 parameterType
属性:为Dao接口的参数类型的别名或全类名
增删改查标签的 resultMap
属性:为 resultMap标签的 id
StuMapper.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?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.cyw.dao.StuDao" > // 结果集的(封装)映射规则 <resultMap id ="UserRst" type ="com.cyw.po.Stu" > <id property ="id" column ="id" /> <result property ="name" column ="name" javaType ="string" /> <result property ="sex" column ="sex" /> // 嵌套查询,调用另一个接口的查询方法 <association property ="card" column ="id" javaType ="com.cyw.po.StuIdCard" select ="com.cyw.dao.StuIdCardDao.getStuIdCardById" /> </resultMap > <select id ="getStuById" parameterType ="integer" resultMap ="UserRst" > // 嵌套查询方式的SQL select * from stu where id = #{id}; </select > </mapper >
StuIdCardMapper.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 <?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.cyw.dao.StuIdCardDao" > <select id ="getStuIdCardById" parameterType ="integer" resultType ="com.cyw.po.StuIdCard" > select * from stuIdCard where id = #{id}; </select > </mapper >
6.2、目录结构及配置文件:
Spring的配置文件
(mybatis的配置文件见上面的“整合步骤”小节):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context" xmlns:aop ="http://www.springframework.org/schema/aop" xmlns:tx ="http://www.springframework.org/schema/tx" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd " > <context:component-scan base-package ="com.cyw" /> <aop:aspectj-autoproxy /> <context:property-placeholder location ="classpath:conf/druid-conf.properties" /> <bean id ="dataSource" class ="com.alibaba.druid.pool.DruidDataSource" > <property name ="driverClassName" value ="${driverClassName}" /> <property name ="url" value ="${url}" /> <property name ="username" value ="${user}" /> <property name ="password" value ="${password}" /> <property name ="initialSize" value ="1" /> <property name ="maxActive" value ="50" /> <property name ="maxWait" value ="30000" /> </bean > <bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name ="dataSource" ref ="dataSource" /> </bean > <tx:annotation-driven transaction-manager ="transactionManager" /> <bean id ="sqlSessionFactory" class ="org.mybatis.spring.SqlSessionFactoryBean" > <property name ="dataSource" ref ="dataSource" /> <property name ="configLocation" value ="classpath:conf/mybatis-conf.xml" /> </bean > <bean class ="org.mybatis.spring.mapper.MapperScannerConfigurer" > <property name ="basePackage" value ="com.cyw.dao" /> </bean > </beans >
7、Mybatis 逆向工程 Mybatis 逆向工程是什么?
Mybatis 逆向工程(MyBatis Generator)也叫 MBG,可以通过逆向工程的配置文件 自动生成 POJO(JavaBean)、Dao、Dao的映射配置文件。
使用步骤:
1、maven 项目在 pom.xml
文件中添加以下代码:
1 2 3 4 5 <dependency > <groupId > org.mybatis.generator</groupId > <artifactId > mybatis-generator-core</artifactId > <version > 1.4.0</version > </dependency >
2、在项目中创建MGB的配置文件(名字随便起,此处命名为genertorConfig.xml
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" > <generatorConfiguration > <context id ="DB2Tables" targetRuntime ="MyBatis3" > <commentGenerator > <property name ="suppressAllComments" value ="true" /> </commentGenerator > <jdbcConnection driverClass ="com.mysql.jdbc.Driver" connectionURL ="jdbc:mysql://localhost:3306/test" userId ="root" password ="root" /> <javaTypeResolver > <property name ="forceBigDecimals" value ="false" /> </javaTypeResolver > <javaModelGenerator targetPackage ="net.biancheng.pojo" targetProject =".\src" > <property name ="enableSubPackages" value ="false" /> <property name ="trimStrings" value ="true" /> </javaModelGenerator > <sqlMapGenerator targetPackage ="net.biancheng.mapper" targetProject =".\src" > <property name ="enableSubPackages" value ="false" /> </sqlMapGenerator > <javaClientGenerator type ="XMLMAPPER" targetPackage ="net.biancheng.mapper" targetProject =".\src" > <property name ="enableSubPackages" value ="false" /> </javaClientGenerator > <table tableName ="website" > </table > <table tableName ="student" > </table > <table tableName ="studentcard" > </table > <table tableName ="user" > </table > </context > </generatorConfiguration >
3、创建执行MBG 的类,来自动生成 POJO、Dao接口、Dao的映射配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package net.biancheng; import java.io.File; import java.util.*; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; public class GeneratorSqlmap { public void generator() throws Exception { // List<String > warnings = new ArrayList<String > (); boolean overwrite = true; // 指定配置文件 File configFile = new File("./config/generatorConfig.xml"); // 创建解析器 ConfigurationParser cp = new ConfigurationParser(warnings); // 读取配置 Configuration config = cp.parseConfiguration(configFile); // DefaultShellCallback callback = new DefaultShellCallback(overwrite); // 创建MGB生成器 MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); // 生成 myBatisGenerator.generate(null); } // 执行main方法以生成代码 public static void main(String[] args) { try { GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap(); generatorSqlmap.generator(); } catch (Exception e) { e.printStackTrace(); } } }
8、Mybatis 运行原理
9、Mybatis 插件
10、Mybatis 扩展