Mybatis_学习笔记

Mybatis框架

  • 1.Mybatis作用:
  • 2.构建Spring+Mybatis
    • 1.先用maven构建一个web项目
    • 2.导入mybatis的相关依赖
    • 3.配置数据库连接
    • 4.编写方法
    • 5.编写xml映射
    • 6.完成MyBatis的配置
    • 7.执行单元测试**
  • 3.小结
  • 4.执行插入数据时获取自增长id
  • 5使用多个参数
  • 6.resultMap
    • 1.resultMap可以解决名称不匹配的问题
    • 2.resultMap主要用于解决多表数据关联查询的问题
  • 7.Mybatis中的占位符
  • 8.动态SQL

1.Mybatis作用:

解决持久层数据处理的问题
传统的jdbc:

//1.声明
String sql = "";
Connection conn = null;
PreparedStatement pstmt = null;
ResultResult rs = null;
//2.获取连接
try{
	conn = dataSource.getConnection();
//3.预编译
	pstmt = conn.xxx(sql);
	pstmt.set???(1,xx);
//4.执行
	pstmt.execute???();
//5.处理结果
	...
}catch (SqlException e){
	...
}finally{
//6.释放资源
	rs.close();
	pstmt.close();
	conn.close();
}

主要是基于JDBC技术的原生代码比较繁琐,没有经过任何优化,开发甚至执行效率低下!
使用MyBatis框架时,不必关心JDBC技术如何实现,只需要编写需要执行的操作的抽象方法,例如User findById(Integer id),然后,为这个方法映射所需执行的SQL语句即可。

2.构建Spring+Mybatis

1.先用maven构建一个web项目

添加依赖:

 <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webmvcartifactId>
      <version>4.3.9.RELEASEversion>
 dependency>

在resources根目录下添加spring-mvc.xml配置文件,同时添加相关的通用配置


	<context:component-scan 
		base-package="cn.tedu.spring" />
		
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/" />
		<property name="suffix" value=".jsp" />
	bean>
	
	
	<mvc:annotation-driven />

在web.xml中添加相关配置:

<servlet>
    <servlet-name>SpringMVCservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:spring-mvc.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>

  <servlet-mapping>
    <servlet-name>SpringMVCservlet-name>
    <url-pattern>*.dourl-pattern>
  servlet-mapping>

  <filter>
    <filter-name>CharacterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    <init-param>
      <param-name>encodingparam-name>
      <param-value>utf-8param-value>
    init-param>
  filter>

  <filter-mapping>
    <filter-name>CharacterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>

此时一个spring的web项目建好了

2.导入mybatis的相关依赖

在pom.xml中添加mybatis相关依赖


<dependency>
	<groupId>org.mybatisgroupId>
	<artifactId>mybatisartifactId>
	<version>3.4.6version>
dependency>


<dependency>
	<groupId>org.mybatisgroupId>
	<artifactId>mybatis-springartifactId>
	<version>1.3.2version>
dependency>


<dependency>
	<groupId>org.springframeworkgroupId>
	<artifactId>spring-jdbcartifactId>
	<version>4.3.9.RELEASEversion>
dependency>


<dependency>
	<groupId>mysqlgroupId>
	<artifactId>mysql-connector-javaartifactId>
	<version>8.0.13version>
dependency>


<dependency>
	<groupId>commons-dbcpgroupId>
	<artifactId>commons-dbcpartifactId>
	<version>1.4version>
dependency>


<dependency>
	<groupId>junitgroupId>
	<artifactId>junitartifactId>
	<version>4.9version>
dependency>

3.配置数据库连接

# data-source
url=jdbc:mysql://localhost:3306/tedu_ums?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
driver=com.mysql.cj.jdbc.Driver
username=root
password=root
initialSize=2
maxActive=10

在resources根目录下添加spring-dao.xml配置文件,同时添加相关的通用配置


	<util:properties id="dbConfig"
		location="classpath:db.properties" />
	
	
	<bean id="dataSource" 
		class="org.apache.commons.dbcp.BasicDataSource">
		
		<property name="driverClassName"
			value="#{dbConfig.driver}" />
		<property name="url"
			value="#{dbConfig.url}" />
		<property name="username"
			value="#{dbConfig.username}" />
		<property name="password"
			value="#{dbConfig.password}" />
		<property name="initialSize"
			value="#{dbConfig.initialSize}" />
		<property name="maxActive"
			value="#{dbConfig.maxActive}" />
	bean>

