接口代理的开发方式(重点)
使用注解的开发方式(重点)
传统DAO实现类的开发方式(目前淘汰,因为分布式的使用)
参数占位符:
#{}:先使用?占位,执行SQL时将具体值赋值给?
${}:拼SQL,会存在SQL注入问题
parameterType:
用于设置参数类型,该参数可以省略
SQL语句中特殊字符处理:
转义字符
:CD提示<select id="selectById" resultType="User">
select * from user where id = #{id};
select>
查询数据可以直接查不会出错
但是增删改必须要开启事务,因为在mybaits中默认不会自动提交
事务两种开启方式:
在sqlSessionFactory.openSession(true);
sqlSession.commit()
删除
1.在接口中添加方法
2.在接口映射文件UserMapper.xml配置SQL语句
3.执行方法
1.在接口中添加方法
void deleteById(int id);
2.在接口映射文件UserMapper.xml配置SQL语句
3.执行方法
@Test
public void test3() throws IOException {
//因为要使用mybatis,所以要把配置文件mybatis-config.xml加载过来(在测试案例访问resoureces的资源,可以直接访问文件)
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//将这个文件转为流的形式,这个流会自动关闭,然后使用这个流获取连接,首先获得连接的builder对象
//这个builder需要new
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//到这步获得了连接的工厂类,接下来通过工厂类获得连接
SqlSession sqlSession = sqlSessionFactory.openSession();
//成功获得连接,使用这个连接将接口使用动态代理生成对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);//因为是动态代理所以用.class
//用代理对象调用接口中的方法
mapper.deleteById(3);
//提示成功,但是实际上确删除不成功,这是因为mybatis的事务
//在进行增删改的操作,要提交事务,mybatis事务的自动提交默认时关闭的
//有两种设置事务的方法,1.在sqlSessionFactory.openSession(true);2.sqlSession.commit()
sqlSession.commit();
//关闭资源,只需要关闭sqlSession
sqlSession.close();
}
修改
int update(User user);
<update id="update">
UPDATE user
SET username = #{username},
birthday =#{birthday},
sex=#{sex},
address=#{address}
WHERE id = #{id};
update>
@Test
public void test4() throws IOException {
//因为要使用mybatis,所以要把配置文件mybatis-config.xml加载过来(在测试案例访问resoureces的资源,可以直接访问文件)
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//将这个文件转为流的形式,这个流会自动关闭,然后使用这个流获取连接,首先获得连接的builder对象
//这个builder需要new
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//到这步获得了连接的工厂类,接下来通过工厂类获得连接
SqlSession sqlSession = sqlSessionFactory.openSession();
//成功获得连接,使用这个连接将接口使用动态代理生成对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);//因为是动态代理所以用.class
//用代理对象调用接口中的方法
User user = new User(1, "cat", Date.valueOf("2022-01-11"), "男", "地球");
mapper.update(user);
//提示成功,但是实际上确删除不成功,这是因为mybatis的事务
//在进行增删改的操作,要提交事务,mybatis事务的自动提交默认时关闭的
//有两种设置事务的方法,1.在sqlSessionFactory.openSession(true);2.sqlSession.commit()
sqlSession.commit();
//关闭资源,只需要关闭sqlSession
sqlSession.close();
}
插入
插入并获取新的主键值
int add(User user);
<insert id="add" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user
VALUES (null, #{username}, #{birthday}, #{sex}, #{address});
insert>
@Test
public void test5() throws IOException {
//因为要使用mybatis,所以要把配置文件mybatis-config.xml加载过来(在测试案例访问resoureces的资源,可以直接访问文件)
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//将这个文件转为流的形式,这个流会自动关闭,然后使用这个流获取连接,首先获得连接的builder对象
//这个builder需要new
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//到这步获得了连接的工厂类,接下来通过工厂类获得连接
SqlSession sqlSession = sqlSessionFactory.openSession();
//成功获得连接,使用这个连接将接口使用动态代理生成对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);//因为是动态代理所以用.class
//用代理对象调用接口中的方法
User user = new User(10086, "dog", Date.valueOf("1980-10-24"), "男", "地球");
System.out.println(user.getId());
int row = mapper.add(user);
System.out.println(row);
System.out.println(user.getId());
//提示成功,但是实际上确删除不成功,这是因为mybatis的事务
//在进行增删改的操作,要提交事务,mybatis事务的自动提交默认时关闭的
//有两种设置事务的方法,1.在sqlSessionFactory.openSession(true);2.sqlSession.commit()
sqlSession.commit();
//关闭资源,只需要关闭sqlSession
sqlSession.close();
}
当只有一个参数时,在xml中编写sql时可以使用传入的参数名,但是多参数的时候不能直接用参数名
select
//多参数
//报错Available parameters are [arg1, arg0, param1, param2]
//方案1,散装,用@Param给咱们的参数起个名字
//List selectByCondition(@Param("username") String username, @Param("sex") String sex);
//方案2,使用对象封装
//List selectByCondition(User user);
//方案3,使用Map集合封装
List<User> selectByCondition(Map<String,String> map);
<select id="selectByCondition" resultType="com.jwl.pojo.User">
select * from user where username like #{username} and sex = #{sex};
select>
sql语句并不是固定不变的,要根据条件编写合适的sql语句
if标签
select if标签 where标签
//动态sql
List<User> selectByIf(@Param("username") String username, @Param("sex") String sex);
<select id="selectByIf" resultType="com.jwl.pojo.User">
select * from user
<where>
<if test="username!=null and username != ''">
username = #{username}
if>
<if test="sex != null and sex !=''">
and sex = #{sex};
if>
where>
select>
update set标签
//这样new一个user,再通过set方法传入数据,如果没传入数据的字段就会是null,会把数据库中不准备修改的数据变为Null
//为了避免这种情况,也要加入if标签来判断
int updateByIf(User user);
<update id="updateByIf">
UPDATE user
<set>
<if test="username !=null and username != ''">
username = #{username},
if>
<if test="birthday !=null">
birthday = #{birthday},
if>
<if test="sex !=null and sex != ''">
sex = #{sex},
if>
<if test="address !=null and address != ''">
address = #{address},
if>
set>
WHERE id = #{id};
update>
批量删除 foreach标签
void deleteByIds(int[] ids);
<delete id="deleteByIds">
delete from user where id in
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
foreach>
delete>
choose标签
跟java的switch类似
List<User> selectBySex(int sex);
<select id="selectBySex" resultType="com.jwl.pojo.User">
select * from user
<where>
<choose>
<when test="sex==1">
sex = '男';
when>
<when test="sex==0">
sex = '女';
when>
<otherwise>
sex = '女';
otherwise>
choose>
where>
select>
sql标签
<select id="selectAll" resultType="User">
select
<include refid="useAll"/>
from user;
select>
<sql id="useAll">
id
,username,birthday,sex,address
sql>
在上述的例子中都是数据库字段名和实体类名相同,查询方便
但是很多情况下数据库字段名和实体类名不同
因为数据库字段名和实体类的属性名不一致,查到的数据封装不到Order中,
解决方法有三种
1.取别名,在写sql时,取对应实体类的别名
2.在mybaits配置文件中的标签中设置自动将数据库和实体类名称转换< setting name=“mapUnderscoreToCamelCase” value=“true”/>,默认为关闭
3.使用resultMap
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
settings>
<resultMap id="OrderMap" type="Order">
<id column="o_id" property="oId"/>
<result column="user_id" property="userId"/>
<result column="create_time" property="createtime"/>
resultMap>
<select id="selectAllBy" resultMap="OrderMap">
select * from tb_order;
select>
如果你对本文有疑问,你可以在文章下方对我留言,敬请指正,对于每个留言我都会认真查看。