MyBatis
三层架构包含三层:界面层 业务逻辑层 数据访问层
界面层:接收用户的数据 显示请求的处理结果 (Jsp servlet html)
业务逻辑层:处理业务逻辑
数据访问层:完成对数据库的增删改查操作
三层对应的包:
界面层:controller(servlet)
业务逻辑层:Service包(xxxsercice类)
数据访问层:dao包(xxxDao类)
三层中类的交互:
用户使用界面层–>业务逻辑层–>Dao层–>数据库
三层对应的处理框架:
界面层:–servlet–springMvc(框架)
业务逻辑层:–service类–spring(框架)
数据访问层:–dao类–mybatis(框架)
框架是一个舞台 是一个模板
模板:①规定了一些条款 内容
②加入自己的东西
框架是一个模板:
①框架定义好了一些功能 这些功能是可用的
②可以加入自己的功能 这些功能可以利用框架已经写好的功能
框架:frameWork是整个或部分系统的可重用设计 简单说 框架是一个半成品的软件 定义好了一些基础功能 可重复使用可升级
框架特点:一般不是全能的 不能做所有的事情 是针对某一领域有效 比如MyBatis做数据库强 但是不能做其他的
- myBatis框架:本是apache的一个开源项目iBatis 代码在Github
Github.com 在上面可以搜索关于Java的很多项目
-
MyBatis是sql映射框架
①sqlmapper:sql映射
可以把数据库表中的一行数据 映射为一个Java对象,一行数据可以看作是一个Java对象 操作这个对象相当于操作表中的数据
②Data Access ObjectslDaps:数据访问 对数据库的增删改查操作
MyBatis提供了哪些功能:
①提供了创建Comment Statement Result的能力②提供了执行sql语句的能力 不用我们执行sql
③提供了循环sql 把sql的结果转化为对象 list集合的能力
④提供了关闭资源的能力 不用我们关闭 Connection Statement Result
开发人员:提供sql语句
最后:开发人员提供sql语句–=mybatis处理sql—开发人员得到list集合或Java对象(表中的数据)
总结:mybatis是一个sql映射框架提供的数据库的操作能力 增强的JDBC 使用mybatis 让开发人员集中精力写sql就可以了 不必关心Connection Statement Result的创建销毁 sql的执行
mapper(映射)
第一个入门mybatis的例子
实现步骤:①创建person表
②加入maven的mybatis的坐标 mysql驱动的坐标
③创建实体类person 保存表中的一行数据的
④创建持久层的dao接口定义操作数据库的方法
⑤创建一个mybatis使用的配置文件叫做sql映射文件 用来写sql语句的 一般一个表一个
sql映射文件 这个文件是xml文件
⑥创建mybatis的主配置文件 一个项目就一个主配置文件 主配置文件提供了数据库的连接信息和sql映射文件的位置信息
⑦创建使用mybais类 通过mybatis访问数据库
定义实体类 定义dao层接口 并在同级dao下建立与dao接口相同名字的sql映射文件 一般一张表一个 里面写官方的固定格式
接口名与Mybatis的映射文件名一定要一模一样。
sql mapper文件 sql映射文件配置
<?xml version="1.0" encoding="UTF-8" ?> <!-- sql映射文件 (sql mapper)-- > <!DOCTYPE mapper PUBLIC -------指定约束文件---------- "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--mapper为根元素,namespace指定了命名空间 namespace="接口的全限定名称"--><mapper namespace="com.bdqn.dao.PersonDao"> <!--查询操作--><!--id="dao接口里的方法名" resultType="实体类全限定名称(全类名)"--> <select id="getList" resultType="com.bdqn.entity.Person"> 返回的数据的类型 SELECT * FROM person </select ><!-- 插入操作--> <insert id="insert"> insert into person(id,useName,sex,pass)values (#{id},#{useName},#{sex},#{pass}) </insert> </mapper>
注释:①sql映射文件是用来写sql语句的 mybatis会执行这些sql
约束文件:限制检查当前文件中出现的属性及标签必须符合mybatis的要求
②nameSpace:叫做命名空间 唯一值 可以是自定义的字符串但是不可重复
- 要求使用dao接口的全限定名称(全类名)
③在当前文件中 可以使用特定的标签 表示数据特定的操作
表示查询 select语句
表示更新操作 update语句
表示插入操作 insert语句
表示删除操作 delete语句
点击类名右击选择CopyReference 获取 全限定名称的方法
例:
id要执行的sql的唯一标识 mybatis会使用这个id来找打要执行的sql语句 执行后得到Result 遍历后得到Java的对象的类型在resources(资源)中创建mybaits.xml主配置文件 用来提供数据库的连接信息和sql映射文件位置信息
mybatis主配置文件信息
<?xml version="1.0" encoding="UTF-8" ?>
<!--约束文件-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--myBatis的主配置文件,主要定义了数据库的配置信息 sql映射文件的位置-->
<!--配置信息-->
<configuration>
<!--
properties配置,用于加载外部的配置文件
指定properties文件的位置 从类路径根开始找文件-->
<properties resource=" jdbc.properties"/>
<!-- settings:控制mybatis全局行为-->
<settings>
<!-- 设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 定义自定义的别名 ①type:自定义类型的全限定名称 alias:别名(短小 容易记忆的)-->
<typeAliases>
<!-- <typeAlias type="com.bdqn.entity.Person" alias="ps"></typeAlias>-->
<!-- ②name是包名 这个包中所有的类 类名就是别名(类名不区分大小写)-->
<package name="com.bdqn.entity"/>
</typeAliases>
<!-- 主配置文件中配置插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins> 插件放在环境上面<environments>
<!--environments主要用与数据源的配置 数据库的连接信息
可以配置多个数据源,
通过default=“数据源id”指定-->
<environments default="development"><!--使用的是id为development的数据源-->
<!--
environment:用于配置一个具体的独立的数据源
id属性是一个唯一值 用于给当前数据源定义一个名称,方便我们在上一级environments中指定
-->
<environment id="development">
<!--
transactionManager:用于配置事务管理,事务管理默认使用的jdbc管理
-->
<transactionManager type="JDBC"/>
<!--
dataSource:具体数据源的连接信息
type:用于指定是否使用连接池
这里type="POOLED"代表使用连接池
-->
<dataSource type="POOLED">
<!--value是从properties中取到的-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/shun?useUnicode=true&characterEncoding=utf8"/>
<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="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pass}"/>
</dataSource>
</environment>
</environments>
<!--
mappers:只要用于配置我们外部的映射配置文件
在主配置中需要引入加载映射配置文件
-->
<mappers>
<!-- (sql mapper) sql映射文件的位置
mapper:主要配置引入某一个具体的映射文件,
resource:进行路径方式引入
-->
<!-- 一个mapper标签指定一个文件的位置
从类路径开始的路径信息 代码编译后生成 target/classes(类路径) 不需要写target/classes
-->
<!-- <mapper resource="com/bdqn/dao/PersonDao.xml"></mapper>-->
<!-- 当天需要因为入的映射文件多的时候 使用<package/>
要求①mapper文件名称需要和接口名称一样 区分大小写一样
②mapper文件和dao接口需要在同一级目录
-->
<package name="com.bdqn.dao"/>
</mappers>
</configuration>
environment(环境)配置:数据库的连接信息
default:必须和某个environment的id值一样 告诉mybatis使用哪个数据库的信息 也就是访问哪个数据库
执行刚才示例操作的最后一步 创建使用nybatis类 通过mybatis访问数据库
使用步骤:
-
访问mybatis读取student 数据
①定义mybatis猪配置文件的名称 从类路径的根开始(target/classes)
String config=“mybatis.xml”;
②读取这个config表示的文件
InoutStream in=Resources.getResourceASStream(config);
③创建sqlSessionFactoryBuilder对象
sqlSessionfactoryBuilder builder=new sqlSessionfactoryBuilder();
④创建sqlSessionFactory对象
sqlSessionFactiory factory=builder.build(in);
⑤获取sqlsession对象 从sqlSessionFacetory中获取(重要)
SqlSession sqlsession=factory.openSession() 里面参数为true时候 默认提交事务 不然则非默认提交事务
⑥指定要执行的sql语句的标识 sql映射文件中的namespace+“.”+标签id值即和方法名一样
Strign sqlId=“com.bdqn.dao.personDao . getList”
⑦执行sql语句 通过sql id找到语句
List list=sqlSession.selectList(sqlId);
⑧输出结果
总结:
mybatis:
*作用:增强的JDBC访问数据库 执行增删改查
基本步骤:①加入maven依赖
<!-- 添加myBatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!-- 添加数据库依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.32</version> </dependency>
②创建dao接口 定义了操作数据库方法
③创建mapper文件也叫做sql映射文件 写sql语句的和接口中的方法对应的sql语句
④创建mybatis的主配置文件 1.连接数据库 2.指定mapper文件的位置路径
⑤使用mybatis对象 sqlsession通过他的不同方法执行sql语句
① 第一个入门的mybatis例子
第一个入门的mybatis例子 //访问mybatis读取person数据 //步骤:①定义mybatis主配置文件的名称 从类路径的根开始(target/classes) String config="myBatis.xml";// ②读取这个config表示的文件 InputStream in=Resources.getResourceAsStream(config); // ③创建sqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();// ④创建sqlSessionFactory对象 SqlSessionFactory factory= builder.build(in);// ⑤获取sqlSession对象 从sqlSessionFactory中获取 (重要) SqlSession sqlSession=factory.openSession(); ⑥指定要执行的sql语句的标识 sql映射文件中的nameSpace+"."+"标签id值" (重要) String sqlId="com.bdqn.dao.PersonDao.getList";// ⑦执行sql语句通过sqlId找到语句 List<Person> pp=sqlSession.selectList(sqlId);// ⑧输出结果 for (Person p:pp){ System.out.println("查询的Person"+p); } sqlSession.close();
添加操作:
①在dao接口添加执行的接口
②在sql映射文件中添加
inser into person(id,name,sex,pass)values(#{id},#{name},#{sex},#{pass});
//使用#{}相当于占位符 其实就是JDBC的PreparedStatement中的??? 可以防止sql注入
#{}里的值必须和实体类的一致 例#{age}这个过程是通过反射来做的**
**${}一般会用于在模糊查询的情况**
</insert>
**③一张表 一般一个sql映射文件 弄好之后在主配置文件中添加sql映射文件的路径信息**
④创建使用mybatis类 有固定模板 只需把执行的sql标识更改要执行的方法即可 然后创建一个数据对象 sqlsession调用insert(sql标识,obj)返回整数 一定要开启提交事务 sqlSession.commit();
* mybatis不会默认提交事务 所以在增删改操作后要手动提交事务sqlSession.commit();
或者在获取sqlSession对象的时候factory调用的openSession()参数为true时 自动提交事务
否非自动提交事务
-
开启日志可得到执行的过程信息 把日志打印到控制台
<!-- settings:控制mybatis全局行为--> -----打印日志-------- <settings> <!--设置mybatis输出日志--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
sqlSession执行的操作方法不同返回的类型也不同
-
增删改 返回的是整数型
- 查询的话 返回的可以是单个对象或者集合
查询select(sql标识)
添加insert(sql标识,传的数据对象)
-----------------------------------------------------------------------------------------------------------------------------主要类的介绍:
①Resource:mybatis中的一个类 负责读取主配置文件
String config=“myBatis.xml”;
InputStream in= Resources.getResourceAsStream(config);
②sqlSessionFactoryBuilder:创建
```java
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
sqlSessionfactory factory= builder.build(in);
③sqlSessionFactory:重量级对象 创建对象耗时较长 使用资源较多 在整个项目中有一个就够用了
sqlSessionFactory接口:接口实现类defaultsqlSessionFactory()
作用:获取sqlsession对象
sqlSession sqlsession=factort.openSession();
-
openSession方法说明
openSession() 无参数的 非自动提交事务的sqlsession
openSession(true) 参数为true的 自动提交事务的sqlsession
sqlsession是一个接口 定义了操作数据库的方法 例如
-
selectone()
-
selectList()
-
insert()
-
update()
-
delete()
-
commit()
-
rollback
使用sqlsession对象不是线程安全的 需要在方法内部中使用 在执行sql语句之前 使用opensession()
获取session() 在执行完成后关闭它sqlsession.close() 可以保证它使用是线程安全的
把重复的操作封装MybatisUtils工具类
由于sqlSessionFactory() 是重量级对象 占用资源大 所以一个项目只需创建一个就够用了 所以把创建它放在静态代码块中 只能被执行一次 不用每次调用都新new一个 浪费资源 在虚拟机加载类的时候被执行 且只执行一次
静态代码块:
static {
}
-
它是随着类的加载机制而执行且只执行一次 并优先于主函数 在代码块设计中可用来创建单例的对象 不用每次调用一个相同的对象的时候都要重新new一次 提高性能
mybatis封装的工具类 //由于sqlSessionFactory是重量级对象 创建对象时候耗时较长 占用资源较大 整个项目只有一个就够用了 //不用每次调用时候都要new一个新的 所以把它放在静态代码块中在虚拟机加载类的时候就会被执行 而且只执行一次 private static SqlSessionFactory factory=null; static { //访问mybatis读取person数据 //步骤:①定义mybatis主配置文件的名称 从类路径的根开始(target/classes) String config="myBatis.xml"; ②读取这个config表示的文件 try { InputStream in= Resources.getResourceAsStream(config); SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();// ④创建sqlSessionFactory对象 factory= builder.build(in); //重量级对象 创建对象耗时较长 使用资源较多 整个项目有一个就够用了 } catch (IOException e) { e.printStackTrace(); } ③创建sqlSessionFactoryBuilder对象 } /** *实现功能描述:获取sqlSession的方法 *@param *@return org.apache.ibatis.session.SqlSession */ public static SqlSession getSqlSession(){ SqlSession sqlSession=null; if(factory!=null){ // ⑤获取sqlSession对象,从sqlSessionFactory中获取 (重要) sqlSession=factory.openSession();//非自动提交事务 参数为true时候 自动提交事务 } return sqlSession; }
-
-
②传统dao执行操作
public List<Person> getList() {
SqlSession sqlSession=MybatisUtil.getSqlSession();//
指定要执行的sql语句的标识 sql映射文件中的nameSpace+"."+"标签id值" (重要)
String sqlId="com.bdqn.dao.PersonDao.getList";
List<Person> list=sqlSession.selectList(sqlId);// sqlSession.close();//关闭
return list;
}
③动态代理:
使用动态代理条件分析:
例:测试类中personDao pp=new personDao();
List list=pp,selectPerson()
- List list=pp,selectPerson();
①dao对象类型是personDao 全限定名称 com.bdqn.dao.personDao 全限定名称和naemSpace一样
②dao调用的方法名称 selectPerson 这个方法名就是mapper文件中的id值
通过dao调用的方法的返回值也可以确定 mybaits要调用的sqlsession方法
-
若返回值为list 则调用的是selectList()方法
-
若返回值为int 或者非list 看mapper文件中的标签是insert还是update就会调用sqlsession的insert()
-
或者update()方法
mybatis的动态代理:mybatis根据dao方法的调用 获取执行sql语句的信息 mybatis根据dao接口
创建出一个dao接口的实现类 并创建这个接口的对象 完成sqlSession调用方法 访问数据库
简单的来说就是不用自己去创建dao的实现类了 且mybatis的动态代理会帮我们创建出来一个dao接口的实现类
动态代理getMapper
通过自己封装的工具类获取sqlsession对象 在通过 sqlSession.getMapper(接口类名.class)
获取personDao对象 对象再.里面的方法即可完成操作
通过 sqlSession.getMapper(接口类名.class) 获取动态代理对象com.sun.proxy.$proxy2
paramentherType使用:dao接口中方法参数的数据类型 ------(了解就行)
paramentherType它的值是java类型的全限定名称(例如:java.lang.Integer)或是mybatis定义的别名(例如:int)
paramentheType不是强制的 mybatis通过反射机制能够发现接口参数的类型 可以没有 一般不写
**一个简单类型的参数:**简单类型 mybatis把java的基本数据类型和String都叫做简单类型
**在mapper文件中获取简单类型的一个参数的值使用#{}**任意字符
public void show5(){ //①通过自己封装的工具类获取sqlSession对象 SqlSession sqlSession = MybatisUtil.getSqlSession(); // ②通过getMapper获取接口类的对象 PersonDao dao = sqlSession.getMapper(PersonDao.class); //参数为接口.class System.out.println("dao="+dao.getClass().getName());//获取dao类型名字 //dao=com.sun.proxy.$Proxy3 JDK的动态代理 // ③通过接口的对象获取他里面要执行的方法 List<Person> pp=dao.getList(); for (int i = 0; i < pp.size(); i++) { Person p=pp.get(i); System.out.println(p); } //或者--------------------> for (Person person:pp){ System.out.println(person); } }
mybatis是封装的JDBC操作:
使用#{}后 mybatis执行sql是使用JDBC中的prepareStatement对象 由mybatis执行下面代码mybatis创建Connection prepareStatement Result 对象
String sql=“select * from person where id=?”;
prepareStatement pst=conn.prepareStatement(sql);
pst.setInt(15);
以下操作与之前的JDBC操作相同
mybatis中当需要传多个参数的时候 不能直接传 需要使用命名参数或者对象参数传递
命名参数: (推荐使用)
多个参数时候 使用@param命名参数 在形参定义的前面加入 @Param(“自定义的参数名称”)
例如: List list(@Param("myId) Integet id,@Param(“myName”) String name);
List<Person> personList (@Param("myId") Integer id,@Param("myPass") String pass);
mapper文件中 多个参数时候 使用@Param命名
例如:select * from person where id=#{“myId”} or name=#{“myName”);
<select id="personList" resultType="com.bdqn.entity.Person"> select * from person where id=#{myId} or pass=#{myPass}; </select>
操作完成之后 sqlsession.close();
对象参数:
把参数封装为一个对象进行传递参数
按位置传参(不用记)
通过Map传参(不用记)
需要传递多个参数的时候使用命名参数或者对象参数
两个占位符的比较
**#**占位符 告诉mybatis使用实际的参数值代替并使用 PreparStatement对象执行sql语句#{}代替sql语句的? 避免sql注入 这样做更安全 更迅速 也是首选的做法
** ∗ ∗ 字符串替换告诉 m y b a t i s 使用 **字符串替换 告诉mybatis使用 ∗∗字符串替换告诉mybatis使用中包含的 '字符串’替换所在的位置 使用statement把sql语句和${}的内容连接起来的 执行效率低 $有sql注入的风险 缺乏安全性主要用在替换表名字 列名 不同列排序等的操作
$可以替换表名或者列名 能确定数据是安全的情况下 可以使用 select*from person order by ${id}
$和#区别===》
**#**①#使用了占位符在sql语句中占位的使用prepareStatement执行sql效率高
②使用#避免sql注入 更安全
**$**① $不使用占位符 是字符串连接的方式 使用statement对象 执行sql效率低
②$有sql注入的风险 缺乏安全性
③$用于替换表名或者列名
执行的时候: $==>select * from person order by id asc
#==>select * from person order by ?asc
ASC升序 DESC降序
排序的时候使用 #{} 则无效果
用 $来替换表名或者列名
复习:
mybatis:
Ⅰ.作用:增强的JDBC访问数据库 执行增删改查操作
Ⅱ.基本步骤:①加入maven依赖 mybatis和mysql驱动坐标
②创建dao接口 定义了操作mysql的方法
③常见mapper文件也叫sql映射文件 用来写sql语句的 和接口中的方法对应的sql语句
④创建mybatis的一个主配置文件 1.连接数据库 2.指定mapper文件的位置
⑤使用mybatis的对象 sqlSession通过他的方法执行sql语句
Ⅲ.使用mybatis的动态代理
① 什么是动态代理:mybatis会帮你创建dao接口的实现类 在实现类中调用sqlSession的方法执行sql语句
②使用动态代理的方式
1.获取sqlSession对象sqlSessionFactory.openSession()
2.使用getMapper方法获取某个接口的对象 sqlSession.getMapper(接口.class)
3.使用dao接口的方法 调用方法要执行的方法 就执行了mapper文件中的sql语句
③使用动态代理方式的要求 1.dao接口和mapper文件在同一级目录
2.dao接口和mapper文件名一致
mapper文件的nameSpace值是接口的全限定名称
④mapper文件中的 等id是接口中方法的名称
⑤dai接口中不要使用重载方法 不要使用同名不同参的方法
Ⅳ理解参数
从java代码把实际的值传入到mapper中
①一个简单类型的参数:#{任意字符}
②多个简单类型的参数:
1.使用@param(“自定义的名称”)
例如: List list(@Param("myId) Integet id,@Param(“myName”) String name);
2.使用一个java对象 对象的属性为mapper文件找到参数#{Java对象的属性名称}
3.使用参数的位置 #{arg0}# {arg1}
4.使用mapper作为参数 #{map的key}
#和$的区别
①#使用占位符 表示列值的 放在等号的右侧
②$不使用占位符 表示字符串连接的 把sql语句连接成一个字符串
③#使用JDBC的prepareStatement执行sql 安全性高
使用 J D B C 的 s t a t e m e n t 执行 s q l 有注入危险 ∗ ∗ 所以 使用JDBC的statement执行sql有注入危险 **所以 使用JDBC的statement执行sql有注入危险∗∗所以常用于替换表名或者列名**
排序的时候只能使用${} 否则排序无效果
替换表名的时候只能使用${} 因为其使用的是statement 若#{}使用的是prepareStatement则?代替
会出现错误
细节:#{}里面的参数名称 是通过接口传的参数来判断参数占位符名称是随意的还是指定的 但是最好是与所有属性名称一致
① reultType:的使用resultType的结果类型 可以是全限定名称或者别名
mybatis的输出结果 mybatis执行了sql语句 得到Java对象
resultType结果类型 指sql语句执行完毕后 数据转化为Java的对象
resultType也可以是其他与查询出来的字段相匹配的实体类 (需要自己手动创建实体类)
定义别名:若查询总条数或处理接收返回结果的类型 即int类型的
使用全限定名称 java.lang.Interger或者别名int
<select id="countList" reultType="java.lang.Interget"> 全限定名称 或者 <select id="countList" resultType="int"> 别名
② 定义自定类的别名的几种方式 (主要用全限定名称 --安全)
1.<typeAliases> (不推荐) type:自定义类型的全限定名称 alias:别名 (短小 容易记忆的) <typeAlias type="com.bdqn.entity.Person" alias="ps"> </typeAliases> 2.<package> (常用)但是有弊端 <package> name是包名 这个包中所有类 类名就是别名(类名不区分大小写) <package name="com.bdqn.entity"/> 缺点: 若不同包下的相同类名 则会报错-->重复 这个<package>也放在<typeAliases>中
查询返回map 1.列名是map的key 2. 列值是map的value
返回map的时候 数据只能是一行的记录 多于一行 会报错
resultType:叫做结果映射类型指定列名和java对象属性的对应关系 resultType已帮我们映射好
resultMap:
①当自定义列值赋给哪个属性 ②当列名和属性名不一致的时候 一定使用resultMap
设置结果映射类型
while(res.next){
person.setId(res.getInt(“id”)) mybatis进行自动进行操作的时候 属性和列名必须一致 不然赋值不上
因为mybatis是通过映射自动完成赋值的
}
映射到JavaBean的简单类型属性
自定义列值赋给哪个属性 <resultMap id="personMap" type="com.bdqn.entity.Person"> id是自定义名称 <!-- 主键列用 <id column="id" property="id"/>--> <id column="id" property="id"/> ==== <!-- 非主键列用 <result column="useName" property="name"/>--> <!-- column 是字段名 property 是对应的属性名--> <result column="useName" property="useName"/> === <result column="sex" property="sex"/> === <result column="pass" property="pass"/> === </resultMap> <!-- ② 设置结果映射类型--> <select id="personListSame" resultMap="personMap">这里填的自定义的名称 SELECT id,useName,sex,pass FROM person </select>
JavaBean内部嵌套一个复杂数据类型(JavaBean)属性 association 一对一
javaType:完整Java类名或别名。
property:映射数据库列的实体对象的属性。
id。设置该项可以有效地提升MyBatis的性能。
result。property:映射数据库列的实体类对象的属性。 column:数据库列名或别名<resultMap id="billProvideResult" type="com.bdqn.entity.Bill" > <id property="id" column="id"/> <result property="billCode" column="billCode"/> <result property="productName" column="productName"/> <result property="totalPrice" column="totalPrice"/> <result property="isPayment" column="isPayment"/> <!--property是在实体类中的属性名称 javaType是属性的数据类型--> <!-- 通过association进行provider对象赋值 --> <association property="provider" javaType="com.bdqn.entity.Provider"> <id column="id" property="id"/> <result column="proCode" property="proCode"/> <result column="proName" property="proName"/> <result column="proContact" property="proContact"/> <result column="proPhone" property="proPhone"/> </association> </resultMap>
association仅处理一对一的关联关系。
association复用
association提供了另一个属性:resultMap。通过这个属性可以扩展一个resultMap来进行联合映射
<resultMap id="Repeat" type="com.bdqn.entity.Provider">通过id 进行Provider结果映射复用 <id column="id" property="id"/> <result column="proCode" property="proCode"/> <result column="proName" property="proName"/> <result column="proContact" property="proContact"/> <result column="proPhone" property="proPhone"/> </resultMap>
JavaBean内部嵌套一个复杂数据类型(集合)属性
collection一对多
property:映射数据库列的实体对象的属性
ofType:完整java类名或者别名(集合中所包括的类型)
resultMap:引用外部的resulMap
<resultMap id="billProvideResult" type="com.bdqn.entity.Bill" > <id property="id" column="id"/> <result property="billCode" column="billCode"/> <result property="productName" column="productName"/> <result property="totalPrice" column="totalPrice"/> <result property="isPayment" column="isPayment"/> //嵌套一个复杂数据类型(集合)属性进行赋值 <collection property="java类中集合的名字" ofType="java类中集合中的实体全类名"> <id property="" cloumn=""/> <result property="" cloumn=""/> </collection> </resultMap>
resultType和resultMap不可以一起用
当不使用mybatis执行查询操作的时候 实体类可以不与表中列名一致 因为是手动进行赋值的
使用mybatis执行查询操作的时候实体类属性则必须和列名一致 因为mybatis是通过映射自动完成赋值操作的
mybatis会根据查询的列名 将列名转化为小写 去进行设置(列名setter方法 )
解决数据库表的列名和实体类的属性不一致的问题
当不使用mybatis执行查询的时候 实体类中的属性可以不和数据库表中的列名必须一致
但是若mybatis执行查询操作的时候 实体类中的属性必须和数据库表中的列名一致 因为是mybatis通过映射自动完成赋值操作的
原因:Mybatis会根据查询的列名 (会将列名转化为小写) 去进行设值(列名setter方法)
如果匹配不到则为空值
①通过设置别名和Java实体类的属性名一致
<select id="personListSame" resultType="com.bdqn.entity.Person">实体类的全限定名称 SELECT id,useName as name,sex,pass FROM person </select>
②设置结果映射类型
<resultMap id="personMap" type="com.bdqn.entity.Person"> <!-- 主键列用 <id column="id" property="id"/>--> <id column="id" property="id"/> === <!-- 非主键列用 <result column="useName" property="name"/>--> <!-- column 是字段名 property 是对应的实体类属性名--> <result column="useName" property="name"/> === <result column="sex" property="sex"/> === <result column="pass" property="pass"/> === </resultMap> <select id="personListSame" resultMap="personMap"> 和命名的一样 SELECT id,useName,sex,pass FROM person </select>
这里推荐resultMap 因为当需要设置字段多的时候 别名AS就繁琐了.
resultType和restulMap不可以一起用
resultMap:结果映射 指定列名和Java对象的属性对应关系
🐟 自定义列值赋给哪个属性
🐟 当列名和属性名不一样时 一定使用resultMap
like查询的两种方案
①Java代码指定like的内容(推荐)
例: String name =“%李%” (传)
select * from person where useName like #{useName}
把该变量当参数传递
② 在mapper文件中拼接"%" 李 “%” String name=“李”(传)
select * from person where name like "%" #{name} "%";
模糊查询中 like ‘张_’ 表示张后面一个字符的数据
like ‘张%’ 表示张后面任意长度的数据
like '%张%'只要包含张的数据
ctrl+alt+o 快捷键 相框内识别文字
动态sql===》
动态sql–if
<select id="selectPerson" resultType="com.bdqn.entity.Person"> select * from person where <if test="useName!=null" and useName!=""> useName=#{useName} </if> <if test="age>0"> or age=#{age} </if> </select>
<if test=“使用参数 Java对象的属性值作为判断条件”
语法: 属性=XXX值 动态sql==》使用java对象作为参数
<if test="使用参数Java对象的属性值作为判断条件" ></if>
例:<if test="age>0"> 这里age 数据库列名<---age=#{age} </if>
当条件不满足导致语法规则不正确时 在where后加1=1 或id>0 或者其他可以组成正确语法的均可
动态sql–where
用来包含多个的 当多个 有一个成立 会自动增加一个where关键字 并去掉 if中的多余的 or and 等
<where> <if test="name!=null and name!=''"> name=#{name} </if> </where>
动态sql–foreach
StringBuilder builder=new StringBuilder();
拼接字符 builder.append()
builder.deleteCharAt( builder.length()-1 ); 删除 最后一个字符 下标是从0开始的
mybatis会帮助我们完成操作
使用
方式① list集合中为基本类型 不是对象的情况下
<select id="getList" resultType="com.bdqn.entity.Person"> select * from where id in <foreach collection="list" item="str" open="(" close=")" separator=","> #{str} </foreach> </select>
collection:表示接口中方法参数的类型 如果是数组使用arrays 如果是集合list使用 list (小写的)
iteam:自定义的表示数组或者集合成员的变量
open:循环开始时的字符 close:循环结束时的字符
separator:集合成员之间的分隔符
方式 ② list集合中为对象时
<select id="getList" resultType="com.bdqn.entity.Person"> select * from where id in <foreach collection="list" iteam="str" open="(" close=")" separator=","> #{str.id} //通过对象获取其属性 </foreach> </select>
动态sql—代码片段
代码片段:复用代码的一种快捷键 把反复用的代码 定义为一个代码片段
语法规则:
<sql id="studentSql"> 自定义的名称唯一的 //里面是重复用的sql(可以是完整的 或者表名等) </sql>
引用:<include refid="定义的唯一的名称"/>
动态sql总结:
根据条件得到不同的sql语句 使用mybatis的标签 if:判断条件的 条件为true执行if之间的sql
添加到主sql之后
where:里面是多个if 如果有一个if判断为true 在sql后加上一个where关键字 会去掉无用的and or 等字符
foreach:循环数组 list集合
sql代码片段:复用sql语句的 ①先定义<sql id="自定义的唯一值"> sql语句 表名字段等 </sql> ②再使用<include refid="id的值"/>
数据库的属性配置文件:
把数据库的连接信息 放到一个单独的文件中和mybatis的主配置文件分开 便于修改和保存处理多个 数据库的信息
①在resouces目录中定义一个属性配置文件 xxx.properties 格式是key-value 一般使用"."做多级目录
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/shunuseUnicode=true&characterEncoding=utf8 jdbc.user=rootjdbc.pass=root
②在mybatis的主配置文件 使用指定文件的位置 从类路径根 开始找文件即resource下 在需要使用值的地方${key}
<!-- properties配置,用于加载外部的配置文件 指定properties文件的位置 从类路径根开始找文件--> <properties resource=" jdbc.properties"/>
指定多个mapper文件的方式
①在标签中 再添加一个 映射文件路径
若有100个映射文件则太麻烦
②使用包名
<package name="com.bdqn.dao"/>
name:xml文件mapper映射文件所在的包名 这个包中所有的xml文件 一次性都能加载给mybatis
使用package的要求:
①mapper文件名称需要和接口名称一样 区分大小写
②mapper文件和dai接口需要在同一级目录
例如: 全包名
拓展:
pageHelper 用来数据分页的 mybatis通用分页插件 支持多种数据库但不同数据库分页语法不一样
pageHelper不是mybatis框架的 是国内作者写的一个小功能组件
步骤:
🐟①在pom.xml中添加PageHelper依赖
<!-- 添加PageHelper依赖--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version> </dependency> </dependencies>
🐟②主配置文件中配置插件
<!-- 主配置文件中配置插件--> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> </plugin> </plugins>
🐟③测试通过PageHelper.starPage() 一定放在查询结果的前面
总结:mybatis主配置文件 Ⅰ数据库属性配置文件的使用 Ⅱ mapper文件的位置
-
mappers标签中添加一个 一次只能引一个sql映射文件
-
package name=“全包名” 一次能加载给mybatis全部
-
PageHelper分页
①功能:实现数据库的分页mysql就是代替limit语句的
②使用步骤:1.加入maven依赖 2.主配置文件中配置插件 告诉mybatis要用它
③查询方法之前 加入PageHelper.starPage(pageNum,pageSize)
pageNum:代表从第几页开始查询
pageSize:代表每页有多少条数据
PageHelper.startPage会返回一个page对象,这个对象在查询结果出来后会把页数,记录总数给page对象,
你用page.getPages()和getTotal()获取页数和记录总数。
PageHelper是MyBatis的分页查询的插件。
-