MyBatis_day1

一.MyBatis框架初使用

  1. 使用底层的selectOne()方法
    • 导入Mybatis的jar包
    • 创建一个全局配置文件 mybatis-config.xml ,根据全局配置文件,创建了一个
      SqlSessionFactory对象.
    • 创建一个sql映射文件, EmployeeMapper.xml,该配置文件中配置了sql语句.
    • 将sql映射文件注册到全局配置文件中
    • 从SqlSessionFactory中获取SqlSession对象. sqlSession代表和数据库的一次会话.
    • 然后调用selectOne(“sql语句的唯一标识”,执行sql的参数)完成查询操作.
    • 最后将SqlSession对象关闭.释放资源.
将sql映射文件注册到全局配置文件中:
       <mappers>
            <!--<mapper resource="EmployeeMapper.xml"/>-->引入一个sql映射配置文件
            <!--批量引入-->
            <package name="com.atguigu.mybatis.dao"/>该包下方的配置文件全部引入
        </mappers>

2.目录结构
在这里插入图片描述

二.Mapper接口开发

Mapper接口的好处:
1.接口中定义的方法明确的类型约束(方法参数的类型 方法返回值的类型)
2.接口本身:
接口本身就是抽象.抽出了规范.不强制要求如何做具体的实现.可以使用jdbc,hibernate,Mybatis.
接口将规范与具体的实现分离.
Mapper接口开发, MyBatis会为接口生成代理实现类。代理对象完成具体的增删改查操作.
最底层还是使用selectOne,update等方法来完成的.
Mapper接口开发需要注意:
1.Mapper接口要与sql映射文件动态绑定. sql映射文件的namespace指定成接口的全类名.

 <mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper"></mapper>

2.Mapper接口方法与sql映射文件的sql语句绑定。 sql语句的id值指定成接口中的方法名.

 <!--
select: 配置查询的sql语句
	 id:sql语句的唯一标识,不能重复,当添加上databaseId="XXX"时,即使用不同的数据库,此时id允许重复
	 resultType:当前sql查询到的数据想让MyBatis封装的javaBean对象的类型.
     #{id}: 从传递过来的参数中取出id值.
 -->
<!--	public Employee getEmpById(Integer id );-->
    <!--sql语句的id值指定成方法名,目的是将sql语句与方法绑定-->
    <select id="getEmpById" resultType="com.atguigu.mybatis.beans.Employee">
        select id,last_name,gender,email from tb1_employee where id = #{id}
    </select>

三.全局配置文件

1.properties
  
    <!-- 
    	properties: Mybatis可以是用properties来引入外部properties类型的文件.
    		resource: 引入类路径下的资源
    		url: 引入网络路径或者是磁盘路径下的资源
     -->
     <properties resource="db.properties" ></properties>在db.properties中配置数据库的驱动,用户名等
     
2.settings
     <!-- 
		settings: 包含了很多重要的设置项
			setting: 用来设置每一个设置项
				name:设置项的名称
				value:设置项的值
	 -->
	 <settings>
	 	<!-- 自动映射下划线到驼峰命名    (数据库中常用下划线命名,JavaBean类中用大写命名)
	 	 DB: last_name  autoMapping:lastName -->
	 	<setting name="mapUnderscoreToCamelCase" value="true"/>
	 </settings>
	 