测试:

  @Test
    public void t1() throws SQLException {
       AbstractApplicationContext ac = new ClassPathXmlApplicationContext("spring-dao.xml");
       DataSource dataSource = ac.getBean("dataSource", DataSource.class);
       System.out.println(dataSource.getConnection());
       ac.close();
   }

4.编写方法

使用MyBatis时,无需自行编写JDBC相关代码,只需要创建Java接口文件,并将需要执行的数据操作的抽象方法添加在接口中即可!

通常,建议按照“增 > 查 > 删 > 改”的顺序开发相关功能。

目标:向数据表中插入新的用户数据。

则创建cn.tedu.mybatis.mapper.UserMapper接口,然后,添加“插入新的用户数据”的抽象方法:

Integer insert(User user);

使用MyBatis时,执行的增、删、改操作均返回Integer,表示受影响的行数。

5.编写xml映射

使用MyBatis时,还需要与接口的抽象方法对应的SQL语句,该SQL语句是在XML文件中配置的!(UserMapper.xml)
注:通常,接口文件的数量与XML映射文件的数量是相同的,是一一对应的!
映射的XML文件应该存放到src\main\resources下,但是,项目中可能存在多个映射文件,为了便于管理,会在resources下创建mappers文件夹,然后把映射的XML文件放在这个文件夹中。

然后,配置该XML映射文件:




	
	
	
	
	
	
		INSERT INTO t_user (
			username, password,
			age, phone, email
		) VALUES (
			#{username}, #{password}, 
			#{age}, #{phone}, #{email}
		)
	


6.完成MyBatis的配置



	
	




	
	
	
	

7.执行单元测试**

public class UserMapperTestCase {

	@Test
	public void insert() {
		AbstractApplicationContext ac
			= new ClassPathXmlApplicationContext(
					"spring-dao.xml");
		
		UserMapper userMapper
			= ac.getBean("userMapper", UserMapper.class);
		
		User user = new User();
		user.setUsername("mapper");
		user.setPassword("1234");
		user.setAge(31);
		user.setPhone("13900139001");
		user.setEmail("[email protected]");
		
		Integer rows = userMapper.insert(user);
		System.out.println("rows=" + rows);
		
		ac.close();
	}
	
}

