MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,而且更名为MyBatis。是一个基于Java的持久层框架php
不管是Mybatis、Hibernate都是ORM的一种实现框架,都是对JDBC的一种封装!java
到目前为止,咱们已经在持久层中学了几种技术了...mysql
那咱们为啥还要学Mybatis呢???如今Mybatis在业内大行其道,那为啥他能那么火呢??sql
Hibernate是一个比较老旧的框架,用过他的同窗都知道,只要你会用,用起来十分舒服...啥sql代码都不用写...可是呢,它也是有的缺点::处理复杂业务时,灵活度差, 复杂的HQL难写难理解,例如多表查询的HQL语句数据库
而JDBC很容易理解,就那么几个固定的步骤,就是开发起来太麻烦了,由于什么都要咱们本身干..apache
而SpringDAO其实就是JDBC的一层封装,就相似于dbutils同样,没有特别出彩的地方....数组
咱们能够认为,Mybatis就是jdbc和Hibernate之间的一个平衡点...毕竟如今业界都是用这个框架,咱们也不能不学呀!微信
其实咱们已经学过了Hibernate了,对于Mybatis入门其实就很是相似的。所以就很简单就能掌握基本的开发了...session
导入Mybatis开发包mybatis
导入mysql/oracle开发包
建立一张表
create table students(
id int(5) primary key,
name varchar(10),
sal double(8,2)
);
复制代码
建立实体:
/** * Created by ozc on 2017/7/21. */
public class Student {
private Integer id;
private String name;
private Double sal;
public Student() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
}
复制代码
建立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>
<!-- 加载类路径下的属性文件 -->
<properties resource="db.properties"/>
<!-- 设置一个默认的链接环境信息 -->
<environments default="mysql_developer">
<!-- 链接环境信息,取一个任意惟一的名字 -->
<environment id="mysql_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用链接池方式来获取链接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
<!-- 链接环境信息,取一个任意惟一的名字 -->
<environment id="oracle_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用链接池方式来获取链接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${oracle.driver}"/>
<property name="url" value="${oracle.url}"/>
<property name="username" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
复制代码
使用Mybatis的API来建立一个工具类,经过mybatis配置文件与数据库的信息,获得Connection对象
package cn.itcast.javaee.mybatis.util;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/** * 工具类 * @author AdminTC */
public class MybatisUtil {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
private static SqlSessionFactory sqlSessionFactory;
/** * 加载位于src/mybatis.xml配置文件 */
static{
try {
Reader reader = Resources.getResourceAsReader("mybatis.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/** * 禁止外界经过new方法建立 */
private MybatisUtil(){}
/** * 获取SqlSession */
public static SqlSession getSqlSession(){
//从当前线程中获取SqlSession对象
SqlSession sqlSession = threadLocal.get();
//若是SqlSession对象为空
if(sqlSession == null){
//在SqlSessionFactory非空的状况下,获取SqlSession对象
sqlSession = sqlSessionFactory.openSession();
//将SqlSession对象与当前线程绑定在一块儿
threadLocal.set(sqlSession);
}
//返回SqlSession对象
return sqlSession;
}
/** * 关闭SqlSession与当前线程分开 */
public static void closeSqlSession(){
//从当前线程中获取SqlSession对象
SqlSession sqlSession = threadLocal.get();
//若是SqlSession对象非空
if(sqlSession != null){
//关闭SqlSession对象
sqlSession.close();
//分开当前线程与SqlSession对象的关系,目的是让GC尽早回收
threadLocal.remove();
}
}
/** * 测试 */
public static void main(String[] args) {
Connection conn = MybatisUtil.getSqlSession().getConnection();
System.out.println(conn!=null?"链接成功":"链接失败");
}
}
复制代码
配置实体与表的映射关系
<?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">
<!-- namespace属性是名称空间,必须惟一 -->
<mapper namespace="cn.itcast.javaee.mybatis.app04.Student">
<!-- resultMap标签:映射实体与表 type属性:表示实体全路径名 id属性:为实体与表的映射取一个任意的惟一的名字 -->
<resultMap type="student" id="studentMap">
<!-- id标签:映射主键属性 result标签:映射非主键属性 property属性:实体的属性名 column属性:表的字段名 -->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sal" column="sal"/>
</resultMap>
</mapper>
复制代码
如今咱们已经有了Mybatis的配置文件和表与实体以前的映射文件了,所以咱们要将配置文件和映射文件关联起来
<mappers>
<mapper resource="StudentMapper.xml"/>
</mappers>
复制代码
在测试类上,咱们是能够获取获得链接的
public class StudentDao {
public void add(Student student) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
sqlSession.insert();
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
Student student = new Student(1, "zhongfucheng", 10000D);
studentDao.add(student);
}
}
复制代码
到如今为止,咱们实体与表的映射文件仅仅映射了实体属性与表的字段的关系...
咱们在Hibernate中若是想要插入数据什么的,只要调用save()方法就好了。Hibernate是自动化屏蔽掉了数据库的差别,而咱们Mybatis是须要本身手动编写SQL代码的...
那么SQL代码是写在哪里的呢???明显地,咱们做为一个框架,不可能在程序中写SQL,咱们是在实体与表的映射文件中写的!
Mybatis实体与表的映射文件中提供了insert标签【SQL代码片断】供咱们使用
//在JDBC中咱们一般使用?号做为占位符,而在Mybatis中,咱们是使用#{}做为占位符
//parameterType咱们指定了传入参数的类型
//#{}实际上就是调用了Student属性的get方法
<insert id="add" parameterType="Student">
INSERT INTO ZHONGFUCHENG.STUDENTS (ID, NAME, SAL) VALUES (#{id},#{name},#{sal});
</insert>
复制代码
在程序中调用映射文件的SQL代码片断
public void add(Student student) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
sqlSession.insert("StudentID.add", student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
复制代码
值得注意的是:Mybatis中的事务是默认开启的,所以咱们在完成操做之后,须要咱们手动去提交事务!
咱们在上面中已经简单知道了Mybatis是怎么使用的以及工做流程了,此次咱们使用Mybatis来完成CRUD的操做,再次巩固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>
<!-- 加载类路径下的属性文件 -->
<properties resource="db.properties"/>
<!-- 设置一个默认的链接环境信息 -->
<environments default="mysql_developer">
<!-- 链接环境信息,取一个任意惟一的名字 -->
<environment id="mysql_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用链接池方式来获取链接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
<!-- 链接环境信息,取一个任意惟一的名字 -->
<environment id="oracle_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用链接池方式来获取链接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${oracle.driver}"/>
<property name="url" value="${oracle.url}"/>
<property name="username" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="zhongfucheng/StudentMapper.xml"/>
</mappers>
</configuration>
复制代码
映射文件
<!-- namespace属性是名称空间,必须惟一 -->
<mapper namespace="StudentID">
<!-- resultMap标签:映射实体与表 type属性:表示实体全路径名 id属性:为实体与表的映射取一个任意的惟一的名字 -->
<resultMap type="zhongfucheng.Student" id="studentMap">
<!-- id标签:映射主键属性 result标签:映射非主键属性 property属性:实体的属性名 column属性:表的字段名 -->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sal" column="sal"/>
</resultMap>
<insert id="add" parameterType="zhongfucheng.Student">
INSERT INTO ZHONGFUCHENG.STUDENTS (ID, NAME, SAL) VALUES (#{id},#{name},#{sal});
</insert>
</mapper>
复制代码
插入数据
public class StudentDao {
public void add(Student student) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
sqlSession.insert("StudentID.add", student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
Student student = new Student(3, "zhong3", 10000D);
studentDao.add(student);
}
}
复制代码
增长select标签
<!-- 查询根据id resultMap这个属性表明是返回值类型,返回值的类型是Student,就是上面实体类型 -->
<select id="findById" parameterType="int" resultMap="studentMap">
SELECT * FROM STUDENTS WHERE id = #{id};
</select>
复制代码
查询出来的结果是一个Student对象,咱们调用SelectOne方法
public Student findById(int id) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
return sqlSession.selectOne("StudentID.findById",id);
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
Student student = studentDao.findById(1);
System.out.println(student.getName());
}
复制代码
<!-- 查询全部数据 返回值类型讲道理是List<Student>的,但咱们只要写集合中的类型就好了 -->
<select id="findAll" resultMap="studentMap">
SELECT * FROM STUDENTS;
</select>
复制代码
咱们查询出来的结果不仅仅只有一个对象了,所以咱们使用的是SelectList这个方法
public List<Student> findAll() throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
return sqlSession.selectList("StudentID.findAll");
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
List<Student> students = studentDao.findAll();
System.out.println(students.size());
}
复制代码
<!--根据id删除-->
<delete id="delete" parameterType="int">
DELETE FROM STUDENTS WHERE id=#{id};
</delete>
复制代码
调用delete方法删除
public void delete(int id ) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
sqlSession.delete("StudentID.delete", id);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
studentDao.delete(1);
}
复制代码
<!--更新-->
<update id="update" parameterType="zhongfucheng.Student">
update students set name=#{name},sal=#{sal} where id=#{id};
</update>
复制代码
查询出对应的对象,对其进行修改
public void update(Student student ) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
sqlSession.update("StudentID.update", student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
Student student = studentDao.findById(2);
student.setName("fucheng");
student.setSal(2000D);
studentDao.update(student);
}
复制代码
<!--
注意:这个insert/update/delete标签只是一个模板,在作操做时,实际上是以SQL语句为核心的
即在作增/删/时,insert/update/delete标签可通用,
但作查询时只能用select标签
咱们提倡什么操做就用什么标签
-->
复制代码
分页是一个很是实用的技术点,咱们也来学习一下使用Mybatis是怎么分页的...
咱们的分页是须要多个参数的,并非像咱们以前的例子中只有一个参数。当须要接收多个参数的时候,咱们使用Map集合来装载!
public List<Student> pagination(int start ,int end) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
/** * 因为咱们的参数超过了两个,而方法中只有一个Object参数收集 * 所以咱们使用Map集合来装载咱们的参数 */
Map<String, Object> map = new HashMap();
map.put("start", start);
map.put("end", end);
return sqlSession.selectList("StudentID.pagination", map);
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
List<Student> students = studentDao.pagination(0, 3);
for (Student student : students) {
System.out.println(student.getId());
}
}
复制代码
那么在实体与表映射文件中,咱们接收的参数就是map集合
<!--分页查询-->
<select id="pagination" parameterType="map" resultMap="studentMap">
/*根据key自动找到对应Map集合的value*/
select * from students limit #{start},#{end};
</select>
复制代码
何为动态SQL??回顾一下咱们以前写的SSH项目中,有多条件查询的状况,以下图
咱们当时刚开始作的时候,是须要在Controller中判断SQL是否已经有条件了,由于SQL语句须要拼接起来....这样干的话,就很是容易出错的。
以下的代码,若是有多个条件的话,那么拼接起来很容易出错!
public String listUI() {
//查询语句
String hql = "FROM Info i ";
List<Object> objectList = new ArrayList<>();
//根据info是否为null来判断是不是条件查询。若是info为空,那么是查询全部。
if (info != null) {
if (StringUtils.isNotBlank(info.getTitle())) {
hql += "where i.title like ?";
objectList.add("%" + info.getTitle() + "%");
}
}
infoList = infoServiceImpl.findObjects(hql,objectList);
ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);
return "listUI";
}
复制代码
后来,咱们以为这样很差,因而就专门写了一个查询助手类:
package zhongfucheng.core.utils;
import java.util.ArrayList;
import java.util.List;
/** * Created by ozc on 2017/6/7. */
public class QueryHelper {
private String fromClause = "";
private String whereClause = "";
private String orderbyClause = "";
private List<Object> objectList;
public static String ORDER_BY_ASC = "asc";
public static String ORDER_BY_DESC = "desc";
//FROM子句只出现一次
/** * 构建FROM字句,并设置查询哪张表 * @param aClass 用户想要操做的类型 * @param alias 别名 */
public QueryHelper(Class aClass, String alias) {
fromClause = " FROM " + aClass.getSimpleName() + " " + alias;
}
//WHERE字句能够添加多个条件,但WHERE关键字只出现一次
/** * 构建WHERE字句 * @param condition * @param objects * @return */
public QueryHelper addCondition(String condition, Object... objects) {
//若是已经有字符了,那么就说明已经有WHERE关键字了
if (whereClause.length() > 0) {
whereClause += " AND " + condition;
} else {
whereClause += " WHERE" + condition;
}
//在添加查询条件的时候,?对应的查询条件值
if (objects == null) {
objectList = new ArrayList<>();
}
for (Object object : objects) {
objectList.add(object);
}
return this;
}
/** * * @param property 要排序的属性 * @param order 是升序仍是降序 * @return */
public QueryHelper orderBy(String property, String order) {
//若是已经有字符了,那么就说明已经有ORDER关键字了
if (orderbyClause.length() > 0) {
orderbyClause += " , " + property +" " + order;
} else {
orderbyClause += " ORDER BY " + property+" " + order;
}
return this;
}
/** * 返回HQL语句 */
public String returnHQL() {
return fromClause + whereClause + orderbyClause;
}
/** * 获得参数列表 * @return */
public List<Object> getObjectList() {
return objectList;
}
}
复制代码
这样一来的话,咱们就不用本身手动拼接了,给咱们的查询助手类去拼接就行了。
而若是咱们使用Mybatis的话,就能够免去查询助手类了。由于Mybatis内部就有动态SQL的功能【动态SQL就是自动拼接SQL语句】!
<!--多条件查询【动态SQL】-->
<!--会自动组合成一个正常的WHERE字句-->
<!--name值会从map中寻找-->
<select id="findByCondition" resultMap="studentMap" parameterType="map">
select * from students
<where>
<if test="name!=null">
and name=#{name}
</if>
<if test="sal!=null">
and sal < #{sal}
</if>
</where>
</select>
复制代码
查询出来小于9000块的人
public List<Student> findByCondition(String name,Double sal) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
/** * 因为咱们的参数超过了两个,而方法中只有一个Object参数收集 * 所以咱们使用Map集合来装载咱们的参数 */
Map<String, Object> map = new HashMap();
map.put("name", name);
map.put("sal", sal);
return sqlSession.selectList("StudentID.findByCondition", map);
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
List<Student> students = studentDao.findByCondition(null,9000D);
for (Student student : students) {
System.out.println(student.getId() + "---" + student.getName() + "----" + student.getSal());
}
}
复制代码
<!--动态更新-->
<!--不要忘了逗号-->
<update id="updateByConditions" parameterType="map">
update students
<set>
<if test="name!=null">
name = #{name},
</if>
<if test="sal!=null">
sal = #{sal},
</if>
</set>
where id = #{id}
</update>
复制代码
给出三个更新的字段
public void updateByConditions(int id,String name,Double sal) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
/** * 因为咱们的参数超过了两个,而方法中只有一个Object参数收集 * 所以咱们使用Map集合来装载咱们的参数 */
Map<String, Object> map = new HashMap();
map.put("id", id);
map.put("name", name);
map.put("sal", sal);
sqlSession.update("StudentID.updateByConditions", map);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
studentDao.updateByConditions(2,"haha",500D);
}
复制代码
delete from students where id in (?,?,?,?);
复制代码
而咱们的Mybatis又支持动态SQL,因此删除起来就很是方便了!
<delete id="deleteByConditions" parameterType="int">
<!-- foreach用于迭代数组元素 open表示开始符号 close表示结束符合 separator表示元素间的分隔符 item表示迭代的数组,属性值能够任意,但提倡与方法的数组名相同 #{ids}表示数组中的每一个元素值 -->
delete from students where id in
<foreach collection="array" open="(" close=")" separator="," item="ids">
#{ids}
</foreach>
</delete>
复制代码
删除编号为2,3,4的记录
public void deleteByConditions(int... ids) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
/** * 因为咱们的参数超过了两个,而方法中只有一个Object参数收集 * 所以咱们使用Map集合来装载咱们的参数 */
sqlSession.delete("StudentID.deleteByConditions", ids);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
studentDao.deleteByConditions(2,3,4);
}
复制代码
咱们要想动态插入的话,就比其余的DML语句稍微复杂一点,由于它有两部分是不肯定的,日常的SQL语句是这样的:
insert into student(id,name,sal) values(?,?,?)
复制代码
SQL代码块是不能像以前那样帮咱们自动去除多余的逗号的,所以咱们须要使用trim标签来本身手动去除...
编写insertSQL语句的时候,不要忘了写()括号。
<!--SQL片断默认是不帮咱们自动生成合适的SQL,所以须要咱们本身手动除去逗号-->
<sql id="key">
<trim suffixOverrides=",">
<if test="id!=null">
id,
</if>
<if test="id!=null">
name,
</if>
<if test="id!=null">
sal,
</if>
</trim>
</sql>
<sql id="value">
<trim suffixOverrides=",">
<if test="id!=null">
#{id},
</if>
<if test="id!=null">
#{name},
</if>
<if test="id!=null">
#{sal},
</if>
</trim>
</sql>
<!--动态插入-->
<insert id="insertByConditions" parameterType="zhongfucheng.Student">
insert into students (<include refid="key"/>) values
(<include refid="value"/>)
</insert>
复制代码
测试三个不一样内容的数据
public void insertByConditions(Student student) throws Exception {
//获得链接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片断的ID,就能够调用对应的映射文件中的SQL
sqlSession.insert("StudentID.insertByConditions", student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
studentDao.insertByConditions(new Student(55, null, null));//name和sal为空
studentDao.insertByConditions(new Student(66, "haxi", null));//sal为空
studentDao.insertByConditions(new Student(77, null, 3999d));//name为空
}
复制代码
若是文章有错的地方欢迎指正,你们互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同窗,能够关注微信公众号:Java3y