MyBatis框架
1.ORM框架介绍
1.1 什么是ORM?
对象关系映射(Object Relational Mapping,简称ORM),对象关系映射即数据库数据与对象的关系的映射
ORM阐述
[图片上传失败...(image-bb9e03-1565855698548)]
1.2 ORM框架有哪些?
Hibernate : 全自动的ORM框架,不用书写SQL语句,就可以对数据库进行增删改查. 跨平台 .Hibernate的代码可以适用于多种数据库.但是,配置比较复杂,第二点查询效率相对而言较低,且不灵活.
Mybatis : 半自动的ORM框架,需要书写SQL语句,就可以对数据库进行增删查改.
Spring Data : 类似于Hibernate,更多基于注解.
1.3 mybatis相对而言的优势以及不足?
优势: 轻便,依赖的jar很少,数据库操作灵活,程序员可操作空间相对较大.
不足 : 基本查询还需手写,开发效率较低
2.MyBatis概述
2.1 官网:https://blog.mybatis.org/
2.2 中文官网:http://www.mybatis.org/mybatis-3/zh/index.html
mybatis起源:
ibatis是mybatis早期的名字,在spring 3.0之前还可以使用,spring 3.0 之后不再支持ibatis,是apach早期的一个开源项目,后更名mybatis,是一个Java持久层的框架,持久化:将数据进行永久化的保存,一般指保存数据到文件中
3.MyBatis入门配置
3.1 Mybtias入门
3.1.1 导入相关jar包
mybatis-3.5.2.jar mybatis核心jar包
mysql-connector-java-5.1.47.jar 数据库连接驱动包
3.1.2 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">
<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://127.0.0.1:3306/mybatis01"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/sxt/bean/UserMapper.xml"/>
</mappers>
</configuration>
3.1.3 mybatis数据库映射文件
映射配置文件
<?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 命名空间 用于区别sql语句的id ,namespace+id 的值必须唯一 -->
<mapper namespace="com.sxt.bean.User111111">
<!-- 在mybatis中 看到了 type 即 类 -->
<select id="selectList" resultType="com.sxt.bean.User">
select * from user
</select>
</mapper>
相关实体类
package com.sxt.bean;
public class User {
private int id;
private String name;
private String sex;
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", sex=" + sex + "]";
}
}
3.1.4 加载配置文件,创建数据库操作对象
package com.sxt.test;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.sxt.bean.User;
public class Test {
public static void main(String[] args) throws Exception {
String resource = "mybatis-config.xml";
//创建一个SqlSessionFactory构造对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//sqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Test.class.getClassLoader().getResourceAsStream(resource));
//数据库SQL会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//增删查改
System.out.println(sqlSession);
// sqlSession 在使用时,必须传一个sql语句,传SQL语句的唯一标识
List<User> users = sqlSession.selectList("com.sxt.bean.User111111.selectList");
for (User user : users) {
System.out.println(user);
}
//关闭session
sqlSession.close();
}
}
4.MyBatis基本CRUD(增删查改)
方式一
4.1 SqlSession工具类
package com.sxt.util;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* 创建 SqlSession
* @author mrt
*
*/
public class MybatisUtil {
static SqlSessionFactory sqlSessionFactory = null;
static {
String source = "mybatis.cfg.xml";
//创建 SqlSessionFactory
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(MybatisUtil.class.getClassLoader().getResourceAsStream(source));
}
/**
* 获取SqlSession 对象
* @return
*/
public static SqlSession getSession() {
return sqlSessionFactory.openSession();
}
}
4.2 核心配置文件
<?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://127.0.0.1:3306/mybatis01"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/sxt/bean/UserMapper.xml"/>
</mappers>
</configuration>
4.3 数据库映射文件
<?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 命名空间 用于区别sql语句的id ,namespace+id 的值必须唯一 -->
<mapper namespace="com.sxt.bean.User">
<!-- 在mybatis中 看到了 type 即 类 -->
<select id="selectUser" resultType="com.sxt.bean.User" parameterType="java.lang.Integer">
select * from user where id = #{id}
</select>
<!-- 查询列表 -->
<select id="selectList" resultType="com.sxt.bean.User" >
select * from user
</select>
<!-- 新增 -->
<insert id="insertUser" parameterType="com.sxt.bean.User">
insert into user value(0,#{name},#{sex})
</insert>
<!-- 删除 -->
<delete id="deleteUser" parameterType="int" >
delete from user where id = #{id}
</delete>
<!-- 修改 -->
<update id="updateUser" parameterType="com.sxt.bean.User">
update user set name = #{name},sex = #{sex} where id = #{id}
</update>
</mapper>
4.4 dao层
package com.sxt.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.sxt.bean.User;
import com.sxt.util.MybatisUtil;
public class UserDao {
public User selectUser(int id) {
SqlSession session = MybatisUtil.getSession();
User u = session.selectOne("com.sxt.bean.User.selectUser", id);
session.close();
return u;
}
public List<User> selectList() {
SqlSession session = MybatisUtil.getSession();
List<User> users = session.selectList("com.sxt.bean.User.selectList");
session.close();
return users;
}
/**
* 新增用户
* @param u
*/
public void insertUser(User u) {
SqlSession session = MybatisUtil.getSession();
session.insert("com.sxt.bean.User.insertUser", u);
session.commit();
session.close();
}
public void deleteUser(int id) {
SqlSession session = MybatisUtil.getSession();
session.delete("com.sxt.bean.User.deleteUser", id);
session.commit();
session.close();
}
public void updateUser(User u) {
SqlSession session = MybatisUtil.getSession();
session.update("com.sxt.bean.User.updateUser",u);
session.commit();
session.close();
}
}
4.5 log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
注意:
1.在mybatis中,涉及到数据库更新操作,需要手动提交
2.namespace+id产生的字符串必须唯一
方式二:
注意点:
1.maper.xml文件中namespace的值,必须与接口的全路径一致
2.mapper.xml文件中,sql标签的id值,必须与接口的方法名一致
接口代码:
package com.sxt.dao;
import java.util.List;
import com.sxt.bean.User;
public interface IUserDao {
/**
* 根据ID 查询用户
* @param id
* @return
*/
public User selectUser(int id);
/**
* 查询所有
* @return
*/
public List<User> selectList();
/**
* 新增用户
* @param u
*/
public void insertUser(User u);
/**
* 删除用户
* @param id
*/
public void deleteUser(int id);
/**
* 修改用户
* @param u
*/
public void updateUser(User u);
}
mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace 命名空间 用于区别sql语句的id ,namespace+id 的值必须唯一 -->
<!--
1. 注意此时的 namespace的值 此时 其值 为IUserDao的全路径
2.此时 xml 配置文件种 数据库 CRUD操作的 标签的id 值 与 接口中的方法名称一致
-->
<mapper namespace="com.sxt.dao.IUserDao">
<!-- 在mybatis中 看到了 type 即 类 -->
<select id="selectUser" resultType="com.sxt.bean.User" parameterType="java.lang.Integer">
select * from user where id = #{id}
</select>
<!-- 查询列表 -->
<select id="selectList" resultType="com.sxt.bean.User" >
select * from user
</select>
<!-- 新增 -->
<insert id="insertUser" parameterType="com.sxt.bean.User">
insert into user value(0,#{name},#{sex})
</insert>
<!-- 删除 -->
<delete id="deleteUser" parameterType="int" >
delete from user where id = #{id}
</delete>
<!-- 修改 -->
<update id="updateUser" parameterType="com.sxt.bean.User">
update user set name = #{name},sex = #{sex} where id = #{id}
</update>
</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">
<!-- mybatis的核心配置文件 -->
<configuration>
<!-- properties配置文件 引入一个properties 配置文件 通过 ${配置文件中的key}获取值 -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 配置 mybatis的日志 -->
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 别名 -->
<typeAliases>
<!--
typeAlias :
|== type : 标识类
|== alias : 类的别名
-->
<!-- <typeAlias type="com.sxt.bean.User" alias="User"/> -->
<!--
别名第二种方式:
package
|==== name : 包名 此时默认改包下面的所有类的别名就是 类名 例如 : com.sxt.bean.User === > User
-->
<package name="com.sxt.bean"/>
</typeAliases>
<!--
mybatis 运行环境
environments : 表示可以有多个环境 一个系统可以有多个数据库(可以时不同的类型的数据库 ) 多数据源
|==== default : 表示当前采用的数据库环境
environment : 具体的数据库环境
| ==== id : 环境的唯一标识
transactionManager : 事务管理器
|==== JDBC : 使用JDBC的事务, 在Mysql中会为每个数据更新操作,开启和关闭事务
|==== MANAGED : 这个配置几乎没做什么。它从来不提交或回滚一个连接
dataSource : 数据源
|==== UNPOOLED : 不使用连接池
|==== POOLED : 使用内置连接池
|==== JNDI : 本地连接池
property : 数据库连接的相关参数
注意: 当使用mybatis默认的时,driver url username password
-->
<environments default="MYSQL">
<environment id="MYSQL">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<environment id="ORACLE">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--
数据库实体类映射文件
mapper : 标识一个具体的映射文件
-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
<!-- 引入一个映射文件 从本地引入 不使用 -->
<!-- <mapper url="file://"/> -->
<!-- 引入一个包下面所有的xml文件 较少使用 因为xml一般会单独放在 xml相关配置文件夹中,不与类放在一起 -->
<!-- <package name="com.sxt.bean"/> -->
</mappers>
</configuration>
测试类
package com.sxt.test;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.sxt.bean.User;
import com.sxt.dao.IUserDao;
public class Test {
public static void main(String[] args) {
String source = "mybatis.cfg.xml";
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(Test.class.getClassLoader().getResourceAsStream(source));
//获取SqlSession
SqlSession session = sessionFactory.openSession();
// 使用Mapper 接口的形式
/**
* 使用接口的形式,和代理,使用mybatis操作数据库时:
* 1. maper.xml文件中的namespace值,必须与操作数据库数据的dao层接口名称全路径一致
* 2. 接口的中抽象方法名称必须与mapper.xml文件 sql语句标签的id值一致
*/
IUserDao userDao = session.getMapper(IUserDao.class);
User user = userDao.selectUser(2);
System.out.println(user);
User u = new User();
u.setName("Lucy");
u.setSex("女");
userDao.insertUser(u);
session.commit();
session.close();
}
}
5.核心配置文件
mybatis.cfg.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">
<!-- mybatis的核心配置文件 -->
<configuration>
<!-- properties配置文件 引入一个properties 配置文件 通过 ${配置文件中的key}获取值 -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 配置 mybatis的日志 -->
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 别名 -->
<typeAliases>
<!--
typeAlias :
|== type : 标识类
|== alias : 类的别名
-->
<!-- <typeAlias type="com.sxt.bean.User" alias="User"/> -->
<!--
别名第二种方式:
package
|==== name : 包名 此时默认改包下面的所有类的别名就是 类名 例如 : com.sxt.bean.User === > User
-->
<package name="com.sxt.bean"/>
</typeAliases>
<!--
mybatis 运行环境
environments : 表示可以有多个环境 一个系统可以有多个数据库(可以时不同的类型的数据库 ) 多数据源
|==== default : 表示当前采用的数据库环境
environment : 具体的数据库环境
| ==== id : 环境的唯一标识
transactionManager : 事务管理器
|==== JDBC : 使用JDBC的事务, 在Mysql中会为每个数据更新操作,开启和关闭事务
|==== MANAGED : 这个配置几乎没做什么。它从来不提交或回滚一个连接
dataSource : 数据源
|==== UNPOOLED : 不使用连接池
|==== POOLED : 使用内置连接池
|==== JNDI : 本地连接池
property : 数据库连接的相关参数
注意: 当使用mybatis默认的时,driver url username password
-->
<environments default="MYSQL">
<environment id="MYSQL">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<environment id="ORACLE">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--
数据库实体类映射文件
mapper : 标识一个具体的映射文件
-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
<!-- 引入一个映射文件 从本地引入 不使用 -->
<!-- <mapper url="file://"/> -->
<!-- 引入一个包下面所有的xml文件 较少使用 因为xml一般会单独放在 xml相关配置文件夹中,不与类放在一起 -->
<!-- <package name="com.sxt.bean"/> -->
</mappers>
</configuration>
6.Mapper.xml配置文件
6.1 mapper.xml的基础配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace 命名空间 用于区别sql语句的id ,namespace+id 的值必须唯一 -->
<!--
namespace :
1. 隔离sql标签
2. 用于代理时,绑定具体的接口
insert delete update select : 标识sql操作类型
一般相应的类型,使用相应的标签
select标签:
id : 标签唯一标识 在同一个namespace中 id值必须唯一 若使用代理形式,则必须与方法名一致
parameterMap : 参Map 弃用
parameterType : 参数类型 是一个类 int 若是集合 map set list 且 若是具体的类时,一般使用全路径
com.sxb.bean.User 没有设置别名时 也可以缺省
resultMap :查询结果的映射关系,其值是一个 resultMap的ID 当查询结果与对应的类中属性名称不一致时,可以使用
resultMap,且resultMap与resultType 不可同时使用
resultType : 查询结果映射的类 根据查询结果的列明 从 指定的类中找同名属性,进行赋值
-->
<mapper namespace="com.sxt.dao.IUserDao">
<resultMap type="User" id="BASE_RESULT_MAP">
<!--
id: 一般用于主键
column : 列名
property : 属性名
-->
<id column="id" property="id"/>
<result column="name111" property="name"/>
<result column="sex111" property="sex"/>
</resultMap>
<!-- <select id="selectAll" resultType="User">
select id as id,name111 as name,sex111 as sex from user
</select> -->
<select id="selectAll" resultMap="BASE_RESULT_MAP" >
select * from user
</select>
<!--
useGeneratedKeys :是否使用生成的key值 true false
keyColumn : key对应列名
keyProperty : key对应属性名
当向数据库新增一条数据,一般会有自动生成ID值,问题:如何获取你刚刚新增的用户id
-->
<insert id="insertUser" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
insert into user value (0,#{name},#{sex})
</insert>
</mapper>
6.2 占位符 # 与 $
在Mybatis中,可以使用是字符串拼接
#号则使用PreparedStatement进行了SQL预编译,可以更好的防止SQL注入攻击
7.模糊查询
7.1重点:方式一: concat 字符串拼接函数
concat(str1,str2,str3,....) : 将多个字符串进行拼接
concat("%",关键字,"%")
7.2(知道):方式二: $符字符串拼接
7.3(掌握): 方式三:bind
<?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.sxt.dao.IUserDao">
<!--
模糊搜索 方式一:
concat (str1,str2,...) : 字符串拼接函数
-->
<select id="selectLike1" resultType="User" parameterType="String">
select * from user where name like concat("%",#{name},"%");
</select>
<!--
模糊搜素 方式二:
使用 $ 将查询参数当作字符串进行拼接
-->
<select id="selectLike2" resultType="User" parameterType="String">
select * from user where name like '%${name}%';
</select>
<!--
模糊搜索 方式三:
使用 bind
-->
<select id="selectLike3" resultType="User" parameterType="String">
<bind name="keyWords" value="'%'+name+'%'"/>
select * from user where name like #{keyWords};
</select>
</mapper>
8.原生分页查询
当存在多个基本类型的参数时,在sql中获取值,无法直接根据参数名称获取值.
8.1 关于参数的值的获取
8.1.1 方式一: @Param("别名")
在sql语句中,可以通过 #{别名}获取值
public List<User> page(@Param("page")int page,@Param("limit")int limit);
<!-- 对应页的数据 -->
<select id="page" resultType="User" parameterType="User" >
select * from user limit #{page},#{limit}
</select>
8.1.2 方式二:arg0-------argn
8.1.3 方式三: param1----paramn
<!-- 对应页的数据 -->
<select id="page" resultType="User" parameterType="User" >
select * from user limit #{arg0},#{arg1}
</select>
<select id="page" resultType="User" parameterType="User" >
select * from user limit #{param1},#{param2}
</select>
分页方式二:RowBounds(offset,limit)
RowBounds rowBounds = new RowBounds((3-1)*2, 2);
user = userDao.page2(rowBounds);
<select id="page2" resultType="User" parameterType="User" >
select * from user
</select>
9.分页插件
9.1分页插件:pageHelper
PageHelper使用步骤:
1.下载相关jar : pagehelper-x.x.x.jar 和 jsqlparser-0.9.5.jar,导入项目中
2.心配置文件中,配置
<!-- 配置插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor" />
</plugins>
3.在要进行分页查询的sql语句执行前,开启分页:
Page<Object> page = PageHelper.startPage(页码, 每页数据条数);
System.out.println(page.getPageNum()); //页码
System.out.println(page.getPageSize()); //每页数据条数
System.out.println(page.getTotal()); // 总数据条数
System.out.println(page.getResult()); // 所有数据
10.属性名和字段名不一致
10.1方案一:
使用as 别名
<select id="selectAll" resultType="User">
select id as id,name111 as name,sex111 as sex from user
</select>
10.2方案二: resultMap
<resultMap type="User" id="BASE_RESULT_MAP">
<!--
id: 一般用于主键
column : 列名
property : 属性名
-->
<id column="id" property="id"/>
<result column="name111" property="name"/>
<result column="sex111" property="sex"/>
</resultMap>
<select id="selectAll" resultMap="BASE_RESULT_MAP" >
select * from user
</select>
11.SQL片段
在mybatis中,会出现部分sql内容重复出现,此时可以使用sql标签,将这部分抽离出来,然后在具体的sql标签中,使用includ 包裹,这样组装成新的sql语句
<sql id="BASE_COLUMN">
id,name,sex
</sql>
<select id="page" resultType="User" parameterType="User" >
select
<include refid="BASE_COLUMN" />
from
user
limit #{param1},#{param2}
</select>
作业: 单表增删查改,分页(PageHelper)(代理的形式)
12.DTD文件配置
https://blog.csdn.net/a15920804969/article/details/79107852
13.动态SQL
13.1 什么是动态sql?
根据传递的参数不同,产生的sql语句也不同,即根据传递的参数,动态的产生相应的sql语句
13.2 mybatis中对动态sql支持的语法:
13.2.1 if
<?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.sxt.dao.IStudentMapper">
<sql id="BASE_COLUMN">
id as id,
name as name,
age as age,
sex as sex,
phone as phone,
c_id as cId
</sql>
<select id="query" parameterType="map" resultType="Student">
select
<include refid="BASE_COLUMN" />
from student
where 1=1
<if test="name != null and name != ''">
and name like concat('%',#{name},'%')
</if>
<if test="minAge != null and minAge != ''">
and age >= #{minAge}
</if>
<!--
在xml中 < 等符号 是特殊符号, 若使用 可以改变 方向
也可以<![CDATA[字符串]]>进行转义包裹
-->
<if test="maxAge != null and maxAge != ''">
and #{maxAge} >= age
</if>
<if test="sex != null and sex !=''">
and sex = #{sex}
</if>
<if test="phone != null and phone !=''">
and phone = #{phone}
</if>
</select>
</mapper>
13.2.2choose(when otherwise)
<select id="query2" parameterType="map" resultType="Student">
select
<include refid="BASE_COLUMN" />
from student
<where>
<choose>
<when test="age == 18">
and age = 18
</when>
<when test="age >= 18">
and age >= 18
</when>
<otherwise>
and age > 0
</otherwise>
</choose>
</where>
</select>
13.2.3where
当where标签中if语句成立, sql语句 后面会自动添加where ,且会去掉 紧跟的and
<select id="query" parameterType="map" resultType="Student">
select
<include refid="BASE_COLUMN" />
from student
<where>
<if test="name != null and name != ''">
and name like concat('%',#{name},'%')
</if>
<if test="minAge != null and minAge != ''">
and age >= #{minAge}
</if>
<!-- 在xml中 < 等符号 是特殊符号, 若使用 可以改变 方向 也可以<![CDATA[字符串]]>进行转义包裹 -->
<if test="maxAge != null and maxAge != ''">
and #{maxAge} >= age
</if>
<if test="sex != null and sex !=''">
and sex = #{sex}
</if>
<if test="phone != null and phone !=''">
and phone = #{phone}
</if>
</where>
</select>
13.2.4 set
set标签自动新增set ,且去掉了最后的逗号
13.2.5 foreach
foreach一般用于批量操作.
<!--
foreach 循环
separator : 分隔符 每次循环时 在元素中间添加符好
open : 在循环前新增sql前缀
close : 在循环结束后 在sql后面追加后缀
item : 循环集合中数据项
-->
<select id="batchQuery" parameterType="int[]" resultType="Student">
select <include refid="BASE_COLUMN" />
from student
<foreach collection="array" separator="," item="id" open="where id in (" close=");">
#{id}
</foreach>
</select>
13.2.6 trim
<!--
prefix : 新增前缀
prefixOverrides="and|or" : 去除第一个 and 或者 or
suffix="" 新增后缀
suffixOverrides 去掉后缀
-->
<insert id="insert" parameterType="Student">
insert into student
<trim prefix="(" suffixOverrides="," suffix=")">
<if test="name != null and name !=''">
name,
</if>
<if test="age != null and age !=''">
age,
</if>
<if test="sex != null and sex !=''">
sex,
</if>
<if test="phone != null and phone !=''">
phone,
</if>
<if test="cId != null and cId !=''">
c_id,
</if>
</trim>
<trim prefix=" value (" suffixOverrides="," suffix=")">
<if test="name != null and name !=''">
#{name},
</if>
<if test="age != null and age !=''">
#{age},
</if>
<if test="sex != null and sex !=''">
#{sex},
</if>
<if test="phone != null and phone !=''">
#{phone},
</if>
<if test="cId != null and cId !=''">
#{cId},
</if>
</trim>
</insert>
14.关联表的处理
多对一
方式一:使用连接查询
<!-- 使用连表查询时,一个实体类中要新增属性,建议创建新的类,包含2个表都有的属性 -->
<select id="query" resultType="Student">
select
st.id as id,
st.name as name,
st.age as age,
st.sex as sex,
st.phone as phone,
st.c_id as cId,
cl.name as cName
from student st left join classes cl on st.c_id=cl.id
</select>
<!-- 使用map作为查询结果的接收对象,无需新增属性 -->
<select id="query2" resultType="map">
select
st.id as id,
st.name as name,
st.age as age,
st.sex as sex,
st.phone as phone,
st.c_id as cId,
cl.name as cName
from student st left join classes cl on st.c_id=cl.id
</select>
方式二: 使用mybatis中resultMap,进行结果封装处理
<resultMap type="Student" id="BASE_RESULT_MAP">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<result column="phone" property="phone"/>
<result column="cId" property="cId"/>
<!-- 多对一 -->
<!--
association
|=== property :对象属性
|=== javaType : 属性类
-->
<association property="classes" javaType="Classes">
<id column="cId" property="id"/>
<result column="cName" property="name"/>
</association>
</resultMap>
<!-- 多对一 示例 -->
<select id="query3" resultMap="BASE_RESULT_MAP">
select
st.id as id,
st.name as name,
st.age as age,
st.sex as sex,
st.phone as phone,
st.c_id as cId,
cl.name as cName
from student st left join classes cl on st.c_id=cl.id
</select>
方式三: 遍历查询
StudentMapper.xml
<resultMap type="Student" id="BASE_RESULT_MAP2">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<result column="phone" property="phone"/>
<result column="cId" property="cId"/>
<association property="classes" javaType="Classes" select="com.sxt.dao.IClassesMapper.selectClass" column="cId" ></association>
</resultMap>
<select id="query4" resultMap="BASE_RESULT_MAP2">
select
st.id as id,
st.name as name,
st.age as age,
st.sex as sex,
st.phone as phone,
st.c_id as cId
from student st
</select>
ClassesMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sxt.dao.IClassesMapper">
<select id="selectClass" resultType="Classes">
select id ,name from classes where id=#{id}
</select>
</mapper>
一对多
方式一:根据resultMap将查询结果进行封装处理
注意点: 每个实体类必须要有默认构造方法(无参构造方法)
<resultMap type="Classes" id="BASE_RESULT_MAP1">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="students" javaType="list" ofType="Student" >
<result column="stId" property="id"/>
<result column="stName" property="name"/>
<result column="age" property="age"/>
</collection>
</resultMap>
Student.java
package com.sxt.bean;
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 1543743204388328403L;
private int id;
private String name;
private int age;
private String phone;
private int cId;
public Student() {}
public Student(int id, String name, int age, String sex, String phone, int cId) {
super();
this.id = id;
this.name = name;
this.age = age;
this.phone = phone;
this.cId = cId;
}
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 getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getcId() {
return cId;
}
public void setcId(int cId) {
this.cId = cId;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ", phone=" + phone + ", cId=" + cId + "]";
}
}
Classes.java
package com.sxt.bean;
import java.util.List;
/**
* 班级
* @author mrt
*
*/
public class Classes {
private int id;
private String name;
private List<Student> students ;
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 List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Classes [id=" + id + ", name=" + name + ", students=" + students + "]";
}
}
方式二: 遍历查询
ClassMapper.xml
<resultMap type="Classes" id="BASE_RESULT_MAP2">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--
collection : 1对多
property : 表示多的属性
javaType : 属性Java类型
ofType : 集合中元素的类型
-->
<collection property="students" javaType="java.util.List" ofType="com.sxt.bean.Student" select="com.sxt.dao.IStudentMapper.query5" column="id">
</collection>
</resultMap>
<select id="query2" resultMap="BASE_RESULT_MAP2">
select
cl.id,
cl.name
from classes cl
</select>
StudentMapper.xml
<select id="query5" resultType="Student">
select
st.id as id,
st.name as name,
st.age as age,
st.sex as sex,
st.phone as phone,
st.c_id as cId
from student st where c_id = #{id}
</select>
15.使用注解实现MyBatis
单表增删查改
public interface IUserDao {
@Select("select * from user")
public List<User> selectAll();
@Insert("insert into user value(0,#{name},#{sex})")
public void insert(@Param("name")String name,@Param("sex")String sex);
@Delete("delete from user where id=#{id}")
public void delete(int id);
@Update("update user set name=#{name} ,sex=#{sex} where id=#{id}")
public void update(@Param("id")int id,@Param("name")String name,@Param("sex")String sex);
/**
* 动态sql
* @param map
* @return
*/
@Select("<script>select id,name,sex from user <where><if test='name !=null and name != \"\"'> name like concat('%',#{name},'%')</if></where></script>")
public List<User> selectList(Map<String,Object> map);
}
16.缓存
在mybatis中,缓存分为2种,一级缓存和二级缓存.一级是默认开启的缓存, 作用范围是指同一个session.
一级缓存: 默认缓存
在同一个SqlSession, 若在不关闭SqlSession的情况下,此时若执行一样的sql语句,只会执行一次.会执行缓存,这种就是一级缓存.
二级缓存:SqlSessionFactory 使用同一个SqlSessionFactory时,若执行一样的sql,则会走二级缓存.
虽然二级缓存默认是开启的,但是需要配置.
1.在核心配置文件中:
<!-- mybatis的缓存 默认是 true -->
<setting name="cacheEnabled" value="true"/>
2.在相关mapper文件中
<!-- 启用二级缓存 -->
<cache />
17.MyBatis逆向工程
需要下载:mybatis-generator-core-1.3.2.jar
Generator.java
package com.generator;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
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 Generator {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
// 指定 逆向工程配置文件
File configFile = new File("config.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,callback, warnings);
myBatisGenerator.generate(null);
}
}
config.xml
<?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>
<!-- jdbc 连接包的地址 -->
<classPathEntry location="libs/mysql-connector-java-5.1.47.jar"/>
<!-- 用于标识这个是个什么数据库 -->
<context id="MySQL" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 数据库连接信息 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis01" userId="root" password="root">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 生成模型的包名和位置 -->
<javaModelGenerator targetPackage="com.sxt.pojo" targetProject="src">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成映射文件的包名和位置 -->
<sqlMapGenerator targetPackage="mapper" targetProject="config">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 生成DAO的包名和位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.sxt.dao" targetProject="src">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名 -->
<table tableName="student" domainObjectName="Student" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
</context>
</generatorConfiguration>