Mybatis的入门学习
一款优秀的持久层框架
官网:
https://mybatis.org/mybatis-3/zh/index.html
快速入门
在导入jar包之后,配置xml文件
最好使用Mybatis-config.xml作为文件名
内容如下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
<!--                数据库链接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///zhoupeng?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--       指定sql映射文件 -->
        <mapper resource="SQL映射文件的地址"/>
    </mappers>
</configuration>
再配置一个sql的配置文件,文件名以,对象+Mapper.xml命名
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:名称空间
-->
<mapper namespace="test">
    <select id="selectBlog" resultType="Blog">
        select * from Blog where id = #{id}
    </select>
</mapper>
开始操作
  //1,加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "Mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2,获取SqlSession的对象,用他来执行SQL
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3,执行sql
        List<User> users = sqlSession.selectList("test.selectAll");
//        for (int i = 0; i < users.size(); i++) {
//            System.out.println(users.get(i));
//        }
        System.out.println(users);
        //4,释放资源
        sqlSession.close();
这里说一下,如果mybatis查出来的全为空,就记得起别名,和对应类的属性名一致
如下:
类属性,记得写get,set方法
private String id;
private String name;
private String age;
private String sex;
private String diZhi;
private String dianHua;
private String time;
private String buMen;数据库,列名:
create table 员工表
(
    员工编号 int(4) auto_increment
        primary key,
    员工姓名 varchar(20)  not null,
    年龄   int(2)       not null,
    性别   varchar(1)   not null,
    地址   varchar(255) not null,
    电话   varchar(13)  not null,
    创建时间 varchar(255) null,
    部门编号 varchar(255) null
);sql配置文本
<select id="selectAll" resultType="com.mybatisxuexi.GongJu.User">
    select
    `员工编号` as id,
    `员工姓名` as name,
    `性别` as sex,
    `年龄` as age,
    `部门编号` as buMen,
    `地址` as diZhi,
    `电话` as dianHua,
    `创建时间` as time
    from
    `员工表`
</select>
但这样又会存在着硬编码问题(虽然很少,但写代码的过程中要尽量去避免,所以我们使用Mapper代理开发)
Mapper
怎么做呢?
首先,我们要在src下定义一个 对象类名+Mapper 的接口
然后 在resoures下创建一个路径和 接口 路径相同的 sql 配置文件 , 这里要注意 在创建报名的时候,一定是 包名/包名/包名 不能是包名.包名.包名 虽然这两种写法在创建完成后看起来的效果是一样的,但第二种方法在编译的时候只会创建一个包,从而导致找不到对象
之后,接口里面的方法名 采用 sql配置文件 对应 sql 的 id ,返回值看情况给,查询的话最好是 List<对象类名>
最后, sql配置文件里,mapper标签里的那个, namespace="接口的全类名"
<mapper namespace="com.mybatisxuexi.JieKou.UserMappers">使用的话,就是在获取 SqlSession 对象之后,使用getMapper 方法获取接口的实现类,最后调用接口实现类中写好的方法
       //1,加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "Mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2,获取SqlSession的对象,用他来执行SQL
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3,执行sql
        UserMappers mapper = sqlSession.getMapper(UserMappers.class);
        System.out.println(mapper.selectAll2());
        //4,释放资源
        sqlSession.close();
而且在使用Mapper代理之后,mybatis的配置文件哪里,可以不用配置sql配置文件的地址,而直接使用接口包的地址,,, 前提是,接口名和配置文件名相同
这里说一下,除了查询之外,其他几个,增删改,都是需要事务提交的!
mybatis将事务的自动提交设置成false
我们在操作完毕后需要使用 sqlSession.commit() 去提交事务
在添加时,我们可能会同时将数据加到几个表里去,与其他表形成外键的联系,直接获取是获取不到的,必须在<insert>标签里有如下设置
<insert useGeneratedKeys="true" keyProperty="主键名">
条件注入
当我们使用Mapper代理操作 并需要对某些sql需要进行条件操作的时候,可以使用转义字符
Mapper类
User seletbyId(int id);sql配置文件
 <select id="seletbyId" resultType="com.mybatisxuexi.GongJu.User">
        select
        *
        from
        `员工表` AS user,
        where
        `员工编号`=#{id}
    </select>
