一.初始的加载
1.操作步骤
1.定义一个接口
public interface UserMapperDao // 接口
2.给接口里面放一个类型各种不同的类型
public interface UserMapperDao { // 接口 int insertUser(); User idUserSelect(int id); User checkLoginByMap(Map<String,Object> map); User UserPassword(User user); List<User> UsersService(); List<User> ageAndSexSelect(@Param("age") int age,@Param("sex") String sex);//根据age 和sex查 }
3.在自定义的类里面调用他
UserMapperDao dao = DaoXML.Dao(UserMapperDao.class); int insertUser = dao.insertUser(); //插入
2.定义MyBatis配置文件的加载代码
public static <T> T Dao(Class<T> type){ try{ //加载配置文件 InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//以字节方式获取 //获取sql sessionFactoryBuider SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessing_Factory = sessionFactoryBuilder.build(is);//工厂 SqlSession sqlSession = sqlSessing_Factory.openSession(true); //启动会话 可以设置是否自动提交 return sqlSession.getMapper(type);//调用方法 创建sql }catch (IOException e) { System.out.println("可能为文件名称不为:mybatis-config.xml"); e.printStackTrace(); } return null; }
二.对于各种不同的类型接口的定义
1.常用的名称作用
查询语句 | ||
名称 | 作用 | |
id | 对应的接口名称 不可以随便写 | User From(User user); |
resultType | 返回的类型 如图返回的是User | |
select | 代表是 查询 | |
resultMap 自定义类型 | ||
resultMap | 返回自定义类型,通过自定义的 这个元素对应的数据 | <resultMap id="xx" type="Password"> <result property="id" column="uid"></result> <result property="name" column="name"></result> <result property="password" column="password"></result> <result property="sex" column="sex"></result> <result property="psd.key" column="key"></result> </resultMap> <select id="selectMany" resultMap="xx"> select id as uid,name,password,sex from t_password where name=#{name} </select> |
这个里面放的是自定义类型的数据 里面的id代表到时查询语句"xx"对应的数据类型 | ||
type="Password" | 代表了返回的数据类型 | |
里面有两个参数property和column 对应的是 类的属性和数据库的字段对应关系 | ||
property | 类的属性 | |
column | 数据库字段名 | |
property="psd.key" column="key" | 代表如果是组合的话psd里面的key属性对应的数据库的key值 | |
自定义类型 | ||
用来给类里面属性是一个类类型的属性赋值 | <resultMap id="nameMany2" type="OneToManyS"> <id property="id" column="id"></id> <result property="name" column="name"></result> <association property="pad" javaType="Password"> <result property="id" column="uid"></result> <result property="name" column="usname"></result> <result property="password" column="password"></result> <result property="sex" column="sex"></result> </association> <!--调用两条sql select="com.myBatis.mappers.Dao3Delete3.selectMany" 使用 Dao3Delete3的selectMany的返回值吧他装到当前对象里面 column="uname" 需要传输过去的值 多个参数需要自定义返回值{id=id,name=uname}--> <association property="pad" select="com.myBatis.mappers.Dao3Delete3.selectMany" column="{id=id,name=uname}" fetchType="eager"> <!-- fetchType="eager" 吧当前分布查询立即加载--> <result property="pad" javaType="password"></result> </association> </resultMap> <select id="selectMany" resultMap="nameMany3"> SELECT * FROM onetomany where name=#{name}; </select> public interface Dao3Delete3 { Password selectMany(); //子查询 这里不需要参数 那边直接使用定义的名称就可以了 } | |
property | 对应的属性值名称(不是随便写的必须是类的属性名) | |
javaType | 属性值的类型 | |
select | 用来调用类里面的接口获取上一个查询语句对应的值 | |
column | 调用类的时候类对应的参数通过 {}符号分割 里面对应的属性 id=id 前一个sql查询查询到数据库中id的值 | |
fetchType | eager 表示在查询主实体时,同时也会查询关联实体 fetchType="lazy"表示只有在需要使用关联实体时才会进行查询 | |
动态SQL 第一个方法 choose when otherwise 相当于 if else if else | ||
choose | 表示一个完整的 if else if 标签 | <select id="多条件查询" resultType="Password" > SELECT * FROM t_password <where> <choose> <when test="id!= null and id!= ''"> id=#{id} </when> <when test="name!= null and name!= ''"> name=#{name} </when> <when test="password!= null and password!= ''"> password=#{password} </when> <when test="sex != null and sex != ''"> sex=#{sex} </when> <otherwise> id=1 </otherwise> </choose> </where> </select> |
when | 后面跟着的只要有一个满足后面的就不满足了 相当于else if | |
otherwise | 如果条件都不满足相当于else | |
where | 相当于给每一个条件都添加where | |
动态SQL 第二个方法 只有 if语句 | ||
prefix|suffix | 将trim 标签中内容前面或后面添加指定内容 | <select id="多条件查询" resultType="Password" > SELECT * FROM t_password <trim prefix="where" suffixOverrides="" prefixOverrides="and|or"> <if test="id!= null and id!= ''"> and id=#{id} </if> <if test="name!= null and name!= ''"> and name=#{name} </if> <if test="password!= null and password!= ''"> and password=#{password} </if> <if test="sex != null and sex != ''"> and sex=#{sex} </if> </trim> </select> |
suffixOverrides|prefixOverrides | 将trim标签中内容前面或者后面去掉指定内容 | |
prefix | 在前面添加where | |
suffix | 在后面添加指定内容 | |
suffixOverrides | 在前面删除指定内容 去掉前缀内容 可以使用 and|or 这样子就可以匹配2个字符 | |
prefixOverrides | 在后面删除指定内容 | |
test | 判断条件 | |
多条件删除 collection 表示名称 item 当前数组中的每一个元素 名称可以随便写 separator 分隔符 open 以什么 "(" 开始 close 以什么 ")" 结束 | ||
collection | 表示放入的属性名 | <!-- Integer 多条件删除(@Param("intID") Integer[] intID);--> <delete id="多条件删除" parameterType="java.lang.String" > delete from t_password where id in <foreach collection="intID" item="huoQuId" separator="," open="(" close=")"> #{huoQuId} </foreach> </delete> |
item | 当前数组中的每一个元素 名称可以随便写 | |
separator | 分隔符 用来添加每一个相隔开 | |
open | 以什么 "(" 开始 | |
close | 以什么 ")" 结束 | |
parameterType | 设置传输进来的类型 | |
用来别名设置的注解 | ||
@Param("id") | 代表了里面的数据类型到时在调用查询语句的时候可以取的名字 | Map FromMapSSS(@Param("id") int id) select * from t_user where id=#{id}; |
防止SQL注入 # $ 两符号 | ||
#{username} | 带$号代表了他是一个写什么传输什么的,不能防止sql语句注入(不推荐) | username=#{username} username=${username} |
${username} | 可以用来防止sql语句注入 | |
Sql片段 sql语句片段 可以直接用来引用 使用 方法来放入 | ||
id | 如果需要引入设置的名称 | <sql id="sqlColumns"> id,name,password,sex </sql> |
sql | sql语句片段 | |
其他 | ||
parameterType | 是传进来的类型 | 方法参数类型。 |
resultType | 传出去的类型 | 方法的返回类型 |
2.对于基本类型
对应的接口: User From(User user); 这里面的 <select id="From" resultType="User"> select * from t_user where username="${username}" and password=#{password}; </select>
二级缓存
1.开启二级缓存在对应的 resources工程文件里面添加
<cache readOnly="true"></cache> <!-- 二级缓存开启-->
1. 缓存的话 先查二级缓存 如果二级缓存没有的话 就去查一级 如果一级也没有就去查数据库
2. 第一级缓存相当于 SqlSession级别(不同接口不同缓存)
3. 第二及缓存相当于 SqlSessionFactory(不同接口相同同缓存)
二级缓存比上一级缓存好的地方是在于他是SqlSessionFactory(对于所有 的class文件 的 )
使用必须
1. 设置 标签
2.关闭或提交之后才有效
3. 使用接口
使用二级缓存必须实现 Serializable 接口 在对应的Modio层
public class Password implements Serializable {}
对应的二级换成代码
// 第一级缓存相当于 SqlSession级别(不同接口不同缓存) 第二及缓存相当于 SqlSessionFactory(不同接口相同同缓存) SqlSessionFactory factory = DaoXML.Dao二级缓存(); SqlSession sql = factory.openSession(true); //启动会话 可以设置是否自动提交 SqlSession sql2= factory.openSession(true); //启动会话 可以设置是否自动提交 //调用缓存接口 二级缓存 dao = sql.getMapper(二级缓存.class); 二级缓存 dao2 = sql2.getMapper(二级缓存.class); // session.clearCache(); //提交 // -------------使用第一个-------------------------- Password select = dao.Select(1); //查询模拟 缓存 System.out.println(select+"\n\n"); // sql.clearCache(); //清除缓存 sql.close(); //关闭接口 这样子才可以进行二级缓存 Password select3 = dao2.Select(1); //查询模拟 使用不同的接口的缓存测试 System.out.println(select3+"\n\n"); dao2.Update(1);//修改模拟 这样子就会让二级缓存失效 System.out.println("\n\n"); Password select2 = dao2.Select(1); //查询模拟 测试在重新插入之后发现二级缓存失效了(因为增删改会让二级缓存失效) System.out.println(select2+"\n\n"); sql2.close(); //关闭当前接口 结束生命周期
mybatis-config.xml 配置文件解析
引入配置文件
用来引入配置文件 账号密码 和连接串
<properties resource="jdbc.properties"/>
开启驼峰法
开启自动开启驼峰法 用来匹配数据库的大小写用 _ 代表要大写
<settings> <!-- 设置开启自动开启驼峰法--> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 设置延迟加载--> <setting name="lazyLoadingEnabled" value="true"/> </settings>
类型别名
以包为单位 设置类型别名 非常有用呀 !
1.但是不区分大小写所以要注意一点(如 User 和user 这2个类当成相同的)
2.在 这里面的 resultType使用
<typeAliases><!--这个标签应该在properties后面 用来设置类型别名 !!类型别名不区分大小写!!! 不设置alias那alias相当于User 以类名设置为准--> <!--<typeAlias type="com.myBatis.Midio.User" alias="User"></typeAlias> <!–设置别名 后面为别名名称–>--> <package name="com.myBatis.Midio"/><!--以包为单位 将包下面所有单位都设置默认类名--> </typeAliases>
Mysql连接
< environment 配置某个具体的环境
id:表示连接数据库的环境的唯一标识 不能重复
JDBC:表示当前环境中 ,执行sql语句的是JDBC原生的事物管理方式,事物的提交和回滚需要手 动 来处理
MANAGED 被管理,比如用spring管理
type 设置数据源的类型
type="POOLED UNPOOLED JNDI"
POOLED:表示使用数据库连接池来缓存数据库连接
UNPOOLED:表示不使用数据库连接池
JNDI :使用上下文中的数据源
name="driver" 连接
name="url" 连接串
name="username" 账号
name="password" 密码
<environments default="development"> <!-- environments 配置多个连接数据库的环境 default default设置默认使用的设置的环境的id--> <environment id="development"> <!-- environment 配置某个具体的环境 id:表示连接数据库的环境的唯一标识 不能重复 --> <transactionManager type="JDBC"/> <!-- 设置事物管理器是jdbc/MANAGEDa JDBC:表示当前环境中 ,执行sql语句的是JDBC原生的事物管理方式,事物的提交和回滚需要手动来处理 MANAGED 被管理,比如用spring管理 --> <dataSource type="POOLED"> <!-- dataSource 配置数据源 属性 : type 设置数据源的类型 type="POOLED UNPOOLED JNDI" POOLED:表示使用数据库连接池来缓存数据库连接 UNPOOLED:表示不使用数据库连接池 JNDI :使用上下文中的数据源 数据的连接 --> <!-- 引入配置文件--> <property name="driver" value="${jdbc.driver}"/> <!--连接--> <property name="url" value="${jdbc.url}"/> <!--连接串--> <property name="username" value="${jdbc.username}"/> <!--账号--> <property name="password" value="${jdbc.password}"/> <!--密码--> <!-- <property name="driver" value="com.mysql.jdbc.Driver"/> <!–连接–>--> <!-- <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_dao?characterEncoding=utf8"/> <!–连接串–>--> <!-- <property name="username" value="root"/> <!–账号–>--> <!-- <property name="password" value="root"/> <!–密码–>--> </dataSource> </environment> </environments>
引入配置文件!!非常好用
引入name 包下面所有的配置文件 有了这个就不需要每一次写一个 接口层都要来这里添加一条了
<!-- 引入配置文件--> <mappers> <!-- <mapper resource="com/myBatis/mappers/UserMapper.xml"/><!–引入自己设置的mysql语句 配置文件–>--> <!-- <mapper resource="com/myBatis/mappers/Dao2User.xml"/><!–引入自己设置的mysql语句 配置文件–>--> <package name="com.myBatis.mappers"/> </mappers>
教程:
记录一下解决循环但是里面没有值的问题
<?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.BST.idao.IArtileDao"> <!--调用映射接口--> <!-- 文章查找--> <!-- <resultMap id="amm" type="Article_message_model">--> <!-- <association property="classes" javaType="java.util.HashMap">--> <!--<!– <collection property="value" ofType="aaaMOdel">–>--> <!-- <collection property="value" javaType="aaaMOdel">--> <!-- <result property="name" column="abs"/>--> <!-- </collection>--> <!-- </association>--> <!-- </resultMap>--> <resultMap id="amm" type="Article_message_model"> <result property="classes" column="classes"/> <collection property="columnList" ofType="Article_message_column_model"> <result property="column" column="column"/> <collection property="articleList" ofType="Article_Model"> <result property="id" column="id"/> <result property="title" column="title"/> <result property="abs" column="abs"/> <result property="date" column="date"/> <result property="name" column="name"/> <result property="sum" column="sum"/> <result property="state" column="state"/> </collection> </collection> </resultMap> <!-- Article_message_model fromArticleAll(); //查询全部文章 resultMap="amm"--> <select id="fromArticleAll" resultMap="amm"> SELECT artile_column.classes,artile_column.`column`, article.id,article.title,article.abs,article.date,article.`name`,article.sum,article.state from artile_key left join artile_column ON artile_column.`column`=artile_key.columnvalue left join article ON article.id=artile_key.columnkey </select> </mapper> <!--跟标签--> <!-- <association property="classes" javaType="HashMap" resultMap="classResultMap" />--> <!-- 方法2 <association property="aaaMOdel" javaType="aaaMOdel"> <result property="key" column="abs"></result> </association> --> <!-- <result property="aaaMOdel.name" column="abs"></result>--> <!-- <result property="abc" column="abs"></result>--> <!-- <result column="classes" ></result>--> <!-- <result column="column" ></result>--> <!-- <result column="id" ></result>--> <!-- <result column="title" ></result>--> <!-- <result column="abs" ></result>--> <!-- <result column="date" ></result>--> <!-- <result column="name" ></result>--> <!-- <result column="sum" ></result>--> <!-- <result column="state" ></result>--> <!-- SELECT artile_column.classes,artile_column.`column`,--> <!-- article.id,article.title,article.abs,article.date,article.`name`,article.sum,article.state--> <!-- from artile_key--> <!-- left join artile_column ON artile_column.`column`=artile_key.columnvalue--> <!-- left join article ON article.id=artile_key.columnkey-->
记录的是
<?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.BST.idao.IArtileDao"> <!--调用映射接口--> <!-- 文章查找--> <!-- <resultMap id="amm" type="Article_message_model">--> <!-- <association property="classes" javaType="java.util.HashMap">--> <!--<!– <collection property="value" ofType="aaaMOdel">–>--> <!-- <collection property="value" javaType="aaaMOdel">--> <!-- <result property="name" column="abs"/>--> <!-- </collection>--> <!-- </association>--> <!-- </resultMap>--> <resultMap id="amm" type="Article_message_model"> <association property="classes" javaType="java.util.HashMap"> <collection property="value" javaType="aaaMOdel"> <result property="name" column="abs"/> </collection> </association> </resultMap> <!-- Article_message_model fromArticleAll(); //查询全部文章 resultMap="amm"--> <select id="fromArticleAll" resultMap="amm"> SELECT abs from article where id=5 </select> </mapper> <!--跟标签--> <!-- <association property="classes" javaType="HashMap" resultMap="classResultMap" />--> <!-- 方法2 <association property="aaaMOdel" javaType="aaaMOdel"> <result property="key" column="abs"></result> </association> --> <!-- <result property="aaaMOdel.name" column="abs"></result>--> <!-- <result property="abc" column="abs"></result>--> <!-- <result column="classes" ></result>--> <!-- <result column="column" ></result>--> <!-- <result column="id" ></result>--> <!-- <result column="title" ></result>--> <!-- <result column="abs" ></result>--> <!-- <result column="date" ></result>--> <!-- <result column="name" ></result>--> <!-- <result column="sum" ></result>--> <!-- <result column="state" ></result>--> <!-- SELECT artile_column.classes,artile_column.`column`,--> <!-- article.id,article.title,article.abs,article.date,article.`name`,article.sum,article.state--> <!-- from artile_key--> <!-- left join artile_column ON artile_column.`column`=artile_key.columnvalue--> <!-- left join article ON article.id=artile_key.columnkey-->