MyBatis_基本知识

1.MyBatis概念

        一个封装了数据库JDBC操作的ORM框架. Apache(ibatis)–> Google(MyBatis)

ORM:   

    对象关系映射  将数据库转换为对象来进行处理 

    数据表就是一个类,表的一行就是一个对象,一行的每个字段就是属性

缺点:  会牺牲程序的执行效率

优点:解决重复去读数据库获取内容的操作

2.MyBatis框架的优缺点

优点:

       1.基于sql语句的框架,可以实现对sql的调优
  2.将sql语句单独编写在xml配置文件中,方便统一管理和维护,降低程序之间的耦合度
  3.提供xml标签,支持动态sql语句编写
  4.提供xml映射标签,支持表和表之间的关联映射

缺点:

       1.需要自己去编写sql语句,对开发人员sql能力要求高
  2.数据库移植性差
  3.不支持表和表之间级联关系增删改操作.

3.在终端建库建表

<!--建库-->
create database if not exists has character set utf8 collate utf8_general_ci;
       character set utf8: 字符集
       collate utf8_general_ci:校队集
<!--建表-->
create table if not exists student 
   (sid Integer primary key auto_increment, 
    name varchar(20),
    age Integer)charset=utf8;

4.pom.xml

<!-- 统一版本管理 -->
<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.junit>4.12</project.junit>
	<project.mybatis>3.4.6</project.mybatis>
	<project.jdbc.connector>8.0.11</project.jdbc.connector>
</properties>

<dependencies>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.12</version>
		<scope>${project.junit}</scope>
	</dependency>
	<dependency>
		<groupId>org.mybatis</groupId>
		<artifactId>mybatis</artifactId>
		<version>${project.mybatis}</version>
	</dependency>
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>${project.jdbc.connector}</version>
	</dependency>
</dependencies>

5.mybatis_config.xml

<!--为java类型起别名,在配置文件中就可以使用别名 目的: 书写简单方便-->
<typeAliases>
	<typeAlias type="com.xalo.model.Student" alias="Student"/>
</typeAliases>

<!--数据库环境配置,一个环境对应一个数据库,和spring整合之后,就不在配置-->
<environments default="development">
  	<environment id="development">
  	<!-- 事物类型配置	  JDBC:使用JDBC的事物管理 -->
  	<transactionManager type="JDBC"></transactionManager>
  		<!-- 数据源的配置 POOLED:使用mybatis默认的数据源-->
  	<dataSource type="POOLED">
  	  <property name="driver" value="com.mysql.cj.jdbc.Driver"/>  <!-- useSSL=false: 是否使用加密 -->
  		<property name="url" value="jdbc:mysql://localhost:3306/has?useUnicode=true&amp;characterEncoding=UTF8&amp;useSSL=false"/>
  		<property name="username" value="root"/>
  		<property name="password" value="12345678"/>
  	</dataSource>
  </environment>
</environments>

<!--映射文件导入-->
<!--当满足下面条件时,可以写成
    1.接口和映射文件在同一包下
    2.接口名和映射文件名一致-->
 <mappers>
      <package name="com/xalo/dao"/> 
 </mappers>  
 <!--当不满足以上两个条件时,映射文件的如下导入-->
<mappers>
  	<mapper resource="com/xalo/dao/studentDao.xml"/>
</mappers>

6.建包: com.xalo.model

mapper:   mapper中写的都是sql语句,将sql语句和代码解

       namespace:  需要写成接口的完整类名(包名.接口名) 

                           不同mapper中的sql语句的隔离

增删改常见属性:

         id:   该条sql语句的唯一标识符, sql语句的id必须是对应的方法名

parameterType:  传入该sql语句的参数的类型,必须和方法的参数类型保持一致

flushCache: 任何时候只要语句被调用,都会导致本地缓存和二级缓存被清空,

                          默认为true(对应插入,更新和删除语句)

