Mybatis

Mybatis

原始方式

SqlMapConfig.xml+UserMapper.xml

查询

SqlMapConfig.xml

<?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>
    <typeAliases>
        <package name="com.yan.model"/>
    </typeAliases>
    <environments default="development">
<!--        配置环境-->
        <environment id="development">
<!--            配置JDBC事务管理器-->
            <transactionManager type="JDBC">
            </transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://172.16.0.5:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="Mapper/UserMapper.xml"/>
    </mappers>
</configuration>

UserMapper.xml

<?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=" ">
    <select id="findUserById" parameterType="int" resultType="user">
    select * from user where id=#{id};
    </select>
</mapper>

使用:

  		//读取配置文件
        InputStream   inputStream= Resources.getResourceAsStream("SqlMapConfig.xml");
        //通过SqlSessionFactoryBuilder获取 sessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过sessionFactory获取sqlSession
        SqlSession sqlSession = sessionFactory.openSession();
        //通过 sqlSession 操作数据库
        User user = sqlSession.selectOne("findUserById", 10);
        //关闭sqlSession
        sqlSession.close();
        System.out.println(user);

模糊查询:

${} 取值 用在Mapper.xml文件中表示值替换相当于字符串拼接sql

会造成sql注入,但在某些场景必须用它,比如 order by ${colname}

简单类型${}中变量必须为value

UserMapper.xml

	<select id="findUserByName" parameterType="string" resultType="user">
    select * from user where username like '%${value}%'
    </select>

测试:

 //读取配置文件
        InputStream   inputStream= Resources.getResourceAsStream("SqlMapConfig.xml");
        //通过SqlSessionFactoryBuilder获取 sessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过sessionFactory获取sqlSession
        SqlSession sqlSession = sessionFactory.openSession();
        //通过 sqlSession 操作数据库
        List<User> users = sqlSession.selectList("findUserByName", "张");
        //关闭sqlSession
        sqlSession.close();
        System.out.println(users);

插入

UserMapper.xml