3.小结

  1. MyBatis使用简单,可以简化开发,开发者不必关注数据库编程的细节;

  2. 使用MyBatis编程主要做好:(1)设计SQL语句; (2)设计抽象方法; (3)配置映射;

  3. 所有的xx.propertiesspring-dao.xml中的配置,需要理解,需要掌握修改配置值,不需要记住;

  4. 关于抽象方法:如果是增删改操作,返回值固定设计为Integer,如果是查询操作,根据查询结果来决定,例如可能是ListUserInteger……;方法的名称应该尽量对应所执行的数据操作,而不应该是某个业务,例如插入数据的方法名可以是insert,或者addnew,但是不应该使用reg;目前,只允许使用最多1个参数,如果一定要使用多个,请封装为1个参数;

  5. 关于映射配置:根据所执行的操作选择 SELECT t_department.id AS dep_id, name, t_user.id, username, password, age, phone, email, is_delete FROM t_user INNER JOIN t_department ON t_user.department=t_department.id WHERE t_department.id=#{id}

    最终,执行查询获取的结果例如:

    DepartmentVO [
    	depId=2, 
    	depName=RD, 
    	users=[
    		User [id=13, username=spring, password=1234, age=23, phone=13800138003, [email protected], isDelete=1, department=null], 
    		User [id=14, username=mybatis, password=12cxv34, age=24, phone=13800138004, [email protected], isDelete=0, department=null], 
    		User [id=17, username=jdbc, password=88888888, age=27, phone=13800138007, [email protected], isDelete=1, department=null], 
    		User [id=21, username=mapper, password=88888888, age=31, phone=13900139001, [email protected], isDelete=1, department=null], 
    		User [id=23, username=namespace, password=88888888, age=31, phone=13900139002, [email protected], isDelete=1, department=null]
    	]
    ]
    

    如果提示错误TooManyResultsException,则错误多半在于查询结果的列名与中普通的节点的column的配置有误!也有可能存在例如2列的名称都是id,却有多条数据的id值不同的问题!

    7.Mybatis中的占位符

    Mybatis中,常见的占位符格式: #{参数},其中,也可能是参数对象中的属性,如果参数是Map类型,还可以是Map中的key。

    使用#{}的占位符可用于替换,例如:

    select * from t_user where username=?
    

    即可替换以上语句中的问号(?),在实际运行时,MyBatis会将以上SQL语句进行预编译,并后续使用#{}替换问号(?)。
    假设获取用户列表时,排序规则不确定,可能使用的抽象方法是:

    List findAllOrderedList(String orderBy);
    

    配置的映射可能是:

    
    

    调用时:

    mapper.findAllOrderedList("id asc");
    mapper.findAllOrderedList("id desc");
    

    以上代码的执行效果是失败的!需要将#{}修改为${},且在抽象方法中,这样的参数必须添加@Param注解,即:

    List findAllOrderedList(
    	@Param("orderBy") String orderBy);
    
    
    

    然后,在调用时,就可以根据参数的不同,实现不同的排序效果!

    使用${}格式的占位符并不具备预编译的效果!它是直接拼接形成的SQL语句,例如:"select * from t_user order by" + orderBy,如果一定使用${}格式的占位符来表示某个值,还需要考虑单引号类似的问题,例如:select * from t_user where username='${username}',由于只是拼接,所以,还存在SQL注入风险!
    小结

    使用#{}是预编译的(没有SQL注入风险,无需关注数据类型),使用${}不是预编译的;

    使用#{}只能替换某个值,使用${}可以替换SQL语句中的任何部分;

    关于SQL注入,不需要太过于紧张,预编译可以从根源上杜绝,或者,在执行SQL指令之前,判断参数中是否包含单引号也可以杜绝!

    通过使用${},可以使得SQL更加灵活,更加通用!但是,却不推荐太过于通用的SQL!因为,即使查询条件可以自由更改,但是,不同的查询条件对应不同的需求,所需的字段列表很有可能是不一样的,查询时,获取不必要的字段,就会造成不必要的资源浪费,例如,显示列表时,可能需要用户名、密码、年龄、手机、邮箱,但是,登录的查询就只需要用户名、密码即可,年龄、手机、邮箱这几项数据在登录时是不需要的,如果也查询出来,就是浪费资源!如果变量太多,又会导致不可控因素太多,容易出错!

    8.动态SQL

    在MyBatis的映射文件中,配置SQL语句时,可以添加例如此类的标签,实现SQL语句的动态变化,即:参数不同,最终执行的SQL语句可能是不同的!

    在使用动态SQL时,最常用的就是这两种,是用于判断的,例如:

    select 
    	* 
    from 
    	t_user
    	
    
    where 
    	${where}
    
    	
    
    order by 
    	${orderBy}
    
    

    关于,主要用于循环处理SQL语句中的某个部分,例如:批量删除某些数据!它的SQL语句可能是:

    delete from t_user where id in (?,?,?)
    

    其中,in关键字右侧的括号中的内容是不确定的,应该是由用户操作时决定的!则需要动态的生成这个部分!

    针对这个问题,设计的抽象方法可能是:

    Integer deleteByIds(Integer[] ids);
    

    配置的映射为:

    
    	delete from 
    		t_user
    	where
    		id in (
    		
    			#{id}
    		
    		)
    
    

    以上配置的中,collection表示被遍历的集合对象,当抽象方法只有1个参数时,取值为listarray,取决于集合对象的数据类型,当抽象方法 有多个参数时,使用@Param注解中的名称,item表示遍历过程中的变量名,separator表示分隔符。

    以上配置还可以调整为:

    id in
    
    	#{id}
    
    

    即:open表示由处理的SQL语句的起始部分的字符串,而close表示结束部分的字符串。

你可能感兴趣的:(Mybatis_学习笔记)