MyBatis基础操作

Mybatis其实就是ORM。

ORM作用:实现对象和表之间的映射,对对象的操作会转换成对表的操作。

一, Mybatis入门实例

1) 导入Mybatis的jar包;

mybatis-3.2.8.jar

mysql-connector-java-5.1.18-bin2.jar

2) 创建实体;一个表对应着一个实体。实体名对应着表名,属性对应着表的字段;

package entity;
public class User {
	private int id;
	private String username;
	private String password;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

3):创建Mybatis的配置文件;

<?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>
  <environments default="development">
      <environment id="development">
            <transactionManager type="JDBC">
            </transactionManager>
            <dataSource type="UNPOOLED">
	            <property name="driver" value="com.mysql.jdbc.Driver"/>
	            <property name="url" value="jdbc:mysql://127.0.0.1:3306/imooc"/>        
	            <property name="username" value="root"/>
	            <property name="password" value="root"/>      
             </dataSource>
        </environment>  
    </environments>  
</configuration>

4):创建一个映射文件,定义SQL命令,指定查询结果与对象的映射,如果表字段与实体属性名字相同,Mybatis会自动进行映射;

<?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="entity.userMapper">
	  
	  <select id = "selectUser" resultType = "entity.User">
	  		select * from user where id = #{id}
	  </select>
	  
</mapper>

5):在配置文件中加载映射文件;

<?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>
  <environments default="development">
      <environment id="development">
            <transactionManager type="JDBC">
                <property name="" value=""/>
            </transactionManager>
            <dataSource type="UNPOOLED">
	            <property name="driver" value="com.mysql.jdbc.Driver"/>
	            <property name="url" value="jdbc:mysql://127.0.0.1:3306/imooc"/>        
	            <property name="username" value="root"/>
	            <property name="password" value="root"/>      
             </dataSource>
        </environment>  
    </environments>  
    <mappers>         
    	<mapper resource = "entity/userMapper.xml"/>  
    </mappers>
</configuration>

6):调用Mybatis的API访问数据库;

package util;

import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisUtil {
	
	//创建SqlSessionFactory,以及获得SqlSession
	public static SqlSession getSqlSession() throws IOException {
		// 通过配置文件获取数据库连接信息
		Reader reader = Resources.getResourceAsReader("config/Configuration.xml");
		// 通过配置信息构建一个SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		// 通过sqlSessionFactory打开一个数据库会话
		SqlSession sqlSession = sqlSessionFactory.openSession();
		return sqlSession;
	}

}

7)测试:

public class Test {
	
	public static void main(String[] args) throws IOException {
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		User user = sqlSession.selectOne("entity.userMapper.selectUser", 1);
		System.out.println("id = "+ user.getId() 
				+ ", username = " + user.getUsername()
				+ ", password = " + user.getPassword());
		sqlSession.close();
	}

}

二, Mybatis配置文件详解

2.1 properties:加载属性文件

<!-- 加载属性文件 -->
<properties resource="jdbc.properties"></properties>

加载 jdbc.properties 文件后,可以在Mybatis配置文件中使用${属性名}方式访问属性文件中的属性信息。例如:

<!-- 连接数据库驱动 -->
<property name="driver" value="${driverClassName}" />
<!-- 连接数据库URL -->
<property name="url" value="${jdbcUrl}" />
<!-- 连接数据库用户名 -->
<property name="username" value="${username}" />
<!-- 连接数据库密码 -->
<property name="password" value="${password}" />

2.2 typeAliases:指定类型别名

<!-- 指定对象的别名 -->
<typeAliases>
    <typeAlias type="com.chinasofti.beans.Product" alias="productAlia"/>
</typeAliases>

指定类型别名后,可以在映射文件的参数类型和返回结构类型中使用别名。

<select id="findAll" resultType="productAlia">
    select * from product
</select>

2.3 enviorments:配置Mybatis运行环境

<!-- 配置MyBatis的环境 -->
<environments default="dev">
    <!-- 配置一个环境 -->
    <environment id="dev">
        <!-- 配置事务管理器 JDBC(有事务)、MANAGED(托管) -->
        <transactionManager type="JDBC" />
        <!-- 配置数据源 JNDI(web服务器方式定义数据源)、POOLED(自带连接池)、UNPOOLED(不带连接池) -->
        <dataSource type="POOLED">
            <!-- 连接数据库驱动 -->
            <property name="driver" value="${driverClassName}" />
            <!-- 连接数据库URL -->
            <property name="url" value="${jdbcUrl}" />
            <!-- 连接数据库用户名 -->
            <property name="username" value="${username}" />
            <!-- 连接数据库密码 -->
            <property name="password" value="${password}" />
        </dataSource>
    </environment>
