1引入dtd约束(6)
Mybatis git地址:https://github.com/mybatis/mybatis-3/wiki/Maven
指导手册:http://www.mybatis.org/mybatis-3/zh/getting-started.html
1.1)Maven项目引入mybatis包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version></dependency>
1.2)找到下载的jar包,解压并找到D:G--学习软件学习mybatis视频学习mybatis-3.4.1orgapacheibatisuilderxml
下的文件将其拷贝到文件夹中(如
D:Eworksoftmybatis-dtd中)
1.3)eclipse中-->preferences-->搜索xml--》xml catalog--》key输入:mybatis-config.xml全局配置文件中的dtd链接:http://mybatis.org/dtd/mybatis-3-config.dtd
--》location选择拷贝的文件地址(D:Eworksoftmybatis-dtdmybatis-3-mapper.dtd)
---》key type选择“URI”
-->ok--》关闭mybatis-config.xml文件再打开即可提示
2全局配置文件引入外部配置文件(7)
使用properties引入外部properties配置文件内容
<properties url=""></properties><!-- 引入网络路径或磁盘路径下资源 -->
<properties resource=""></properties><!-- 引入类路径下资源 -->
2.1)新建配置文件
dbconfig2.properties
内容:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8
jdbc.username=root
jdbc.password=(Junli@2018*test)
2.2)修改mybatis-config.xml全局配置
<configuration>
<properties resource="dbconfig.properties"></properties><!-- 引入类路径下资源 -->
<!-- <properties url=""></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 resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
3setting运行时设置(8)
3.1)mapUnderscoreToCamelCase 映射下划线到驼峰规则,即数据库为下划线命名规则,java bean为驼峰命名规则。默认false,设置为true
<settings>
<!-- name:设置项名,value:设置项值 -->
<setting name="mapUnderscoreToCamelCase" value="true"/><!--映射数据库下划线-java bean驼峰命名规则 -->
</settings>
4typeAliases别名(9)
<!-- typeAliases别名处理器,可以为我们的java类型起别名 -->
<typeAliases>
<!-- typeAliases:为某个java类型起别名;type:指定要起别名的类型全类名,默认别名为类型小写,employee -->
<typeAlias type="com.mybatis.bean.Employee" alias="emp"/>
</typeAliases>
5typehandlers类型处理器(10)
Java数据类型和数据库数据类型转换
Mybatis3.4后已自动注册部分类型处理(如日期),无需手动注册。
6plugins插件(11)
允许插件拦截的方法:
Executor/parameterHandler/resultSetHandler/statementhandler。
7enviroments运行环境(12)
Enviroments:环境列表,可配置多个,通过default切换不同环境
Enviroment:配置具体的环境信息,id为环境唯一标识。
Enviroment必须有2个标签:
transactionManager:
Type:配置事务管理器类型,JDBC | MANAGED 和自定义事务管理器 ,后续通过spring管理
dataSource:数据源,POOLED | UNPOOLED | JNDI 和自定义连接池,后续通过spring管理
如:
<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>
<environment id="test">
<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>
8databaseidprovider多数据库支持(13)
8.1)全局配置文件中配置多数据库支持
<!-- 多数数据库支持
DB_VENDOR:别名,作用得到数据库厂商标识(驱动自带),mybatis工具数据库厂商标识执行不同sql
MySQL,Oracle,SQL Server,***数据库厂商标识
-->
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/><!-- 为不同的数据库厂商名起别名 -->
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
8.2)mapper映射文件中配置sql执行对应的数据库id(databaseId)
<select id="selectEmployee" resultType="com.mybatis.bean.Employee"
databaseId="mysql">
select * from myemployeee where id = #{id}
</select>
<select id="selectEmployee" resultType="com.mybatis.bean.Employee"
databaseId="oracle">
select employee_id id,last_name lastName,email email from employees where employee_id= #{id}
</select>
9mappers sql映射注册(14)
将sql映射注册到全局配置中
<!--mappers :将sql映射注册到全局配置中 -->
<mappers>
<!-- mapper:注册一个sql映射(单个注册)
resources:引入类路径下的sql映射文件
url:引用网络路径或磁盘路径下的sql映射文件
file://var/mappers/EmployeeMapper.xml
class:引用接口,一般用于接口注解方式
使用方式1:有sql映射文件,且与接口同名,与接口在同一层目录下
使用方式2:没有sql映射文件,所有sql通过注解写在接口上
推荐:重要复杂的,使用dao接口写sql映射文件
不重要,简单的dao接口可使用注解方式。
-->
<!-- <mapper resource="EmployeeMapper.xml"/>
<mapper url="d:/test/EmployeeMapper.xml"/> -->
<!-- <mapper class="com.mybatis.bean.EmployeeMapper"/> -->
<!-- package 批量注册,最好将mapper接口名和xml文件放在同一个包名下 -->
<package name="com.mybatis.bean"/>
</mappers>
注意:
public interface EmployeeMapper {
// @Select("select * from myemployeee where id = #{id}")
List<Employee> selectEmployee(Integer id);
}
如果EmployeeMapper 接口和EmployeeMapper.xml文件同名,采用注解方式时则相当于将EmployeeMapper.xml中的sql写在了EmployeeMapper 接口中,因此需要注释其中一种,否则会冲突。
为方便显示,可在conf文件夹下创建com.mybatis.dao文件夹,将.xml文件放在该目录下,接口类放在src/main/java的com.mybatis.dao文件夹中。因为:无论是src/main/java还是resources下的文件最终都会编译到classes(类路径下)。
创建的文件结构如下:
编译后的文件:
可以看到.xml和接口确实被编译到同一个文件夹下(即2个是一个包,只是eclipse视觉是2个):
需要调整的地方:
<mapper namespace="com.mybatis.dao.EmployeeMapper">
Employee employee = (Employee) session.selectOne("com.mybatis.dao.EmployeeMapper.selectEmployee", 1);
<package name="com.mybatis.dao"/>
10xml映射文件(16)
常用标签:
标签名 |
作用 |
备注 |
Cache |
命名空间二级缓存配置 |
|
Cache-ref |
其他命名空间缓存配置引用 |
|
Resultmap |
自定义结果集映射 |
|
parameterMap |
已废弃,老式风格参数映射 |
|
Sql |
抽取可重用语句块 |
|
Insert |
映射插入语句 |
|
Update |
映射修改语句 |
|
Delete |
映射删除语句 |
|
Select |
映射查询语句 |
测试
1)拷贝项目重命名为mybatistest2
2)项目结构如下:
3)EmployeeMapper.java
public interface EmployeeMapper {
//查询
List<Employee> selectEmployee(Integer id);
//增加
Integer addEmp(Employee employee);
//修改
Integer updateEmp(Integer id);
//删除
Integer deleteEmp(Integer id);
}
4)EmployeeMapper.xml
<mapper namespace="com.mybatis.dao.EmployeeMapper">
<select id="selectEmployee" resultType="com.mybatis.bean.Employee"
databaseId="mysql">
select * from myemployeee where id = #{id}
</select>
<!-- <select id="selectEmployee" resultType="com.mybatis.bean.Employee"
databaseId="oracle">
select * from myemployeee where id = #{id}
</select> -->
<insert id="addEmp" parameterType="com.mybatis.bean.Employee">
insert into myemployeee(last_name,email,gender)
values(#{lastName,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},#{gender,jdbcType=VARCHAR})
</insert>
<update id="updateEmp" parameterType="com.mybatis.bean.Employee">
update myemployeee mm
set mm.last_name=#{lastName,jdbcType=VARCHAR}
,mm.email=#{email,jdbcType=VARCHAR}
,mm.gender=#{gender,jdbcType=VARCHAR}
where mm.id=#{id,jdbcType=INTEGER}
</update>
<delete id="deleteEmp" >
delete mm from myemployeee mm where mm.id=#{id,jdbcType=INTEGER}
</delete>
</mapper>
注意:mysql的delete的语法有些特殊,delete 语句在用别名的时候要在delete后边多写一个别名。
5)mybatis-config.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="dbconfig.properties"></properties><!-- 引入类路径下资源 -->
<!-- setting 设置项 -->
<settings>
<!-- name:设置项名,value:设置项值 -->
<setting name="mapUnderscoreToCamelCase" value="true"/><!--映射数据库下划线-java bean驼峰命名规则 -->
</settings>
<!-- typeAliases别名处理器,可以为我们的java类型起别名 -->
<typeAliases>
<!-- typeAliases:为某个java类型起别名;type:指定要起别名的类型全类名,默认别名为类型小写,employee -->
<typeAlias type="com.mybatis.bean.Employee" alias="emp"/>
</typeAliases>
<!-- <properties url=""></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>
<environment id="test">
<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>
<!-- 多数数据库支持
DB_VENDOR:别名,作用得到数据库厂商标识(驱动自带),mybatis工具数据库厂商标识执行不同sql
MySQL,Oracle,SQL Server,***数据库厂商标识
-->
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/><!-- 为不同的数据库厂商名起别名 -->
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
<!--mappers :将sql映射注册到全局配置中 -->
<mappers>
<!-- mapper:注册一个sql映射(单个注册)
resources:引入类路径下的sql映射文件
url:引用网络路径或磁盘路径下的sql映射文件
file://var/mappers/EmployeeMapper.xml
class:引用接口,一般用于接口注解方式
使用方式1:有sql映射文件,且与接口同名,与接口在同一层目录下
使用方式2:没有sql映射文件,所有sql通过注解写在接口上
推荐:重要复杂的,使用dao接口写sql映射文件
不重要,简单的dao接口可使用注解方式。
-->
<!-- <mapper resource="EmployeeMapper.xml"/>
<mapper url="d:/test/EmployeeMapper.xml"/> -->
<!-- <mapper class="com.mybatis.bean.EmployeeMapper"/> -->
<!-- package 批量注册,最好将mapper接口名和xml文件放在同一个包名下 -->
<package name="com.mybatis.dao"/>
</mappers>
</configuration>
6)dbconfig.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8
jdbc.username=root
jdbc.password=(Junli@2018*test)
7)启动类:
Mytest.java
public class Mytest {
public static void main(String[] args) throws IOException {
SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession();//手动提交
// SqlSession session = sqlSessionFactory.openSession(true);//自动提交
try {
// Employee employee = (Employee) session.selectOne("com.mybatis.dao.EmployeeMapper.selectEmployee", 1);
EmployeeMapper mapper=session.getMapper(EmployeeMapper.class);
Employee employee = new Employee(null,"test","test@com.cm","男");
//mapper为代理对象
mapper.addEmp(employee);
// System.out.println(employee);
//手动提交
session.commit();
} finally {
session.close();
}
}
//从xml文件中创建sqlsessionfactory
public static SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";//类路径下直接写配置
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}
11 insert获取自增主键的值(17)
插入sql中新增属性:
<!-- 获取自增主键的值 -->
<insert id="addEmp" parameterType="com.mybatis.bean.Employee"
useGeneratedKeys="true" keyProperty="id">
insert into myemployeee(last_name,email,gender)
values(#{lastName,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},#{gender,jdbcType=VARCHAR})
</insert>
Test类中执行语句:
Employee employee = new Employee(null,"test3","test3@com.cm","男");
//mapper为代理对象
//添加
mapper.addEmp(employee);
System.out.println("新增主键:"+employee.getId());
12 oracle使用序列生成主键(18)
Oracle主键不能自增,需要通过序列模拟自增。每次插入时,先从序列获取下一个值。
1)查询当前存在序列:
Select * from user_sequences; //查询序列列表。
2)如存在employees_seq序列,先查询学列下一个值
Select employees_seq.nextval from dual;
--得到值221,
再查一次:
Select employees_seq.nextval from dual;
--得到222.
即每次查询就会自增
3)insert into employees values(223,’test’,’test@com.cn’,’男’);
其中223为先从序列获取的值,再自行赋值数据中的。
13获取非自增主键的值,selectkey(19)
<insert id="addEmp" parameterType="com.mybatis.bean.Employee"
useGeneratedKeys="true" keyProperty="id" databaseId="oracle">
<!-- 编写查询主键的sql序列
keyProperty:查出的值赋值给javabean的属性
order:执行顺序
BEFORE在之前;
先运行selectkey查询id的sql,查出id值封装给javabean的id属性
再运行插入的sql,可获取id属性对应的值
AFTER使用序列:
先运行插入的sql(从序列中取出新值作为id)
再运行selectkey查询id的sql,查出id值封装给javabean的id属性
insert into myemployeee(last_name,email,gender)
values(employees_seq,#{email,jdbcType=VARCHAR},#{gender,jdbcType=VARCHAR})
此时查询序列语句应该改为:
select employees_seqd.currval from dual
resultType:返回值类型
-->
<selectKey keyProperty="id" order="BEFORE" resultType="integer">
<!-- 编写查询主键的sql序列 -->
select employees_seqd.nextval from dual
</selectKey>
insert into myemployeee(last_name,email,gender)
values(#{id,jdbcType=integer},#{email,jdbcType=VARCHAR},#{gender,jdbcType=VARCHAR})
</insert>
14参数处理(20)
类型 |
处理方式 |
备注 |
单个参数 |
Mybatis不会特殊处理 #{参数名}:取出参数的值 |
|
多个参数(命名参数) |
多个参数会被封装成一个map 1)默认: Key: param1...paramN或者参数索引 Value:传入的参数值 #{param1},#{param2} 2)多个参数封装成map @Param(“id”) |
Employee selectEmployeeByIdAndLastName(Integer id,String lastName); 取值:#{id},#{lastName}会报错 1)默认方式: select * from myemployeee where id = #{param1} and last_name=#{param2} 2)封装成map方式: Employee selectEmployeeByIdAndLastName(@Param("id")Integer id,@Param("lastName")String lastName); select * from myemployeee where id = #{id} and last_name=#{lastName} |
POJO |
多个参数正好是业务数据模型,可直接传入pojo,#{属性名},取出传入pojo的属性值。 |
|
Map |
如果多个参数不是业务数据模型,没有对应的pojo,可直接传入map。 #{key}取出map中对应的值 |
<select id="selectEmployeeByMap" resultType="com.mybatis.bean.Employee"> select * from myemployeee where id = #{id} and last_name=#{lastName} </select> Employee selectEmployeeByMap(Map<String,Object> map); Map<String,Object> map=new HashMap<String,Object>(); map.put("id", 1); map.put("lastName","test"); Employee employee1=mapper.selectEmployeeByMap(map); |
TO |
多个参数不是业务模型中的数据,但经常使用,推荐编写一个TO(transfer object)数据传入对象,如 Page{ int index; int size;} |
案例分析:
1)selectEmployeeByIdAndLastName(@Param("id")Integer id,String lastName);
取值:id==>#{id/param1} lastName==>#{param2}
2)selectEmployeeByIdAndLastName(Integer id,Employee emp);
取值:id==>#{param1} lastName==>#{param2.lastName}
3)selectEmployeeByIdAndLastName(Integer id,@Param("e")Employee emp);
取值:id==>#{param1} lastName==>#{param2.lastName/e.lastName}
4)selectEmployeeByIdAndLastName(List<Integer> ids);
取值:取出第一个id值:#{list[0]}
集合collection(list/set)类型或数组,也会特殊处理,把传入的list或数组封装在map中,key,collection(collection);如果是list还可以使用key(list);数组(array)。