3.typeAliases
     	 <!-- 
	 	typeAliases:别名处理,为java 类型注册别名
	 		typeAlias: 为某个java类指定别名
	 			type: 指定java的类型(包名+ 类名
	 			alias: 指定具体的别名。 如果alias不显示的指定,则默认的别名是类名的首字母小
                       写. 
	 				   别名不区分大小写。
	 		package: 批量取别名.
	 			 name:指定包名。   为该包下的所的类取默认的别名。
	 			 批量取别名可能会出现别名冲突的情况. 例如指定的包下与子包下相同的类.
	 			 可以使用@Alias("别名")在类上标注具体的别名.
	  -->
	  <typeAliases>	
	  	<package name="com.atguigu.mybatis.beans"/>
	  	<!-- <typeAlias type="com.atguigu.mybatis.beans.Employee" alias="emp" /> -->
	  </typeAliases>
	  
 4.environments
       <!--
		environments: 环境们。  使用default来指定具体使用的环境.
			 environment:配置具体的环境.
			 	id: 当前环境的标识
			 	transactionManager:事务管理器
			 		type: 配置具体的事务管理器的类型
			 			JDBC: JdbcTransactionFactory
			 			MANAGED:ManagedTransactionFactory			
			 	最终: 事务管理要交给Spring. 使用Spring的声明式事务.		 	
			 	dataSource:数据源
			 		type: 执行数据源的类型.
			 			UNPOOLED:不使用连接池 UnpooledDataSourceFactory
			 			POOLED:使用连接池  PooledDataSourceFactory
			 			JNDI:从web服务器中获取数据源.  JndiDataSourceFactory			 
			 	最终: 数据源交给Spring管理
	  -->
	<environments default="mysql">此处default配置那个id标识,使用的就是哪一个数据库
		<environment id="mysql">
			<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>
		 <!--使用oracle数据库-->
        <environment id="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
     <!-- 
		databaseIdProvider:
			Mybatis用来支持多数据库厂商。Mybatis可以根据不同的数据库执行不同的sql语句
			DB_VENDOR: VendorDatabaseIdProvider 作用就是得到数据库厂商的标识名.
					   Connection.getMetaData().getDataBaseProductName();	
			常见的数据库厂商的标识名:
				MySQL:  MySQL
				Oracle: Oracle
				SQL Server:  SQL Server		
	 --> 
	 <databaseIdProvider type="DB_VENDOR">
	 	<!-- 为数据库厂商的标识名起别名 -->
	 	<property name="MySQL" value="mysql"/>
	 	<property name="Oracle" value="oracle"/>
	 	<property name="SQL Server" value="sqlserver"/>
	 </databaseIdProvider>
      
6.mappers
      <!-- 
		mappers: 引入sql映射文件
			mapper: 引入单个的sql映射文件
				resource: 引入类路径下的sql映射文件
				url:引入网络路径或者是磁盘路径下的sql映射文件.
		    package: 批量引入sql映射文件
		    		 要求: 
		    		   1.sql映射文件的名字与 Mapper接口的名字一致.
		    		   2.Sql映射文件与Mapper接口必须在同一目录下.
		    	name:指定包名	    		 
 	 -->
 	<mappers>
    <!--<mapper resource="EmployeeMapper.xml"/>-->
    <!--批量引入-->
    <package name="com.atguigu.mybatis.dao"/>
</mappers>


sql映射文件

1.增删改查

 <insert id=""  parameterType="" databaseId="" >
 <update>
 <delete>
 <select id="" parameterType="" resultType=""  databaseId="">
 如果想要获取到增删改对数据的影响条数,可以直接在接口的方法中声明返回值类型即可.

2.主键自增以及主键值的返回

  • a.对于支持自增主键的数据库(Mysql),可以使用useGeneratedKeys=“true”
    keyProperty=“javaBean类的某个属性”

  • b.对于不支持自增主键的数据库(oracle),使用selectKey的子标签完成主键值得返回.
    selectKey的用法:
    BEFORE: selectKey在插入语句之前执行
    AFTER: selectKey在插入语句之后执行

  • c.Oracle数据库的自增策略:
    使用序列模拟自增. 可以从序列中查询 nextval currval.
    在这里插入图片描述

3.参数传递:

单个参数(普通类型(基本类型/包装类型+String)):  Mybatis不会做特殊的处理 
       取值: #{参数名(随便写)} 取出参数值
       
多个参数:MyBatis会做特殊处理. 多个参数会被封装成一个Map。
	      封装map的规则:
			 key: param1 ,param2 , param3 ..... paramN / 0 1 2 ....N-1
          value:具体传入的参数值
          
<!--测试传递多个参数的编写方式:public Employee getEmpByIdAndLastName(Integer id,String lastName);
   select * from tb1_employee where id=#{param1} and last_name=#{param2}
   
   当接口处明确标出Param时,这里可以使用对应的值来进行传参
      public Employee getEmpByIdAndLastName(@Param("id")Integer id , @Param("lastName")String lastName);
-->
<select id="getEmpByIdAndLastName" resultType="com.atguigu.mybatis.beans.Employee">
    select * from tb1_employee where id=#{id} and last_name=#{lastName}标明时可以使用对应值
</select>

异常: ### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found.
         Available  parameters are [1, 0, param1, param2]
	  解决: 取值使用#{param1/ 0}  #{param2 / 1 }

1.命名参数**: 明确的指定多个参数封装map的时候所使用的key。 @Param(“key”)
取值: #{@Param指定的key/paramN}

2.POJO: 如果参数很多,正好又是业务逻辑的数据模型中的属性,直接传入POJO
取值: #{POJO的属性名}

3.Map: 如果参数很多,不是业务逻辑的数据模型中的属性,可以封装成map传入.
取值: #{map中的key}
map.put(“aa”,1001);
map.put(“bb”,“Tom”);
映射配置中:
select * from tb1_employee where id=#{aa} and last_name=#{bb}取key值

参数处理的源码分析

 names={0=id,1=lastName}
 args=[1001,Tom]
	public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();
    if (args == null || paramCount == 0) {
      return null;
    } else if (!hasParamAnnotation && paramCount == 1) {
      return args[names.firstKey()];
    } else {
      final Map<String, Object> param = new ParamMap<Object>();
      int i = 0;
      for (Map.Entry<Integer, String> entry : names.entrySet()) {
        param.put(entry.getValue(), args[entry.getKey()]);
        // add generic param names (param1, param2, ...)
        final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
        // ensure not to overwrite parameter named with @Param
        if (!names.containsValue(genericParamName)) {
          param.put(genericParamName, args[entry.getKey()]);
        }
        i++;
      }
      return param;
    }

参数值的获取方式

1.#{}: 可以获取map中的值 或者是POJO对象属性的值。 还可以直接获取普通类型的参数.

2.${}: 可以获取map中的值 或者是POJO对象属性的值

区别:
#{}:是以预编译的形式将参数设置到sql语句中. PreparedStatement 防止sql注入.
${}:取出的值直接拼装到sql语句中.会有安全问题.

使用场景:
   大部分情况下推荐使用#{},原生的jdbc不支持占位符的地方可以使用 ${}来进行动态的赋值.
   例如在表名的位置可以使用${}来获取值

   eg: select  xxxxx    from    where  条件  order by 排序字段  排序方式  limit ?,?;
   分表:
		  select * from 2016_salary ;
		  select * from 2017_salary ; 
		  select * from ${year}_salary ;
       用户选择2016年,则从2016_salary表查.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值