</environments>

一个environment配置一个运行环境。在实际开发中,一般都会把开发环境和生产环境分开配置。

2.4 mappers:加载映射文件。

<mappers>
    <mapper resource="com/chinasofti/beans/ProductMapper.xml"/>
</mappers>

三, ${}和#{}的区别

1):在预编译的时候,Mybatis会${属性名}中的内容简单替换具体的属性值,PrepardStatement对象进行预编译的时候会把#{属性值}替换成问号;

2):#{属性名}可以防止SQL注入;而${属性名}可能会引发SQL注入的安全问题。

四, 动态SQL命令

动态SQL命令可以在SQL命令中加入业务逻辑控制。动态SQL语句就是在程序运行的时候才对SQL命令进行编译和运行。

4.1 <where>和<if>

where:动态添加where标签;

if:判断条件是否成立,如果条件成立才添加SQL命令,否则不添加;

<select id="findAll" parameterType="productAlia" resultType="productAlia">
    select * from product
    <where>
        <if test="name != '' and name != null">
            name like CONCAT('%', #{name}, '%')
        </if>
    </where>

</select>

注意:if标签的test属性值也是ognl表达式,但是可以不写#{}

4.2 <sql>

作用:定义一个SQL命令,可以被其他标签引用,可以提高SQL命令的重用性。

命令格式:

<sql id="sql标识">
	sql命令
</sql>

引用SQL:

<include refid="sql标识"></include>

4.3 <foreach>标签

作用:循环生成SQL命令

命令格式:

<foreach collection="数组或集合" open="" close="" separator="" item=""></foreach>

collection:传入参数名。该参数可以是数组,也可以是集合类型,必选;

open:表示该SQL语句以什么开始,可选;

close:表示该SQL语句以什么结束,可选;

separate:Mybatis会在每次迭代时候给SQL语句添加separate属性指定的字符,可选;

item:指定访问集合元素的名字;

index:表示当前迭代的索引值,可选。

例如:

<select id="delete" resultMap="productResultMap">
	delete from product
	<where>
		product_id in
		<foreach collection="productIds" open="(" close=")" separator="," item="productId">
			${productId}
		</foreach>
	</where>
</select>

五, 接口映射

5.1 实现接口映射

接口映射的要求是什么?

​ 1)接口的方法名与SQL的id属性相同;

​ 2)调用session的getMapper方法,获取映射接口的代理对象;

​ 3)Mapper配置文件的命名空间的名字必须与接口的完整名字(包名+接口名)相同;

​ 4)接口方法的参数类型必须要与SQL命令的参数类型相同;

​ 5)接口方法的返回值类型要与SQL命令的返回结果类型相同。

实现接口映射的步骤:

1):定义一个接口类,提供一个接口方法,该方法的名字与SQL命令的id相同;

2):修改映射文件的命名空间名字。命名空间名字要与接口名相同;

3):调用session的getMapper方法获取映射接口的代理对象;

4):调用接口方法;

5):提交事务;

6):关闭资源;

package com.chinasofti.demo02接口映射;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.chinasofti.beans.Product;
import com.chinasofti.mapper.ProductMapper;
import com.chinasofti.utils.MyBatisUtil;

public class Demo02 {

	public static void main(String[] args) {
		// 获取SqlSession对象
		SqlSession session = MyBatisUtil.getSession();
		// 调用session对象的getMapper方法获取映射接口的代理对象。 
		ProductMapper productMapper = session.getMapper(ProductMapper.class);
		// 调用接口对象的方法
		Product product = new Product();
		product.setName("积木");
		List<Product> productList = productMapper.findAll(product);
		// 遍历集合
		for (Product p : productList) {
			System.out.println(p);
		}
		// 提交事务
		session.commit();
		// 关闭资源
		session.close();
	}
	
}

六,Mybatis注解

6.1 基本注解

@Select:定义select命令。

@Insert:定义insert命令。

@update:定义update命令。

@delete:定义delete命令。

public interface ProductMapper {

	@Select("select * from product")
	List<Product> findAll(Product product);
	
	@Insert("insert into product(name, price) values(#{name}, #{price})")
	void addProduct(Product product);
	
	@Update("update product set price = #{price} where id = #{id}")
	void updateProduct(Product product);
	
	@Delete("delete from product where id = #{id}")
	void deleteProduct(int id);
}

使用注解,就不需要在XxxMapper.xml文件中定义SQL命令。

