MyBatis
来源:互联网 发布:win10 linux bash 编辑:程序博客网 时间:2024/05/22 17:10
为什么要使用MyBatis?
- MyBatis是介于纯手工的JDBC和全自动的Hibernate之间的一个半自动化的持久层框架。
- JDBC:SQL夹杂在Java代码块里,耦合度高,维护不易且实际开发需求中sql有变化时改起来太麻烦了,而且功能简单
- Hibernate是一种全自动的框架,旨在消除sql,开发人员即使不懂任何sql语句,也能实现对象与数据记录之间的映射,简单的运用还是非常方便的。但是因为sql命令都是Hibernate内部自动生产的,不容易做特殊优化,如果要实现复杂查询的定制语句,还需要学习HDL,增大了学习的负担。
- 对于开发人员而言,核心sql还是需要自己定制和优化的,MyBatis将sql和java编码分开,功能边界清晰,一个专注数据,一个专注业务。
接口文件和XML
接口文件EmployeeMapper.java
package com.zc.mybatis.dao;import com.zc.mybatis.bean.Employee;public interface EmployeeMapper { //传入单个参数:mybatis不会做特殊处理, //#{参数名/任意名}:取出参数值 public Employee getEmpById(Integer id); /*多个参数:mybatis会做特殊处理。 多个参数会被封装成 一个map, key:param1...paramN,或者参数的索引也可以 value:传入的参数值 #{}就是从map中获取指定的key的值; 【命名参数】:明确指定封装参数时map的key;@Param("id") 多个参数会被封装成 一个map, key:使用@Param注解指定的值 value:参数值 #{指定的key}取出对应的参数值*/ public Employee getEmpByIdAndLastName(@Param("id")Integer id,@Param("lastName")String lastName);}//select返回List public List<Employee> getEmpsByLastNameLike(String lastName);
XML文件EmployeeMapper.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.zc.mybatis.dao.EmployeeMapper"><!-- namespace:名称空间;指定为接口的全类名id:唯一标识resultType:返回值类型#{id}:从传递过来的参数中取出id值public Employee getEmpById(Integer id); --> <select id="getEmpById" resultType="com.zc.mybatis.bean.Employee"> select id,last_name lastName,email,gender from tbl_employee where id = #{id} </select> <!-- public Employee getEmpByIdAndLastName(Integer id,String lastName);--> <select id="getEmpByIdAndLastName" resultType="com.zc.mybatis.bean.Employee"> select * from tbl_employee where id = #{id} and last_name=#{lastName} </select> <!-- public List<Employee> getEmpsByLastNameLike(String lastName); --> <!--resultType:如果返回的是一个集合,要写集合中元素的类型 --> <select id="getEmpsByLastNameLike" resultType="com.atguigu.mybatis.bean.Employee"> select * from tbl_employee where last_name like #{lastName} </select></mapper>
MyBatis的全局配置文件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> <!-- 1、mybatis可以使用properties来引入外部properties配置文件的内容; resource:引入类路径下的资源 url:引入网络路径或者磁盘路径下的资源 --> <properties resource="dbconfig.properties"></properties> <!-- 2、settings包含很多重要的设置项 setting:用来设置每一个设置项 name:设置项名 value:设置项取值 --> <!--是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。--> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!-- 3、typeAliases:别名处理器:可以为我们的java类型起别名 别名不区分大小写 --> <typeAliases> <!-- 1、typeAlias:为某个java类型起别名 type:指定要起别名的类型全类名;默认别名就是类名小写;employee alias:指定新的别名 --> <!-- <typeAlias type="com.zc.mybatis.bean.Employee" alias="emp"/> --> <!-- 2、package:为某个包下的所有类批量起别名 name:指定包名(为当前包以及下面所有的后代包的每一个类都起一个默认别名(类名小写),) --> <package name="com.zc.mybatis.bean"/> <!-- 3、批量起别名的情况下,使用@Alias注解为某个类型指定新的别名 --> </typeAliases> <!-- 4、environments:环境们,mybatis可以配置多种环境 ,default指定使用某种环境。可以达到快速切换环境。 environment:配置一个具体的环境信息;必须有两个标签;id代表当前环境的唯一标识 transactionManager:事务管理器; type:事务管理器的类型;JDBC(JdbcTransactionFactory)|MANAGED(ManagedTransactionFactory) 自定义事务管理器:实现TransactionFactory接口.type指定为全类名 dataSource:数据源; type:数据源类型;UNPOOLED(UnpooledDataSourceFactory) |POOLED(PooledDataSourceFactory) |JNDI(JndiDataSourceFactory) 自定义数据源:实现DataSourceFactory接口,type是全类名 --> <environments default="dev_mysql"> <environment id="dev_mysql"> <transactionManager type="JDBC"></transactionManager> <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="dev_oracle"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${orcl.driver}" /> <property name="url" value="${orcl.url}" /> <property name="username" value="${orcl.username}" /> <property name="password" value="${orcl.password}" /> </dataSource> </environment> </environments> <!-- 5、databaseIdProvider:支持多数据库厂商的; type="DB_VENDOR":VendorDatabaseIdProvider 作用就是得到数据库厂商的标识(驱动getDatabaseProductName()),mybatis就能根据数据库厂商标识来执行不同的sql; MySQL,Oracle,SQL Server,xxxx --> <databaseIdProvider type="DB_VENDOR"> <!-- 为不同的数据库厂商起别名 --> <property name="MySQL" value="mysql"/> <property name="Oracle" value="oracle"/> <property name="SQL Server" value="sqlserver"/> </databaseIdProvider> <!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 --> <!-- 6、mappers:将sql映射注册到全局配置中 --> <mappers> <!-- mapper:注册一个sql映射 注册配置文件 resource:引用类路径下的sql映射文件 mybatis/mapper/EmployeeMapper.xml url:引用网路路径或者磁盘路径下的sql映射文件 file:///var/mappers/AuthorMapper.xml 注册接口 class:引用(注册)接口, 1、有sql映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下; 2、没有sql映射文件,所有的sql都是利用注解写在接口上; 推荐: 比较重要的,复杂的Dao接口我们来写sql映射文件 不重要,简单的Dao接口为了开发快速可以使用注解; --> <!-- <mapper resource="mybatis/mapper/EmployeeMapper.xml"/> --> <!-- <mapper class="com.zc.mybatis.dao.EmployeeMapperAnnotation"/> --> <!-- 批量注册: --> <package name="com.zc.mybatis.dao"/> </mappers></configuration>
参数处理
单个参数:MyBatis不会做特殊处理。 #{参数名}:取出参数值。
public Employee getEmpById(Integer id);
多个参数:MyBatis会做特殊处理,多个参数会被封装成一个map。要使用命名@Param("参数名")
明确指定封装参数时map的key。
key:使用@Param注解指定的值。
value:参数值
使用#{指定的key}就可以取出对应的参数值。
<!--public Employee getEmpByIdAndLastName(@Param("id")Integer id,@Param("lastName")String lastName);--> <select id="getEmpByIdAndLastName" resultType="com.atguigu.mybatis.bean.Employee"> select * from tbl_employee where id = #{id} and last_name=#{lastName} </select>
POJO: 如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入POJO。#{属性名}:取出传入的POJO的属性值。
Map:如果多个参数不是业务模型中的数据,没有对应的POJO,为了方便,我们也可以传入map。#{key}:取出map中对应的值。
<!-- public Employee getEmpByMap(Map<String, Object> map); --> <select id="getEmpByMap" resultType="com.atguigu.mybatis.bean.Employee"> select * from tb1 where id=#{id} and last_name=#{lastName} </select>
TO:如果多个参数不是业务模型中的数据,但是经常要使用,推荐编写一个TO(Transfer Object)数据传输对象。
Page{
int index;
int size;
}
参数值的获取
#{}:可以获取map中的值或者pojo对象属性的值;
${}:可以获取map中的值或者pojo对象属性的值;
select * from tbl_employee where id=${id} and last_name=#{lastName}
运行结果:Preparing: select * from tbl_employee where id=2 and last_name=?
区别:
- #{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
- ${}:取出的值直接拼装在sql语句中;会有安全问题。
- 大多情况下,我们去参数的值都应该去使用#{};在原生jdbc不支持占位符的地方我们就可以使用${}进行取值,比如分表、排序等。如:
① 按照年份分表拆分:select * from ${year}_salary where xxx;
,
② 排序:select * from tbl_employee order by ${f_name} ${order}
select返回
- 返回List
<!-- public List<Employee> getEmpsByLastNameLike(String lastName); --><!--如getEmpsByLastNameLike("%e%")--> <!--resultType:如果返回的是一个集合,要写集合中元素的类型 --> <select id="getEmpsByLastNameLike" resultType="com.atguigu.mybatis.bean.Employee"> select * from tbl_employee where last_name like #{lastName} </select>
- 返回一条记录的map,key就是列名,值就是对应的值
<!--public Map<String, Object> getEmpByIdReturnMap(Integer id); --> <select id="getEmpByIdReturnMap" resultType="map"><!--mybatis已经给map取了别名--> select * from tbl_employee where id=#{id} </select>
- 多条记录封装一个map:如
Map<Integer,Employee>
,其中键是这条记录的主键,值是记录封装后的javaBean
<!-- //告诉MyBatis封装这个map的时候使用哪个属性作为主键 @MapKey("id") public Map<Integer, Employee> getEmpByLastNameLikeReturnMap(String lastName); --> <select id="getEmpByLastNameLikeReturnMap" resultType="com.atguigu.mybatis.bean.Employee"> select * from tbl_employee where last_name like #{lastName} </select>
动态SQL
- if test 和where
<!-- 查询员工,要求,携带了哪个字段查询条件就带上这个字段的值 --> <!-- public List<Employee> getEmpsByConditionIf(Employee employee); --> <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee"> select * from tbl_employee <!-- where --> <where> <!-- test:判断表达式(OGNL) 使用if test从参数中取值进行判断,遇见特殊符号写转义字符: 如&&:&& "":"" --> <if test="id!=null"> id=#{id} </if> <if test="lastName!=null && lastName!="""> <!-注意and要放在前面,最后一句sql语句的拼装会出现问题---> and last_name like #{lastName} </if> <if test="email!=null and email.trim()!="""> and email=#{email} </if> <!-- ognl会进行字符串与数字的转换判断 "0"==0 --> <if test="gender==0 or gender==1"> and gender=#{gender} </if> </where> </select>
- choose
<!-- public List<Employee> getEmpsByConditionChoose(Employee employee); --> <select id="getEmpsByConditionChoose" resultType="com.atguigu.mybatis.bean.Employee"> select * from tbl_employee <where> <!-- 如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个 --> <choose> <when test="id!=null"> id=#{id} </when> <when test="lastName!=null"> last_name like #{lastName} </when> <when test="email!=null"> email = #{email} </when> <otherwise> gender = 0 </otherwise> </choose> </where> </select>
- update和set
<!--public void updateEmp(Employee employee); --> <update id="updateEmp"> <!-- Set标签的使用 --> update tbl_employee <set> <if test="lastName!=null"> last_name=#{lastName}, </if> <if test="email!=null"> email=#{email}, </if> <if test="gender!=null"> gender=#{gender} </if> </set> where id=#{id} </update>
- for each
取元素:
<!--public List<Employee> getEmpsByConditionForeach(@Param("ids")List<Integer> ids); --> <select id="getEmpsByConditionForeach" resultType="com.atguigu.mybatis.bean.Employee"> select * from tbl_employee where id in <!-- collection:指定要遍历的集合: list类型的参数会特殊处理封装在map中,map的key就叫list item:将当前遍历出的元素赋值给指定的变量 separator:每个元素之间的分隔符 open:遍历出所有结果拼接一个开始的字符 close:遍历出所有结果拼接一个结束的字符 index:索引。遍历list的时候是index就是索引,item就是当前值 遍历map的时候index表示的就是map的key,item就是map的值 #{变量名}就能取出变量的值也就是当前遍历出的元素 --> <foreach collection="ids" item="item_id" separator="," open="(" close=")"> #{item_id} </foreach> </select>
存元素:
<!-- 批量保存 --> <!--public void addEmps(@Param("emps")List<Employee> emps); --> <!--MySQL下批量保存:可以foreach遍历 mysql支持values(),(),()语法--> <insert id="addEmps"> insert into tbl_employee(last_name,email,gender,d_id) values <foreach collection="emps" item="emp" separator=","> (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id}) </foreach> </insert>
- 抽取可重用的sql片段
<!--1、sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用 2、include来引用已经抽取的sql:--> <sql id="insertColumn"> last_name,email,gender,d_id </sql> <insert id="addEmps"> insert into tbl_employee( <include refid="insertColumn"></include> ) values <foreach collection="emps" item="emp" separator=","> (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id}) </foreach> </insert>
MyBatis逆向工程
MyBatis Generator简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的根据表生成对应的映射文件,接口,以及bean类。支持基本的增删改查(targetRuntime=”MyBatis3Simple”),以及QBC((Query By Criteria,按标准查询)风格的条件查询(targetRuntime=”MyBatis3”)。但是表连接、存储过程等这些复杂的SQL定义需要我们手工编写。
mbg.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> <!--targetRuntime="MyBatis3"mbg会生成带动态sql的crud--> <context id="DB2Tables" targetRuntime="MyBatis3"> <commentGenerator> <property name="suppressAllComments" value="true" /> </commentGenerator> <!-- 配置数据库连接 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/ssm_crud" userId="root" password="123456"> </jdbcConnection> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- 指定javaBean生成的位置 --> <javaModelGenerator targetPackage="com.atguigu.crud.bean" targetProject=".\src\main\java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!--指定sql映射文件生成的位置 --> <sqlMapGenerator targetPackage="mapper" targetProject=".\src\main\resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- 指定dao接口生成的位置,mapper接口 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.atguigu.crud.dao" targetProject=".\src\main\java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!-- table指定每个表的生成策略,根据表创建相应的javaBean(名字用domainObjectName指定) --> <table tableName="tbl_emp" domainObjectName="Employee"></table> <table tableName="tbl_dept" domainObjectName="Department"></table> </context></generatorConfiguration>
分页查询
在mybatis-config.xml中添加:
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
批量查询
applicationContext.xml
<!--创建出SqlSessionFactory对象 --> <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- configLocation指定全局配置文件的位置 --> <property name="configLocation" value="classpath:mybatis-config.xml"></property> <!--mapperLocations: 指定mapper文件的位置--> <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"></property> </bean> <!--配置一个可以进行批量执行的sqlSession --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg> <constructor-arg name="executorType" value="BATCH"></constructor-arg> </bean>
然后在sercive中加入SqlSession的注解
package com.atguigu.mybatis.service;import java.util.List;import org.apache.ibatis.session.SqlSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.atguigu.mybatis.bean.Employee;import com.atguigu.mybatis.dao.EmployeeMapper;@Servicepublic class EmployeeService { @Autowired private EmployeeMapper employeeMapper; @Autowired private SqlSession sqlSession; public List<Employee> getEmps(){ EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class); for (int i = 0; i < 10000; i++) { mapper.addEmp(new Employee(UUID.randomUUID().toString().substring(0, 5), "b", "1")); } return employeeMapper.getEmps(); }}
- MyBatis
- MyBatis
- Mybatis
- myBatis
- mybatis
- MyBatis
- mybatis
- Mybatis
- MyBatis
- Mybatis
- mybatis
- MyBatis
- MyBatis
- mybatis
- MyBatis
- mybatis
- mybatis
- mybatis
- 有没有职业规划的30岁,可以差出多少万年薪?
- idea 下载、上传项目到github
- Python 学习笔记: A byte of python (一) 基础
- JAVA基础
- apply家族函数
- MyBatis
- Java反射
- 智力题
- ELK在大数据运维中的应用
- 传智播客-Java学习笔记day24
- HDU4549 M斐波那契数列【矩阵快速幂】
- 在SAP Cloud Platform中的Fiori app中如何获得登陆用户名?
- 【leetcode】two-sum
- PHPStorm POST表单传输失败