<!--    添加 -->
    <insert id="addUser" parameterType="user" >
        <!--    为user设置id -->
        <selectKey keyProperty="id" resultType="int" order="AFTER">
            SELECT LAST_INSERT_ID();
        </selectKey>
        insert into user (username,sex,birthday,address)
        value (#{username},#{sex},#{birthday},#{address})
    </insert>

测试:

 //读取配置文件
        InputStream   inputStream= Resources.getResourceAsStream("SqlMapConfig.xml");
        //通过SqlSessionFactoryBuilder获取 sessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过sessionFactory获取sqlSession
        SqlSession sqlSession = sessionFactory.openSession();
        User user=new User();
        user.setUsername("yan");
        user.setBirthday(new Date());
        user.setAddress("长丰县");
        user.setSex("2");
		//通过 sqlSession 操作数据库
        int affectRow = sqlSession.insert("addUser", user);
        //提交数据
        sqlSession.commit();
        //关闭sqlSession
        sqlSession.close();
        System.out.println(affectRow);
		System.out.println(user.getId());

删除

UserMapper.xml

<!--    删除-->
    <delete id="deleteUser" parameterType="int">
        delete from user where id=#{id}
    </delete>

测试

 //读取配置文件
        InputStream   inputStream= Resources.getResourceAsStream("SqlMapConfig.xml");
        //通过SqlSessionFactoryBuilder获取 sessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过sessionFactory获取sqlSession
        SqlSession sqlSession = sessionFactory.openSession();
        //通过 sqlSession 操作数据库
        int affectRow = sqlSession.delete("deleteUser", 29);
		//提交数据
        sqlSession.commit();
        //关闭sqlSession
        sqlSession.close();
        System.out.println(affectRow);

更新

UserMapper.xml

<!--    更新用户-->
    <update id="updateUser" parameterType="user">
        update user set
        username=#{username},sex=#{sex},birthday=#{birthday},address=#{address}
        where id = #{id}
    </update>

测试

 //读取配置文件
        InputStream   inputStream= Resources.getResourceAsStream("SqlMapConfig.xml");
        //通过SqlSessionFactoryBuilder获取 sessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过sessionFactory获取sqlSession
        SqlSession sqlSession = sessionFactory.openSession();
        User user=new User();
        user.setUsername("闫绍帅");
        user.setBirthday(new Date());
        user.setAddress("长丰县");
        user.setSex("2");
        user.setId(26);
    	//通过 sqlSession 操作数据库
        int affectRow = sqlSession.update("updateUser", user);
        //提交数据
        sqlSession.commit();
        //关闭sqlSession
        sqlSession.close();
        System.out.println(affectRow);

#{}和${}区别

#{}相当于占位符?

当入参是对象时,#{}中填入有get方法的变量名就会取到对象中的值

当入参是简单类型时,#{}可填写任意值

类似于PreparedStatement,可以防止sql注入

${}只是简单的替换值不会做额外的处理,相当于拼接sql字符串

当入参是对象时${}中填入有get方法的变量名就会取到对象中的值

当入参是简单类型时,${}中只能填写value

${}会引起sql注入

mapper代理

默认使用jdk动态代理

Mapper和接口放在同一目录(todo:Mapper接口与xml分离)

SqlMapConfig.xml

<?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>
    <typeAliases>
        <package name="com.yan.model"/>
    </typeAliases>
    <environments default="development">
<!--        配置环境-->
        <environment id="development">
<!--            配置JDBC事务管理器-->
            <transactionManager type="JDBC">
            </transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://172.16.0.5:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.yan.mapper"/>
    </mappers>
</configuration>

UserMapper.xml

<?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.yan.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="user">
    select * from user where id=#{id};
    </select>
<!--    添加 -->
    <insert id="save" parameterType="user" >
        <selectKey keyProperty="id" resultType="int" order="AFTER">
            SELECT LAST_INSERT_ID();
        </selectKey>
        insert into user (username,sex,birthday,address)
        value (#{username},#{sex},#{birthday},#{address})
    </insert>
</mapper>

UserMapper.java

public interface UserMapper {
    int save(User user);
    User findUserById(int id);
}

测试:

 //读取配置文件
        InputStream   inputStream= Resources.getResourceAsStream("SqlMapConfig.xml");
        //通过SqlSessionFactoryBuilder获取 sessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过sessionFactory获取sqlSession
        SqlSession sqlSession = sessionFactory.openSession();
        //通过 sqlSession 操作数据库
//        List<User> users = sqlSession.selectList("findUserByName", "张");
        User user=new User();
        user.setUsername("闫绍帅");
        user.setBirthday(new Date());
        user.setAddress("长丰县");
        user.setSex("2");
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//        mapper.save(user);
        User user1 = mapper.findUserById(36);
        sqlSession.commit();
        System.out.println(user1);

配置log4j

依赖:

  			<dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>

log4j.properties(类路径下)

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.yan.mapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

SqlMapConfig.xml的configuration标签下:

	 <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>

参数映射

parameterType

ONGL表达式支持嵌套类型,用 . 获取嵌套类型属性,参数是hashmap时候.后面写键名

内置别名 int-->int,String-->string,HashMap-->hashmap...

resultType

列名和返回对象属性名一致或者返回简单类型可以用resultType

列名与对象属性名不一致

1.起别名

2.用resultMap

例:

  <resultMap id="userResultMap" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username_"/>
        <result property="sex" column="sex"/>
        <result property="birthday" column="birthday"/>
    </resultMap>
    <select id="findUserById" parameterType="int" resultMap="userResultMap">
    select id ,username username_,sex,birthday from user where id=#{id};
    </select>

动态SQL

1.条件查询拼接

<!--    如果user.id==0返回所有否则根据id查询-->
    <select id="findUsers" parameterType="user" resultType="user">
        select * from user
        <where>
            <if test="id !=null and id != 0 and id.toString()!=''">
                id=#{id}
            </if>
            <if test="username !=null and username !=''">
                AND username=#{username};
            </if>
        </where>
    </select>

2.SQL片段

	<sql id="if-test">
        <if test="id !=null and id != 0 and id.toString()!=''">
            id=#{id}
        </if>
        <if test="username !=null and username !=''">
            AND username=#{username};
        </if>
    </sql>
	<!--    如果user.id==0返回所有否则根据id查询-->
    <select id="findUsers" parameterType="user" resultType="user">
        select * from user
        <where>
           <include refid="if-test"></include>
        </where>
    </select>

3.foreach

<!--    foreach遍历-->
    <select id="findUsersByIds" parameterType="list" resultType="user">
        select * from user
        <where>
            <if test="list!=null and list.size()>0">
                id in
                <foreach collection="collection" index="i" open="(" close=")" item="item" separator=",">
                    ${item}
                </foreach>
            </if>
        </where>
    </select>

懒加载

Orders.java

public class Orders {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;
    
    //用户信息
    private User user;
    
    //订单明细
    private List<Orderdetail> orderdetails;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number == null ? null : number.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note == null ? null : note.trim();
    }

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public List<Orderdetail> getOrderdetails() {
		return orderdetails;
	}

	public void setOrderdetails(List<Orderdetail> orderdetails) {
		this.orderdetails = orderdetails;
	}

	@Override
	public String toString() {
		return "Orders [id=" + id + ", userId=" + userId + ", number=" + number
				+ ", createtime=" + createtime + ", note=" + note + ", user="
				+ user + ", orderdetails=" + orderdetails + "]";
	}
    
}

SqlMapConfig.xml开启懒加载:

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

OrdersMapper.xml

<mapper namespace="com.yan.mapper.OrdersMapper">
   <resultMap id="lazyLoadUser" type="orders">
       <id property="id" column="id"/>
       <result property="userId" column="user_id"/>
       <association property="user" select="com.yan.mapper.UserMapper.findUserById" column="user_id"/>
   </resultMap>
    <select id="findOrdersById" parameterType="int" resultMap="lazyLoadUser">
        select * from orders where id=#{id};
    </select>
</mapper>

用到user属性时才会加载association中的查询语句,column="user_id"传入参数

mybatis缓存

一级缓存

session级别缓存(默认开启)

二级缓存

全局缓存,多session共用(session关闭才会写入缓存commit,close等)

SqlMapConfig.xml中允许使用二级缓存

	<settings>
		<settings>
			<!--允许使用二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

UserMapper.xml使用二级缓存

 <cache/>

model要继承序列化接口Serializable

任意session执行insert,delete,update等操作,二级缓存数据会清空

禁用某个方法使用二级缓存

 <select id="findUserById" parameterType="int" resultMap="userResultMap" useCache="true">
        select id ,username username_,sex,birthday from user where id=#{id};
  </select>

Mybatis自带缓存不支持分布式缓存,可以整合其他缓存实现分布式缓存

原文地址:https://www.cnblogs.com/yanshaoshuai/p/12944442.html