timeout:     这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数.

                      默认为unset(依赖驱动)

resultType:  必须和方法的返回值保持一致  

                   所有更新操作(增删改)操作,不用指定返回值类型,默认返回受影响的行数.

      #{ }:       数值绑定

${ } 和#{ }的区别

 #:将传入的数据当成一个字符串,会对自动传入的数据加一个双引号
 $:将传入的数据直接显示生成在sql中
 #:方式能够很大程度的防止sql注入
 $:方式无法防止sql注入
 MyBatis排序时使用order by动态参数时,用$而不是# 

resultMap: 解决表中的字段名和实体的属性名不一致的问题 

                     常用与多表查询以及查询时使用别名的情况

            result标签:普通键设置

            id属性:    实体的唯一标识符

           column属性:表中的字段配置

           property属性:实体类的属性名

  mybatis 在3.4.4之后不能直接使用 #{index} 

  替换为 #{argindex}  index指的是参数的位置,从0开始

  如果有多个参数就不需要指定 parameterType

所有的更新操作(增删改)操作,不用指定返回值类型, 默认返回受影响的行数

<update id="updateNameById">
     update student set name=#{arg0} where id = #{arg1};
</update>

                         

 //com.xalo.model
//(1) Student.java
 public class Student{
     private String name;
     private Integer age;
     //提供构造方法(无参,有参)
     //提供setter getter方法
     //提供toString()方法
   }
   
//com.xalo.dao
//(2)StudentDao
public interface StudentDao {
    //添加学生
   public void addStudent(Student student);  
   
   //查询所有的学生
   public List<Student> queryAllStudent();
   //根据id查询学生
   public Student queryStudentById(Integer id);	
   //查询姓名
   public List<Student> queryAllStudentName();
   //查询多条记录中的某几个字段
   public List<Map<String, Object>> queryMulField2();
   //不使用resultMap时,查询多条记录中的某几个字段
   public List<Map<String, Object>> queryMulField();
	
	//根据id修改姓名,方法的返回值代表修改的总数
	public Integer updateNameById(String name,Integer id);
    
    //根据id删除学生,方法的返回值代表删除的总数
    public Integer deleteStudentById(Integer id);

   }
//(3)studentDao.xml
/*mybatis面向接口的编程:
 *  可以把该配置文件看作是接口的实现类,最终会根据该配置文件生成对应接口的实习类
 * 1.namespace: 需要写成接口的完整类名(包名.接口名)
 * 2.sql语句的id必须是对应的方法名
 * 3.parameterType:必须和方法的参数的类型保持一致
 * 4.resultType: 必须和方法的返回值保持一致
 * 5.所有的更新操作(增删改)操作,不用指定返回值类型(resultType),默认返回受影响的行数
 * 6.mybatis在3.4.4之后不能直接使用#{index},替换为 #{argindex} index:参数的位置,从0开始.
 * 7.mapper中书写的是sql语句,将sql语句和代码解耦
 */
