dao层:主要进行数据的访问(使用JDBC访问数据库,操作数据库中的数据)
Mybatis中的mapper接口相当于以前的dao,但是区别在于,mapper仅仅是接口,我们不需要提供实体类
创建mybatis的映射文件
映射文件命名规则:实体类+Mapper.xml
一个映射文件对应一个实体类
用于编写sql,访问以及操作表中的数据
存放位置:src/main/resource/与java路径保持一致+mapper
映射文件中的namespace要和mapper接口的全类名保持一致
映射文件中sql语句的id要和mapper接口中的方法名保持一致
Sqlsession:代表java程序和数据库之间的会话
httpsession:表示java程序和浏览器之间的会话
Select查询功能必须设置resultType或resultMap
resultType:设置默认的映射关系
resultMap:设置自定义的映射关系
List.foreach(user -> System.out.println(user))
配置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>
<!--
MyBatis核心配置文件中,标签的顺序:
properties?,settings?,typeAliases?,typeHandlers?,
objectFactory?,objectWrapperFactory?,reflectorFactory?,
plugins?,environments?,databaseIdProvider?,mappers?
-->
<!--引入properties文件-->
<properties resource="jdbc.properties" />
<!--设置类型别名-->
<typeAliases>
<!--
typeAlias:设置某个类型的别名
属性:
type:设置需要设置别名的类型
alias:设置某个类型的别名,若不设置该属性,那么该类型拥有默认的别名,即类名且不区分大小写
-->
<!-- <typeAlias type="com.jwt.mybatis.pojo.User" alias="user"></typeAlias>-->
<!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写-->
<package name="com.jwt.mybatis.pojo"/>
</typeAliases>
<!--
environments:配置多个连接数据库的环境
属性:
default:设置默认使用的环境的id
-->
<environments default="development">
<!--
environment:配置某个具体的环境
属性:
id:表示连接数据库的环境的唯一标识,不能重复
-->
<environment id="development">
<!--
transactionManager:设置事务管理方式
属性:
type="JDBC|MANAGED"
JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事务的提交或回滚需要手动处理
MANAGED:被管理,例如Spring
-->
<transactionManager type="JDBC"/>
<!--
dataSource:配置数据源
属性:
type:设置数据源的类型
type="POOLED|UNPOOLED|JNDI"
POOLED:表示使用数据库连接池缓存数据库连接
UNPOOLED:表示不使用数据库连接池
JNDI:表示使用上下文中的数据源
-->
<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="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/sys?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--引入映射文件-->
<mappers>
<!--<mapper resource="mappers/UserMapper.xml"/>-->
<!--
以包为单位引入映射文件
要求:
1、mapper接口所在的包要和映射文件所在的包一致
2、mapper接口要和映射文件的名字一致
-->
<package name="com.jwt.mybatis.mapper"/>
</mappers>
</configuration>
environments:配置多个连接数据库的环境
default:设置默认使用的环境的id
environment:配置某个具体的环境
id:表示连接数据库的环境的唯一标识,不能重复
transactionManager:设置事务管理方式
type="JDBC|MANAGED"
JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事务的提交或回滚需要手动处理
MANAGED:被管理,例如Spring
dataSource:配置数据源
type:设置数据源的类型 type="POOLED|UNPOOLED|JNDI"
POOLED:表示使用数据库连接池缓存数据库连接
UNPOOLED:表示不使用数据库连接池
JNDI:表示使用上下文中的数据源
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/sys?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="****"/>
</dataSource>
resources下设置多级目录:../../../../..
创建po实体类
实体类与表一一对应
实体类.xml
namespace 表空间:名称最好能跟实体类一致(包名.类名)或者产生标记作用
id:标识,不能重复,相当于dao中的一个方法
resultType:表示当前方法返回结果的数据类型(设置默认的映射关系)
resultMap:(设置自定义的映射关系)
parameterType:表示传入的参数的类型
当方法传入为某一种参数时,可以写具体的数据类型
当方法传入为多种参数时,可以使用map进行映射
select name,location,age from user where name like '%'+?+'%' and age = ?
name是String类型,age是int类型,此时就需要使用parameterType="java.util.Map"来进行映射
<select id="方法名" parameterType="java.util.Map" >
select name,location,age from user where name like #{name} and age = #{age}
<select>
传参
如果有多个参数的时候,mybatis会自动将这些参数放在当前map集合中,以两种方式进行存储arg param
1.arg param
使用arg作为参数的标识的时候,arg0表示第一个参数,arg1表示第二个参数
#{arg0} #{arg1}
使用param作为参数的标识的时候,param1表示第一个参数,param2表示第二个参数
#{param1}#{param2}
2.@Param
参数特定标签
()括号里面加注解(@Param(“具体值”)数据类型 数据)
(@Param("name") String name)
(@Param("age") Integer age)
以param1表示第一个参数,param2表示第二个参数
以@param注解的值为键,以参数为值
3.手动将这些参数放在一个map中进行存储
Map<String,Object>
xml中写入key值,传参传入value
#{具体值}
map.put(具体值,value)
4.mapper接口方法的参数是实体类类型的参数
只需要通过#{}和${}以属性的方式访问属性值,需要注意${}的单引号问题
当传入参数过多时,一般编写一个工具类,专门封装各种参数vo(queryVo)
mybatis获取参数值的两种方式${}和#{}
#{}和${}都可以通过任意的名称获取相对应的参数值,但是需要注意${}的引号问题
#{}:占位符,相当于JDBC中的?,接收传递过来的参数的值
接收过来的名字不重要,值才重要
${}:字符串拼接,一般用于替换列名,多用于排序
比如查询名字,会缺失引号
需要注册映射文件(在mybatis中)
<!--注册映射文件-->
<mappers>
<mapper resource="com/jwt/po/Team.xml"></mapper>
<mapper resource="com/jwt/mapper/TeamMapper.xml"></mapper>
</mappers>
开始测试
读取(加载)配置文件
创建SqlSessionFactory,用来创建SqlSession对象
获取SqlSession对象,其内部封装对数据库表操作的各种方法
通过SqlSession对象,执行sql语句,并接收查询返回的结果
public class AppTest {
@Test
public void test01() throws IOException {
// 1 读取mybatis.xml配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// 2 创建SqlSessionFactory, SqlSessionFactory重量级对象(该类对象的创建,非常消耗资源),
// 用来创建SqlSession对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 3 获取SqlSession对象
// SqlSession对象:对表的具体的增删查改操作,都是基于SqlSession来实现,其内部封装对数据库表操作的各种方法。
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4 通过SqlSession对象,执行sql语句,并接收查询返回的结果。
List<Team> list =sqlSession.selectList("com.jwt.po.Team.findAll");
for (Team team : list){
System.out.println(team);
}
sqlSession.close();
}
}
创建utils.SqlSessionUtils封装SqlSession(工具类 一般都是公共的静态方法)
Mybatis的各种查询功能
1.查询一个实体类对象
返回实体类对象
2.查询一个list集合
返回list集合
3.查询某列数量
返回Integer/int
4.根据id查询用户信息为map集合
Map<String,Object>
返回map
5.查询所有信息为map集合
多个map放到一个list中
List<Map<String,Object>>
或者
在方法上添加注解@MapKey("id") 某个字段的值作为键
如果要把数据转化为map集合的话
如果查询出来的只有一条数据,可以直接转化为map
如果查询出来的有多条数据,要么转化为map类型的list集合,要么在方法上使用注解@MapKey()进行标识
模糊查询
1.用${}代替#{}
2.concat进行字符串拼接
select * from user where username like concat('%',#{username},'%')
3.%两边使用""拼接直接加#{属性名}
select * from user where username like "%"#{username}"%"
批量删除
#{}会自动添加单引号
要使用${}来进行传值
int deleteMore(@Param("ids") String ids)
delete from user where id in (${ids})
自定义映射
数据库字段与字段之间使用的是下划线_
而3实体类属性中用的是驼峰
解决字段名和属性名不一致的情况
1.为字段设置别名,来保证字段名和属性名保持一致
2.设置全局配置,将_自动映射为驼峰式命名()
在mybatis-config中设置
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
3.resultType只能解决默认的映射关系(字段名和属性名一致的情况)
自定义映射的话可以使用resultMap
要自己设置字段与属性的关系
id设置主键的映射关系
result设置普通字段映射关系
字段名与属性名一致也需要设置
property:映射关系中的属性名
column:映射关系中的字段名
<resultMap id="empResultMap" type="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</resultMap>
<select id="getAllEmp" resultMap="empResultMap">
select * from emp;
</select>
多对一
对一的时候,创建1的对象
对多的时候,创建对多的集合
(对一对应对象
对多对应集合)
多对一关系 association
<resultMap id="empResultMapTwo" type="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<!-- association:处理多对一的映射关系
property:需要处理多对一关系的属性名
javaType:该属性的类型(通过反射获取类型中的属性)
-->
<association property="dept" javaType="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
</association>
</resultMap>
<!-- Emp getEmpAndDept(@Param("eid") Integer eid);-->
<select id="getEmpAndDept" resultMap="empResultMapTwo">
select * from emp left join dept on emp.did = dept.did where emp.eid = #{eid};
</select>
一对多关系collections
<resultMap id="deptAndEmpResultMap" type="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<!-- collaction:处理一对多映射关系
ofType:表示集合中的类型-->
<collection property="emps" ofType="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</collection>
</resultMap>
<!-- Dept getDeptAndEmp(@Param("did") Integer did);-->
<select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
select * from dept left join emp on dept.did = emp.did where dept.did = #{did}
</select>
动态SQL
根据特定条件动态拼接SQL语句
1.if
可以根据标签中test属性所对应的表达式决定是否需要拼接
方法1:通过恒成立条件1=1(存在缺陷:如果条件都不成立的话,where条件就是多余)
<resultMap id="empResultMapOne" type="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</resultMap>
<!-- Emp getAll(Emp emp);-->
<select id="getAll" resultMap="empResultMapOne">
select * from emp where 1 = 1
<if test="empName != null and empName != ''">
and emp_name = #{empName}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="email != null and email != ''">
and email = #{email}
</if>
</select>
方法2:where标签
(如果where里面有内容,会自动生成where关键字,可以自动识别把前面多余的and去掉 去不掉后面的and)
(如果where里面没有内容,也不会有where关键字)
使用mybatis,将集合数据存入数据库
<foreach collection="list" item="conf" index="index" separator=",">
(
#{conf.属性名1,jdbcType=INTEGER},
#{conf.属性名2,jdbcType=VARCHAR}, ....
)
</foreach>
2.trim标签
prefix suffix:将trim标签中内容前面或后面添加指定内容
suffixOverrides prefixOverrides:将trim标签中内容前面或后面去除指定内容
3.choose when otherwise 相当于java中的if..else if..else
when至少要有一个 (一个条件成立就不判断其他的了)
otherwise最多只能有一个
4.foreach
collection:需要循环的数组或集合
item:表示数组或集合中的每一个数据
separator:循环体之间的分隔符
open:foreach标签所循环的所有内容的开始符
close:foreach标签所循环的所有内容的结束符(一般就是in)
举例1:批量删除数组
int deleteMore(@Param("eids") Integer[] eids);
<delete id="deleteMore" >
delete from emp where eid in
<!--
collection:表示当前要循环的数组或集合 前面要使用@Param定义
item:表示当前数组或集合中的每一个对象
separator:每一次循环体之间的分隔符 分隔符前后会默认加空格
open:以左括号开始
close:以右括号结束 -->
<foreach collection="eids" item="eid" separator="," open="(" close=")">
#{eid}
</foreach>
</delete>
举例2:通过list集合实现批量添加
不能使用open和close
Arrays.asList()
int addMore(@Param("emps") List<Emp> emps);
<insert id="addMore">
insert into emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)
</foreach>
</insert>
5.sql标签
把经常查询的字段来进行一个记录
在<sql id="">中定义
引用:<include refid="id名">
分页插件
添加依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
在mybatis-config中配置分页插件
<plugins>
<!--设置分页插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
测试
需要在查询之前开启分页
PageHelper.startPage(PageNum,PageSize);
mapper.selectByExample(null)