调用的时候,加个参数就好了。
几个注意点:
一,
使用 #{} 的方式去动态控制条件时,实际上是将条件换成 ? 可以防止sql注入
也可以使用 ${} 去控制,但这个是直接拼接,不能防止sql注入
所以以后基本都是用 #{} 进行控制
二,
由于是在xml文档里面进行编写,所以免不了有些特殊的条件语法无法书写,比如 > < 号,这时候我们可以使用两种方式解决
1,转义字符,这个直接百度就行
2,使用
<![CDATA[
    想写的符号        
]]>在id里直接输入大写的 CD 然后回车就会自动生成
三,
如果有多个条件参数,则需要进行处理,处理方法有三种
1,散装,直接写,
Mapper类
 /**
     *
     * @param sex 性别
     * @param age 小于多少的年龄
     * @return
     */
    List<User> selectGeRen(@Param("sex") String sex, @Param("age") int age);sql配置的xml
 <select id="selectGeRen" resultType="com.mybatisxuexi.GongJu.User">
        select
        *
        from
        `员工表` AS u
        where
        u.`性别`=#{sex}
        AND
        u.`年龄` <![CDATA[
            <
        ]]> #{age};
    </select>使用的时候,方法参数前必须配置@Param(“ #{}里面的参数名 ”)
2,使用对象
创建一个实体类对象,对象属性必须要和 #{} 里面的参数名对应上(只需要其中几个对应就行)
Mapper类
/**
     *
     * @param t  实体类对象
     * @return
     */
    List<User> selectGeRen(T1 t);实体类
public class T1 {
    private String sex;
    private int age;
    private int a;
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public T1() {
    }
    public T1(String sex, int age) {
        this.sex = sex;
        this.age = age;
    }
}
3,使用map
必须要添加与之对应的键
Mapper类
/**
     *
     * @param m map集合
     * @return
     */
    List<User> selectGeRen(Map m);创建的map集合
 Map map = new HashMap<>();
 map.put("sex","男");
 map.put("age",40);
 System.out.println(mapper.selectGeRen(map));
动态SQL
如果有多个条件参数,而不做处理的话,当用户只输入一个参数的时候,就只能查到空值,简单来说就是查不到,所以我们的代码需要根据用户的输入来进行动态的变化
所以,mybatis为我们提供了一个动态标签
<if></if>
<select id="selectGeRen" resultType="com.mybatisxuexi.GongJu.User">
        select
        *
        from
        `员工表` AS u
        where
        <if test="sex != null and sex != ''">
            u.`性别`=#{sex}
    	</if>
        <if test="age != null">
            AND u.`年龄` <![CDATA[
            	<
        	]]> #{age};
    	</if>  
    </select>
但是这样的话,又会出现一个bug,就是,当第一个 sex 为空时,编译后的sql语句为:
select
* 
from 
`员工表` AS u
where
and AND u.`年龄` < ?;这样肯定是错误的,所以得改进上面的方法,
有两种方式,第一个是加恒等式
<select id="selectGeRen" resultType="com.mybatisxuexi.GongJu.User">
        select
        *
        from
        `员工表` AS u
        where  1=1
        <if test="sex != null and sex != ''">
            AND u.`性别`=#{sex}
    	</if>
        <if test="age != null">
            AND u.`年龄` <![CDATA[
            	<
        	]]> #{age};
    	</if>  
    </select>在第一个条件前面加 AND ,然后在where后面加 1=1 这样的恒等式就可以解决
第二种方式是mybatis提供的<where></where>标签
<select id="selectGeRen" resultType="com.mybatisxuexi.GongJu.User">
        select
        *
        from
        `员工表` AS u
        <where>
        	<if test="sex != null and sex != ''">
            	u.`性别`=#{sex}
    		</if>
        	<if test="age != null">
            	AND u.`年龄` <![CDATA[
            		<
        		]]> #{age};
    		</if>
    	</where>
    </select>where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
然后就是单条件的动态查询,
需求,用户可以选择查询方式,
这时候就where后面只能跟一个语句,但却需要动态选择,在java代码中,这样的方案可以用Switch解决,恰好,mybatis给我们提供了一个这样的方式
choose、when、otherwise这三个标签
<select id="selectGeRen" resultType="com.mybatisxuexi.GongJu.User">
        select
        *
        from
        `员工表` AS u
       <where>
    <choose><!-- 相当于switch-->
    <when test="sex != null and sex != ''"><!--相当于cese-->
            u.`性别`=#{sex}
            </when>
    <when test="age != null">
            AND u.`年龄` <![CDATA[
            <
        ]]> #{age};
            </when>
            <otherwise><!--相当于那个啥?忘了,d开头那个-->
            1=1
            </otherwise>
    </choose>
       </where>
    </select>
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号