定义完成后,需要Mybatis配置文件中加载映射接口。

<mappers>
    <mapper class="com.chinasofti.mapper.ProductMapper"/>
</mappers>

测试:

package com.chinasofti.demo02接口映射;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.chinasofti.beans.Product;
import com.chinasofti.mapper.ProductMapper;
import com.chinasofti.utils.MyBatisUtil;

public class Demo02 {

	public static void main(String[] args) {
		testDelete();
	}
	
	private static void testDelete() {
		// 获取SqlSession对象
		SqlSession session = MyBatisUtil.getSession();
		// 调用session对象的getMapper方法获取映射接口的代理对象。 
		ProductMapper productMapper = session.getMapper(ProductMapper.class);
		// 调用接口对象的方法
		productMapper.deleteProduct(8);
		// 提交事务
		session.commit();
		// 关闭资源
		session.close();
		System.out.println("删除成功!");
	}

	private static void testUpdate() {
		// 获取SqlSession对象
		SqlSession session = MyBatisUtil.getSession();
		// 调用session对象的getMapper方法获取映射接口的代理对象。 
		ProductMapper productMapper = session.getMapper(ProductMapper.class);
		// 调用接口对象的方法
		Product product = new Product();
		product.setId(8);
		product.setPrice(199);
		productMapper.updateProduct(product);
		// 提交事务
		session.commit();
		// 关闭资源
		session.close();
		System.out.println("修改成功!");
	}

	private static void testInsert() {
		// 获取SqlSession对象
		SqlSession session = MyBatisUtil.getSession();
		// 调用session对象的getMapper方法获取映射接口的代理对象。 
		ProductMapper productMapper = session.getMapper(ProductMapper.class);
		// 调用接口对象的方法
		Product product = new Product();
		product.setName("坦克");
		product.setPrice(1999);
		productMapper.addProduct(product);
		// 提交事务
		session.commit();
		// 关闭资源
		session.close();
		System.out.println("添加成功!");
	}

	private static void testFind() {
		// 获取SqlSession对象
		SqlSession session = MyBatisUtil.getSession();
		// 调用session对象的getMapper方法获取映射接口的代理对象。 
		ProductMapper productMapper = session.getMapper(ProductMapper.class);
		// 调用接口对象的方法
		Product product = new Product();
		product.setName("积木");
		List<Product> productList = productMapper.findAll(product);
		// 遍历集合
		for (Product p : productList) {
			System.out.println(p);
		}
		// 提交事务
		session.commit();
		// 关闭资源
		session.close();
	}
	
}

6.2 映射结果

@ResultType:指定结果类型

@Results:自定义结果映射

@Result:指定表的字段与实体属性的映射关系

@Select("select * from product")
//	@ResultType(Product.class)
@Results({
    @Result(column="id", property="id"),
    @Result(column="name", property="name"),
    @Result(column="price", property="price")
})
List<Product> findAll(Product product);

​ 如果查询结果的字段名与实体的属性名字相同的时候,可以不需要指定结果的类型,它会自动进行映射。

​ 如果查询结果的字段名与实体的属性名不相同,那么久需要自定义结果映射。

@SelectKey

@SelectKey(before = true|false, 
			keyProperty = "实体属性", 
			keyColumn = "主键列",
			resultType = 映射结果的类型, 
			statement="获取主键的sql"

before:指定在插入前或插入后执行statement语句。

statement:获取插入数据的id。

keyProperty:实体的id属性。

keyColumn:表的主键列。

resultType:返回结果类型。

例如:

@Insert("insert into product(product_name, product_price) values(#{name}, #{price})")
@SelectKey(
		before = false, 
		keyProperty = "id", 
		keyColumn = "product_id",
		resultType = Integer.class, 
		statement = { "select last_insert_id()" })
public int insert(Product product);

6.3 在注解中使用动态SQL

如果需要在注解中使用动态SQL,那么SQL命令需要放在script中定义。

举例(动态添加查询条件):

@Select("<script>"
			+ "select * from product"
			+ "<where>"
			+ "	<if test=\"name != null and name != ''\">"
			+ "		name like CONCAT('%', #{name}, '%')"
			+ "	</if>"
			+ "</where>"
			+ "</script>")
List<Product> findAll(Product product);

举例(删除多条记录):

@Delete({
	"<script>delete from product where product_id in " +
        "<foreach collection=\"ids\" item = \"id\" open=\"(\" separator=\",\" close=\")\">" +
    	    "#{id}" +
        "</foreach>" +
    "</script>"
})
void deleteProducts(int[] ids);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值