<?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.xalo.dao.inter.StudentDao">

   <insert id="addStudent" parameterType="Student">
       insert into student (name,age) values(#{name},#{age});
   </insert>
   
   <select id="queryAllStudent" resultType="Student">
       select * from student;
   </select>
   <select id="queryStudentById" parameterType="Integer" resultType="Student">
      select * from student where id = #{id};
   </select>
   <select id="queryAllStudentName" resultType="java.lang.String">
         select name from student;
   </select>
   
  (1)当实体类跟表中属性名不一致
       用resultMap标签中做实体类中属性和表中字段名之间的映射
       id: 当前resultMap映射结果   type: 表中每一行记录封装成什么类型对象
       property: 实体类中属性名   column: 表中字段名称
      
    // 查询表中的某几个字段的值 
	 <resultMap type="java.util.Map" id="stuMap">
	      <result column="name" property="name"/>
	      <result column="age"  property="age"/>
	 </resultMap>  	  
	// 查询结果为多条记录的某几个字段 
	     <select id="queryMulField2" resultMap="stuMap">
	         select id,age from student;
	     </select>
	     
	(2)当实体类跟表中属性名一致  
	// 不使用resultMap时, 查询表中某几个字段的值 
      <select id="queryMulField" resultType="java.util.Map">
           select id,age from student;
      </select>
      
  <update id="updateNameById">
         update student set name=#{arg0} where id = #{arg1};
  </update>

 <delete id="deleteStudentById" parameterType="Integer" flushCache="true" statementType="PREPARED" timeout="20">
           delete from student where id = #{id};
 </delete>
</mapper>

//com.xalo.test
//(3) DaoTest  新建JUnit Test Case
//面向接口的编程,核心是代理模式
/*常用对象的作用域
 *1.SqlSessionFactoryBuilder:作用是用来创建session工厂
 *  所以session工厂创建成功,就可以将其所占有的资源释放掉,作用域就是一个局部变量
 *2.SqlSessionFactory:作用是用来创建session对象,我们没有必要每创建一个session对象,就是一个新的session工厂对象;
 *   所以 SqlSessionFactory对象的作用域为整个应用.  单例模式
 *3.SqlSession:
 * 作用使用CURD数据使用,由于该对象是非线程安全的,所以我们希望每个线程都拥有自己的session对象.
 */
  public class DaoTest {
       private SqlSessionFactory sf;
       private SqlSession session;
    @Before
	public void before() throws IOException {
	  //(1)读取mybatis配置文件
       InputStream inputStream = Resources.getResourceAsStream("mybatis_config.xml");
       //(2)创建配置文件并创建session工厂
         sf = new SqlSessionFactoryBuilder().build(inputStream);
	}
	@Test
	public void addStudent(){
	  //(3)创建session对象
	       session = sf.openSession();
	  //(4)创建要插入数据库中的对象
	  Student student = new Student(2,"鬼王",25);
	  //参数1: 映射文件的sql语句;  参数2: 要插入的对象
	    session.insert("com.xalo.model.Student.addStudent", student);
		session.commit();
		session.close();
	    System.out.println(student);
	 }
	@Test
	public void testInterface(){
	        session = sf.openSession();
	   StudentDao studentDao = session.getMapper(StudentDao.class);
	   //加载接口,使用接口中的方法
	   List<Student> list = studentDao.queryAllStudent();   //查询所有学生
	   List<Student> list = studentDao.queryAllStudentName(); //查询姓名
	   List<Map<String, Object>> list = studentDao.queryMulField2();//查询多条记录中的某几个字段
	   List<Map<String, Object>> list = studentDao.queryMulField();//不使用resultMap时,查询多条记录中的某几个字段
	   session.commit();
	   session.close();
	   System.out.println(list);
	 }
	 @Test
	 public void queryStudentById(){
	         session = sf.openSession();
	   StudentDao studentDao = session.getMapper(StudentDao.class);
	   //加载接口,使用接口中的方法
	    Student student = studentDao.queryStudentById(1);
	    session.commit();
	    session.close();
	    System.out.println(student);
	  }
	  @Test
	  public void updateNameById(){
	          session = sf.openSession();
	   StudentDao studentDao = session.getMapper(StudentDao.class);
	     //加载接口,使用接口中的方法
	     Integer count = studentDao.updateNameById("周帅", 1);
	     session.commit();
	     session.close();
	     System.out.println("修改成功" + count);
	    }
	@Test
	public void deleteStudentById(){
	        session = sf.openSession();
	   StudentDao studentDao = session.getMapper(StudentDao.class);
	    //加载接口,使用接口中的方法
	   Integer count =  studentDao.deleteStudentById(3);
	    session.commit();
	    session.close();
	    System.out.println("删除成功:" + count);
	   }
	   
	@After
	public void after() {

	}
   }

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值