读配置文件、
xml文件查mybatis文档
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>
<!--读配置文件、起别名、字段属性不一致、插入数据主键回填、resultMap映射一对一 多对一、一对多、多对多、
#预编译? $区别字符串拼接,可以传递sql参数进去、多个参数读取、模糊查询concat、嵌套sql、动态sql select标签set标签trim标签 foreach 用于删除 if -->
<!--properties使用外部配置文件连接通过${配置文件的key}取值 必须放在第一行-->
<properties resource="db.properties">
<!--里面的property代表另外配置属性 优先级没有配置文件高-->
<property name="username" value="root"></property>
</properties>
<!--log4j和STDOUT_LOGGING的日志 name=logImpl -->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<!--typeAliases用于起别名两种方式 用于resultType不用写全限定类名 只用写alias的名字
package用于扫描一个指定的包 默认别名为小写的类名,大写也可读取到-->
<!-- 方式一type全限定类名-->
<typeAlias type="com.lee.entity.User" alias="User"></typeAlias>
<!--方式二package用于扫描一个指定的包 默认别名为小写的类名,大写也可读取到 -->
<package name="com.lee.entity" ></package>
<!--方式三使用注解给User类起别名用于resultType使用@Alias("user")-->
</typeAliases>
<environments default="development">
<!--default是环境的id,选中使用哪个环境 transactionManager type两种jdbc和managed-->
<!--dataSource两种POOLED和unPOOLED表示池子 -->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--用于连接数据库-->
<!-- <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://10.36.144.46:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>-->
<!--使用配置文件的方式读取-->
<property name="driver" value="${driverClass}"/>
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--用于实现mapper连接到实现接口的xml
每一个Mapper.xml都要在核心mybatis.xml上配置-->
<mapper resource="mapper/IUserMapper.xml"/>
<!--用class和package规定在同一包下并且同名-->
<!--<mapper class="com.lee.dao.IUserDao"></mapper>-->
<!--<package name="com.lee.dao"></package>-->
</mappers>
</configuration>
mapper配置
<?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">
<!--万能map可以parameterType为map #{key}为key
模糊查询的%value%给定,只给value
-->
<!--映射namespace为IUserDao的接口,id为方法名 resultType为返回类型全限定名-->
<mapper namespace="com.lee.mapper.IBaseDao">
</mapper>
读配置文件、
起别名、
字段属性不一致、
插入数据主键回填、
resultMap映射一对一 多对一、一对多、多对多、
#预编译? $区别字符串拼接,可以传递sql参数进去、
多个参数读取、
模糊查询concat、
嵌套sql、
动态sql select标签 set标签 trim标签 foreach 用于删除 if
获取SqlSession
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
String file="mybatis02.xml";
InputStream resourceAsStream = null;
try {
resourceAsStream = Resources.getResourceAsStream(file);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
测试
@Test
public void selectManager(){
//MybatisUtils工具类 里面通过SqlSessionFactoryBuilder.build(“配置文件”)的方法创建了SqlSessionFactory
//通过getSqlSession()返回了一个sqlSession,通过SqlSessionFactory.openSession()得到sqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
//相当于创建了一个接口的实现类
IUserMapper mapper = sqlSession.getMapper(IUserMapper.class);
//selectManager是接口中的一个方法 通过mapper调用
//这个方法被xml文件映射了,xml文件中写了sql语句 所以就通过调用方法去映射到了xml中的sql语句
ArrayList<Manager> managers = mapper.selectManager();
System.out.println(managers);
// for (Manager manager : managers) {
// System.out.println(manager);
// }
}
IUserMapper.xml中的配置 即在这里写sql语句
简单了解如何使用
//add 方法 参数类型即add方法的参数的类型 Manager
//#{name} 通过#{Manager的属性名}来取得值,后面会提到获取多个参数的方式,当参数为一个对象时,可以#{Manager的属性名}获取
<insert id="add" parameterType="Manager">
<selectKey order="AFTER" keyProperty="id" resultType="integer">
select last_insert_id()
</selectKey>
insert into manager (name,password,age) values (#{name},#{password},#{age})
</insert>
加深使用 对一和对多
public class Manager {
private Integer id;
private String mname;
private String password;
private Integer age;
private Integer uid;
//Manager表中查到的user表的数据保存在user中,一对一或者多对一
private User user;
}
public class User {
private Integer id;
private String name;
private String password;
private Integer age;
private String email;
private Double salary;
private Date opendate;
private String png;
private Integer role;
//user表中查到的manager数据保存在managerList中一对多或者多对多
private List<Manager> managerList;
}
//对一的情况,即一对一、多对一,用association,property表示Manager类中的属性名称
javaType类型为User
即Manager类中有一个属性 用来保存User的信息,数据库表中多个manager对应一个user,
类似于多个员工对应一个部门,查询员工信息包含部门信息
<!--resultMap解决属性和字段名称不一致情况 type就是返回值类型-->
<resultMap id="resultUserMap" type="manager">
<id column="id" property="id"></id>
<result column="name" property="mname"></result>
<result column="password" property="password"></result>
<result column="age" property="age"></result>
<result column="uid" property="uid"></result>
<!--一对一、多对一 用association property的值user就是Manager中的属性user -->
<association property="user" javaType="User">
<!--里面的操作一样是解决字段不一致 需要在多表查询起别名 不然出现重复字段 信息会出错,出错为查询了manager的信息后 user的信息会被manager的信息覆盖
也可以不起别名,前提是表中的字段不重复,即表1和表2的字段名称不是一样的
-->
<id column="uid" property="id"></id>
<result column="uname" property="name"></result>
<result column="upwd" property="password"></result>
<result column="uage" property="age"></result>
</association>
</resultMap>
<!--id:selectManager 为接口中的selectManager方法
在调用接口中的方法时自动映射过来
resultMap映射到上面的resultMap标签
u.id uid,u.name uname,u.password upwd,u.age uage起别名
别名用于防止信息出错
-->
<select id="selectManager" resultMap="resultUserMap">
SELECT
m.*,u.id uid,u.name uname,u.password upwd,u.age uage
FROM
manager m
INNER JOIN t_user u ON (
m.uid = u.id)
</select>
<resultMap id="resultUserMap" type="user">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="password" property="password"></result>
<result column="age" property="age"></result>
<result column="email" property="email"></result>
<result column="salary" property="salary"></result>
<result column="opendate" property="opendate"></result>
<result column="png" property="png"></result>
<result column="role" property="role"></result>
<!--多对多、一对多 collection -->
<collection property="managerList" ofType="Manager">
<id column="mid" property="id"></id>
<result column="mname" property="mname"></result>
<result column="mpwd" property="password"></result>
<result column="mage" property="age"></result>
</collection>
</resultMap>
<select id="selectManager" resultMap="resultUserMap">
SELECT
u.*,m.id mid,m.name mname,m.password mpwd,m.age mage,m.uid mid
FROM
t_user u
INNER JOIN manager m ON (
u.id=m.uid)
</select>
解决多个参数读取的问题
<resultMap id="resultManagerMap" type="Manager">
<id column="id" property="id"></id>
<result column="name" property="mname"></result>
<result column="password" property="password"></result>
<result column="age" property="age"></result>
</resultMap>
<select id="selectManagerByName" resultMap="resultManagerMap" >
<!--多个参数读取,因为不是通过名字去得到参数的,如果参数是对象,就通过对象的属性名得到
方式一 select * from manager where name=#{arg0} and password=#{arg1}
方式二 select * from manager where name=#{param1} and password=#{param2}
方式三 select * from manager where name=#{name} and password=#{password} 此时传的是个对象,parameterType为对象 一个对象时通过属性名得到参数
方式四 select * from manager where name=#{key} and password=#{key}此时传的是个对象parameterType为map对象 一个map对象时通过map 的key得到
方式五 select * from manager where name=#{param1.name} and password=#{param2.password} 此时方法里传的是两个对象,对象1的name,对象2的password 也是通过属性名称得到参数
方式六:参数里面加@param注解
模糊查询用concat select * from manager where name like concat('%',#{name},'%')
一个参数时,名字也不用对应,模糊查询的#{name},方法的参数名为name1也可得到值
-->
select * from manager where name like concat('%',#{name},'%')
</select>
${}和#{}的区别
#{}的语句编译后是预编译的效果,用占位符?代替
${}语句编译后是字符串拼接的效果,比较危险,当项目上线后数据库没有访问权限时,可以在页面写${}语句去查询数据
<!--sql语句直接传进来 能够直接使用 属于字符串拼接 没有预编译
#预编译? $区别字符串拼接,可以传递sql参数进去
-->
<select id="selectManagerBy$" resultMap="resultManagerMap">
<!-- ${sql}接收传进来的sql语句直接操作-->
${sql}
</select>
用sql标签写重复代码
嵌套sql语句,以及where标签、set标签、trim标签
if里的内容和输出的内容冲突用cdate解决,<![CDATE[<if test=“age<20”/>]]>
where
<select id="selectManagerByNamePwd" resultMap="resultManagerMap">
<!--<include refid="sql"></include>
用refid嵌套id为sql的代码-->
<include refid="sql"></include>
</select>
<!--sql标签用作写重复代码-->
<sql id="sql">
select * from manager
<where>
<!--where标签作用代替where 以及自动删掉多余的and-->
<!--传递为多个对象时要用param1.mname param2.password的方式-->
//if判断的作用是,当查询条件为一个时,也能够查询,
// 即传进来的manager对象里只有mname有值,其他均为null
<if test="mname!=null and mname!=''">
and name=#{mname}
</if>
<if test="password!=null and password!=''">
and password=#{password}
</if>
</where>
</sql>
set
<update id="updateMethod" parameterType="Manager">
update manager
<set><!--set标签的作用 去除多余的逗号 代替set-->
<if test="mname!=null and mname!=''">
name=#{mname},
</if>
<if test="password!=null and password!=''">
password=#{password},
</if>
</set>
<where>
id=#{id}
</where>
</update>
trim
<update id="updateMethod" parameterType="Manager">
update manager
<trim prefix="set" suffixOverrides=","><!--trim 替代select 和set 去除多余的逗号和and
prefix前缀 suffix后缀 suffixOverrides替代掉的后缀 prefixOverrides 替代掉的前缀-->
<if test="mname!=null and mname!=''">
name=#{mname},
</if>
<if test="password!=null and password!=''">
password=#{password},
</if>
</trim>
<where>
id=#{id}
</where>
</update>
Foreach
<!--删除多条语句 传进来为list,只有一个参数,不按照名字得到值,collection里面的类型为list、array、map ,item为变量名通过#{id}获取 separator 分割list的每个数据-->
<delete id="deleteMethod" >
delete from manager where id in
<foreach collection="list" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</delete>
主键回填
<!-- 方式一支持主键自增的情况下 用useGeneratedKeys="true"设置为主键回填,回填的属性为id keyProperty="id"-->
<insert id="add" parameterType="Manager" useGeneratedKeys="true" keyProperty="id">
insert into manager (name,password,age) values (#{name},#{password},#{age})
</insert>
<!--方式二 主键自增情况下 主键回填 selectKey 查找增加后的id ,回填到keyProperty='id'order决定是在增加之后查询 -->
<insert id="add" parameterType="Manager">
<selectKey order="AFTER" keyProperty="id" resultType="integer">
select last_insert_id()
</selectKey>
insert into manager (name,password,age) values (#{name},#{password},#{age})
</insert>
<!--不支持主键自增的情况下 在sql语句插入之前把主键准备好 uuid-->
<insert id="add" parameterType="Manager" >
<selectKey order="BEFORE" keyProperty="id" resultType="string">
SELECT REPLACE(UUID(),'-','');
</selectKey>
insert into manager (id,name,password,age) values (#{id},#{name},#{password},#{age})
</insert>