zoukankan      html  css  js  c++  java
  • MyBatis-全局配置文件

    MyBatis 的配置文件包含了影响 MyBatis 行为甚深的 设置(settings)和属性(properties)信息。文档的 顶层结构如下:

    configuration 配置
    properties 属性:可以加载properties配置文件的信息
    settings 设置:可以设置mybatis的全局属性
    typeAliases 类型命名
    typeHandlers 类型处理器
    objectFactory 对象工厂
    plugins 插件
    environments 环境
    environment 环境变量
    transactionManager 事务管理器
    dataSource 数据源
    databaseIdProvider 数据库厂商标识
    mappers 映射器

     1.为全局配置文件绑定dtd约束:

    1)联网会自动绑定
    2)没网的时候【/org/apache/ibatis/builder/xml/mybatis-3-config.dtd】:解压mybatis 的jar包然后在eclipse中绑定

     2. properties属性

    <configuration>
    		<!-- 
    			1.mybatis可以使用properties来引入外部properties配置文件的内容
    			  resource:引入类路径下的资源
    			  url:引入网络路径或者磁盘路径下的资源
    		 -->
    		   <properties resource="jdbc.properties"></properties>
    			<environments default="development">
    				<environment id="development">
    					<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.passowrd}"/>
    					</dataSource>
    				</environment>
    			</environments>
    			<!-- 将我们写好的sql映射文件一定要注册到全局配置文件中 -->
    			<mappers>
    				<mapper resource="EmployeeMapper.xml"/>
    			</mappers>
    		</configuration>
    

     3.settings包含很多重要的设置项

          setting:用来设置每一个设置
          name:设置项名
          value:设置项取值

       举例:驼峰式命名

     <settings>
    	<setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings> 

    1).mapUnderscoreToCamelCase:自动完成数据表标准列名和持久化类标准属性名之间的映射。
    例如:last_name和lastName

    4.typeAliases:【不建议大家使用别名】

    作用:A type alias is simply a shorter name for a Java type
    		
    		   <!-- typeAliases:别名处理器,可以为我们的java类型起别名,别名不区分大小写 -->
    		   <typeAliases>
    		   <!-- typeAlias:为某个java类型起别名
    				type:指定要起别名的类型全类名;默认别名就是类名小写;
    				alias:执行新的别名
    			-->
    				<typeAlias type="com.neuedu.mybatis.bean.Employee"/>
    				<!-- 
    					package:为某个包下的所有类批量起别名
    					   name:指定包名(为当前包以及下面所有的后代包的每一个类都起一个默认别名【类名小写】)
    				 -->
    				<package name="com.neuedu.mybatis.bean"/>
    				<!-- 批量起别名的情况下,使用@Alias注解为某个类型指定新的别名 -->
    		   </typeAliases>
    	 
    
    	   虽然有这么多的别名可以使用:但是建议大家还是使用全类名,看SQL语句是怎么被封装为JAVA 对象的时候简单!
    

     5.typeHandlers:类型处理器

    类型处理器:负责如何将数据库的类型和java对象类型之间转换的工具类

    6.environments【用于配置MyBatis的开发环境】

    <!--
         environments:环境们,mybatis可以配置多种环境,default指定使用某种环境。可以达到快速切换环境。
        environment:配置一个具体的环境信息;必须有两个标签;id代表当前环境的唯一标识
        transactionManager:事务管理器
       type:事务管理器的类型;type="[JDBC|MANAGED]"),这两个都是别名,在Configuration类中可以查看具体类!但是Spring对事务的控   制才是最终的管理方案!
       JDBC:这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务。
       MANAGED:这个配置几乎没做什么,它从来不提交和回滚一个连接。而是让容器来管理事务的整个生命周期。

      所以综上:这里如果要配置事务处理器,就配置为JDBC。表示使用本地的JDBC事务。

        当然也可以自定义事务管理器:只需要和人家一样实现TransactionFactory接口,type指定为全类名。
       dataSource:数据源
       type:type="[UNPOOLED|POOLED|JNDI]"
       unpooled:无数据库连接池
        pooled:有数据库连接池
      JNDI:
       自定义数据源:实现DataSourceFactory接口,type也是全类名

       但是我们也说了,无论是事务管理器的配置还是数据源的配置我们都会使
        用spring来做,这里只需要了解一下即可!
    -->

    	<environments default="development">
    		<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.passowrd}"/>
    			</dataSource>
    		</environment>
    		<environment id="development">
    			<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.passowrd}"/>
    			</dataSource>
    		</environment>
    	</environments>
    

      

    补充:这里可以了解一下如何配置第三方数据源:
    定制自己的第三方数据源,如下所示:
    要求:需要自定义一个类继承UnpooledDataSourceFactory类,然后在构造器中初始化该对应的dataSource属性,如下所示:

    自定义类为:
    			public class C3P0DataSource  extends UnpooledDataSourceFactory{
    				public C3P0DataSource() {
    					this.dataSource = new ComboPooledDataSource(); 
    				}
    			}
    			
    		MyBatis的全局配置文件为:
    						<environments default="development">
    						<environment id="development">
    							<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> -->
    							<!-- 配置使用第三方的数据源。属性需要配置为第三方数据源的属性 -->
    							<dataSource type="com.neuedu.mapper.C3P0DataSource">
    								<property name="driverClass" value="${jdbc.driver}"/>
    								<property name="jdbcUrl" value="${jdbc.url}"/>
    								<property name="user" value="${jdbc.username}"/>
    								<property name="password" value="${jdbc.password}"/>
    							</dataSource>
    						</environment>
    		测试类:
    			@Test
    			public void test02(){
    				//1.获取sqlSessionFactory对象
    				SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    				//2.利用sqlSessionFactory对象创建一个SqlSession对象
    				SqlSession session = sqlSessionFactory.openSession();
    				System.out.println(session.getConnection());
    				//提交事务
    				session.commit();
    			}
    	  当然这里需要加入c3p0的jar包;
    		c3p0-0.9.2.1.jar
    		mchange-commons-java-0.2.3.4.jar
    

      7.MyBatis的增删改查标签:

    <select></select>
    <insert></insert>
    <update></update>
    <delete></delete>
    例如:
    <insert id="saveEmployee">
    INSERT INTO tbl_employee(user_name,email,gender) VALUES(#{userName},#{email},#{gender})
    </insert>

    databaseIdProvider环境

    MyBatis is able to execute different statements depending on your database vendor. The
    ? MyBatis 可以根据不同的数据库厂商执行不同的语句

    <databaseIdProvider type="DB_VENDOR">
    <property name="SQL Server" value="sqlserver"/>
    <property name="DB2" value="db2"/>
    <property name="Oracle" value="" />
    <property name="MySQL" value="" />
    </databaseIdProvider>

    Type: DB_VENDOR
    –使用MyBatis提供的VendorDatabaseIdProvider解析数据库 厂商标识。也可以实现DatabaseIdProvider接口来自定义。
    Property-name:数据库厂商标识
    Property-value:为标识起一个别名,方便SQL语句使用

    这样在执行不同数据库的时候,就会执行不同数据库的语句了!当然如上所示:当有指定
    了databaseId属性的和没有指定databaseId属性的,都有的情况下那就按着有指定databaseId属性的sql语句执行!
    所以:databaseId属性:
    1).对于不同的数据库,做不同的SQL操作时,SQL语句会有不同。例如:
    MySQL和Oracle的分页[mysql分页为limit,而ORACLE分页我们使用rownumber]、插入主键的方式。
    MySQL:INSERT INTO tbl_employee(user_name,email,gender) VALUES(#{userName},#{email},#{gender})
    ORACLE:INSERT INTO employee(id,user_name,email) VALUES(test.seq.nextval,#{userName},#{email})
    所以要想使用ORACLE的自增序列还需要创建一个序列:
    如下所示:
    create sequence test_seq start with 1;

    这样做的好处:在service层只需要调用一个mybatis的方法,而不需要关注底层选择使用的数据库。
    employeeDao.insert(employee);

    那么:mybatis如何区分使用的是哪个数据库呢?使用databaseId属性

    ①.在mybatis-config.xml文件中进行配置
    		  		<databaseIdProvider type="DB_VENDOR">
    					<property name="ORACLE" value="oracle"/>
    					<property name="MySQL" value="mysql"/>
    				</databaseIdProvider>
    		    
    		  ②.在mybatis的映射文件中使用databaseId来区分使用的是哪一个数据库
    		  	  在mybatis的全局配置文件配置了这个之后,我们只需要在sql映射文件中通过在执行语句的标签上加一个属性databaseId即可!
    				<select id="getEmployeeById" resultType="emp">
    					select * from tbl_employee where id = #{id}
    				</select>
    				<select id="getEmployeeById" resultType="emp" databaseId="mysql">
    					select * from tbl_employee where id = #{id}
    				</select>
    				<select id="getEmployeeById" resultType="emp" databaseId="oracle">
    					select * from tbl_employee where id = #{id}
    				</select>
    
    		  
    		 
    	   
    			<environments default="dev_mysql">
    				<environment id="dev_oracle">
    					<transactionManager type="JDBC"/>
    					<dataSource type="POOLED">
    						<property name="driver" value="${jdbc.oracle.driver}"/>
    						<property name="url" value="${jdbc.oracle.url}"/>
    						<property name="username" value="${jdbc.oracle.user}"/>
    						<property name="password" value="${jdbc.oracle.passowrd}"/>
    					</dataSource>
    				</environment>
    				<environment id="dev_mysql">
    					<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.passowrd}"/>
    					</dataSource>
    				</environment>
    			</environments>
    

       8.mapper映射

      

    <!-- mappers:将sql映射注册到全局配置中 -->
    <mappers>
    <!-- mapper:注册一个sql映射
    注册配置文件:
    resource:引用类路径下的sql映射文件
    mybatis/mapper/EmployeeMapper.xml
    url:引用网络路径下或者磁盘路径下的sql映射文件
    url="file:///var/mappers/AuthorMapper.xml"

    注册接口
    class:引用(注册)接口
    1.有sql映射文件,映射文件名必须和接口同名,并且放在与接口同一个目录下;
    2.没有sql映射文件,所有的sql都是利用注解写在接口上;
    推荐:
    比较重要的,复杂的Dao接口我们来写sql映射文件
    不重要,见到的Dao接口为了开发快速可以使用注解


    -->
    <mapper resource="mybatis/mapper/EmployeeMapper.xml"/>
    <mapper class="com.neuedu.mybatis.mapper.EmployeeMapperAnnotation"/>
    <!-- 批量注册:
    1.注解版肯定是没问题的
    2.但是对于Mapper.xml映射文件和接口分开的,就需要保证在同一个包下了,否则找不到 -->
    <package name="com.neuedu.mybatis.mapper"/>
    </mappers>

    补充:MyBatis有基于XML文件的方式也有基于注解的方式,如下所示:
    1.使用基于注解的MyBatis映射
    1).新建一个XxxMapper接口。通常情况下,Mapper接口和Mapper.xml文件同名,且在同一个包下;
    MyBatis在加载Mapper接口的时候也会自动的加载Mapper.xml文件。

    2).在该接口中新建方法.
    若该方法上没有注解,则mybatis会去对应的Mapper.xml文件中查找和方法名匹配的id的节点进
    而执行该节点对应的SQL语句。
    3).在方法上使用MyBatis的注解

    如下所示:代码和配置如下所示:
    Mapper接口为:
    public interface EmployeeMapper {

    public Employee getEmployeeById(Integer id);
    //讲到此处了!此处以下没讲
    @Update("update tbl_employee set user_name = #{userName} where id = #{id}")
    public void updateEmployee(Employee employee);
    }
    MyBatis的sql映射文件可以没有,MyBatis的全局映射文件可以只用mapper标签加载Mapper接口

    <mappers>
    				<!-- resource="com/neuedu/mapper/EmployeeMapper.xml" -->
    				<mapper class="com.neuedu.mapper.EmployeeMapper"/>
    			</mappers>
    

      

    增删改操作需要提交事务:
    	  	@Test
    		public void test02(){
    			//1.获取sqlSessionFactory对象
    			SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    			//2.利用sqlSessionFactory对象创建一个SqlSession对象
    			SqlSession session = sqlSessionFactory.openSession();
    			EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
    			Employee employee = new Employee(1, 1,"张三丰","tangseng@163.com");
    			
    			mapper.updateEmployee(employee);
    			//提交事务
    			session.commit();
    		}
    

      2.获取自增主键值【当向数据库中插入一条数据的时候,默认是拿不到主键的值的, 需要设置如下两个属性才可以拿到主键值!】

      

    对于mysql:
    			<!--设置userGeneratedKeys属性值为true:使用自动增长的主键。使用keyProperty设置把主键值设置给哪一个属性-->
    			<insert id="addEmp" parameterType="com.neuedu.mybatis.bean.Employee" 
    			  useGeneratedKeys="true" keyProperty="id" databaseId="mysql">
    				insert into tbl_employee(last_name,email,gender) 
    				values(#{lastName},#{gender},#{email})
    			</insert>	
    			
    对于ORACLE:
    					<insert id="addEmp" databaseId="oracle">
    			     <!-- order="BEFORE" 设置selectKey中包含的语句先执行。且返回的类型为resultType指定的类型。
    			          再把该值付给keyProperty指定的列 -->
    						<selectKey keyProperty="" resultType="int" order="BEFORE"></selectKey>
    						insert into tbl_employee(id,last_name,email,gender) 
    						values(#{id},#{lastName},#{gender},#{email})
    					</insert>
    		
    

      3.SQL节点:

      

    1).可以用于存储被重用的SQL片段
    2).在sql映射文件中,具体使用方式如下:

    <insert id="addEmp">
    			insert into tbl_employee(id,
    			<include refid="employeeColumns"></include>) 
    			values(#{id},#{lastName},#{gender},#{email})
    		</insert>	
    	
    	  <sql id="employeeColumns">
    	  	last_name,email,gender
    	  </sql>  
    

      

    五:参数处理
    单个参数:mybatis不会做特殊处理
    #{参数名}: 取出参数值

    多个参数:mybatis会做特殊处理
    多个参数会被封装成一个map,
    key:param1...paramN,或者参数的索引也可以
    value:传入的参数值

    #{}就是从map中获取指定的key的值

    异常:
    org.apache.ibatis.binding.BingdingException:
    Parameter 'id' not found.
    Available parameters are [1,0,param1,param2]
    操作:
    方法:public Employee getEmployeeAndLastName(Integer id,String lastName);
    取值:#{id},#{lastName}

    命名参数:明确指定封装参数时map的key:@param("id")
    多个参数会被封装成一个map,
    key:使用@Param注解指定的值
    value:参数值
    #{指定的key}取出对应的参数值


    POJO:
    如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo;
    #{属性名}:取出传入的pojo的属性值

    Map:
    如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map
    #{key}:取出map中对应的值

    List、Set
    #这里面的值也会被封装到map集合中:
    key:collection
    值:对应的参数值

    #{collection[0]}或#{list[0]}

    #关于参数的问题:
    ①.使用#{}来传递参数
    ②.若目标方法的参数类型为对象类型,则调用其对应的getter方法,如getEmail()
    ③.若目标方法的参数类型为Map类型,则调用其get(key)
    ④.若参数是单个的,或者列表,需要使用@param注解来进行标记
    ⑤.注意:若只有一个参数,则可以省略@param注解


    六、参数值的获取
    #{}:可以获取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} :排序是不支持预编译的!

    MyBatis-映射文件select元素

    Select元素来定义查询操作。
    Id:唯一标识符。
    – 用来引用这条语句,需要和接口的方法名一致
    parameterType:参数类型。
    –可以不传,MyBatis会根据TypeHandler自动推断
    resultType:返回值类型。
    – 别名或者全类名,如果返回的是集合,定义集合中元素的类型。不能和resultMap同时使用

    1.返回类型为一个List
    eg:public List<Employee> getEmpsByLastNameLike(String lastName);
    <!-- resultType:如果返回的是一个集合,要写集合中元素的类型 -->
    <selecct id="getEmpsByLastNameLike" resultType="com.neuedu.mybatis.bean.Employee">
    select * from tbl_employee where lastName like #{lastName}
    </select>

    2.返回单条记录为一个Map
    <!-- 返回一条记录的map:key就是列名,值就是对应的值 -->
    public Map<String,Object> getEmpByIdReturnMap(Integer id);

    <select id="getEmpByIdReturnMap" resultType="map">
    select * from tbl_employee where id = #{id}
    </select>


    3.返回为一个ResultMap:自定义结果集映射规则
    尤其是当数据表的列名和类的属性名不对应的时候:
    1.起别名
    2.符合下划线转驼峰式命名规范
    3.用这里的resultMap

    <!-- resultMap:自定义结果集映射规则 -->
    public Employee getEmployeById(Integer id);

    <!-- 自定义某个javaBean的封装规则
    type:自定义规则的javabean类型
    id:唯一id方便引用
    -->
    <resultMap type="com.neuedu.mybatis.bean.Employee" id = "myEmp">
    <!--
    指定主键列的封装规则
    id定义主键列会有底层优化
    column:指定是哪一列
    property:指定对应的javaBean属性
    -->
    <id column="id" property = "id">
    <!-- 定义普通列封装规则 -->
    <result column="last_name" property="lastName"/>
    <!--其它不指定的列只要属性名和列名会自动封装,我们只要写resultMap就把全部的映射规则
    都写上,不写是因为列名和属性名是对应的 -->

    </resultMap>

    <!--只需要在映射的地方映射一下就可以了 --》

    <select id="getEmployeById" resultMap="myEmp">
    select * from tbl_employee where id = #{}
    </select>

  • 相关阅读:
    mysql数据库常用指令
    解决windows的mysql无法启动 服务没有报告任何错误的经验。
    “Can't open file for writing”或“operation not permitted”的解决办法
    启动Apache出现错误Port 80 in use by "Unable to open process" with PID 4!
    如何打开windows的服务services.msc
    常见的HTTP状态码 404 500 301 200
    linux系统常用的重启、关机指令
    (wifi)wifi移植之命令行调试driver和supplicant
    linux(debian)安装USB无线网卡(tp-link TL-WN725N rtl8188eu )
    alloc_chrdev_region申请一个动态主设备号,并申请一系列次设备号
  • 原文地址:https://www.cnblogs.com/lc-java/p/7488069.html
Copyright © 2011-2022 走看看