目录
1 、mybatis入门操作
1.1 、封装map
学习了个注解 @beforeEach 做了简化,抽取了生成 SQLSessionFactory 方法。
利用mybatis查询数据时 如果返回结果确定唯一则使用pojo对象接受,如果不能确定就使用list集合接受 。
mybatis默认支持单值传参,如果遇到多值需要将多值转化为单值 1.利用pojo对象封装 2.利用万能map集合 3.如果参数一定使用多值操作,那么就用使用@Param(“sex”)String sex进行封装
package com.jt;
import com.jt.mapper.DemoUserMapper;
import com.jt.pojo.DemoUser;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.annotation.Resource;
import javax.naming.Name;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestMybatis2 {
private SqlSessionFactory sqlSessionFactory;//成员变量>调用
@BeforeEach
public void init() throws IOException {
String resource = "mybatis\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testMybatis01() {
SqlSession sqlSession = sqlSessionFactory.openSession();
//sqlSessionFactory是成员变量 直接调用(里面的是空的)会报空指针异常
//所以得调用init()方法 或者 添加注解@beforeEach
//作用:测试API中的注解 在执行@Test注解方法之前会先执行
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
List<DemoUser> list = demoUserMapper.findAll();
System.out.println(list);
sqlSession.close();
}
// 查询naem=王昭君的用户
@Test
public void testFindTwo() throws IOException {
//指定配置文件地址
String resource = "mybatis\\mybatis-config.xml";
//通过io流 加载指定的配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//动态生成SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取mapper接口
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
String Name = "王昭君";
DemoUser demoUser = demoUserMapper.findTwo(Name);
System.out.println(demoUser);
sqlSession.close();
}
@Test
public void testFindByName() {
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
String name = "王昭君";
List<DemoUser> list = demoUserMapper.findByName(name);
System.out.println(list);
sqlSession.close();
}
//查询sex=女的用户 年龄>18
@Test
public void testFindBYSA() {
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
DemoUser user = new DemoUser();
user.setSex("女").setAge(18);
List<DemoUser> list = demoUserMapper.findBySA(user);
System.out.println(list);
sqlSession.close();
// [DemoUser(id=18, name=甄姬c, age=20, sex=女),
// DemoUser(id=27, name=阿科, age=20, sex=女),
// DemoUser(id=31, name=王昭君, age=19, sex=女),
// DemoUser(id=41, name=白骨精, age=3000, sex=女),
// DemoUser(id=44, name=大乔, age=19, sex=女)]
}
@Test
public void testFindBYSA2() {
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
DemoUser user = new DemoUser();
String sex="女";
int age=18;
List<DemoUser> list = demoUserMapper.findBySA2(sex,age);
// Parameter 'sex' not found. Available parameters are [arg1, arg0, param1, param2]
System.out.println(list);
sqlSession.close();
}
@Test
// mybatis如果遇到多值传参时,默认条件采用下标的方式获取数据
// mybatis天生只支持单值传参,如果遇到多值的问题,则应该将多值封装为单值
// 封装为实体对象 user对象
// 更为常用的方式 map集合
// 如果传递的数据有多个可以使用注解@param("key") @Param("sex") String sex,@Param("age") int age
public void testFindBYSA3() {
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
DemoUser user = new DemoUser();
Map<String,Object>map = new HashMap<>();
map.put("sex", "女");
map.put("age", 18);
List<DemoUser> list = demoUserMapper.findBySA3(map);
// Parameter 'sex' not found. Available parameters are [arg1, arg0, param1, param2]
// mybatis如果遇到多值传参时,默认条件采用下标的方式获取数据
// mybatis天生只支持单值传参,如果遇到多值的问题,则应该将多值封装为单值
// 封装为实体对象 user对象
// 更为常用的方式 map集合
System.out.println(list);
sqlSession.close();
}
}
demoUserMapper.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">
<!--namespace是mybaits映射文件的唯一标识,与接口对应-->
<!--xml映射文件 必须与 接口一对一绑定
namespace : 指定需要绑定的接口名称 不能重复
-->
<mapper namespace="com.jt.mapper.DemoUserMapper">
<!--id 表示接口方法 需要与接口方法绑定
resultType 返回值结果类型 返回对象的包路径
规则:sql语句不要添加多余的;号,oracle数据库不能添加;号
方法:select update delete
-->
<select id="findAll" resultType="com.jt.pojo.DemoUser">
select id,name,age,sex from demo_user
</select>
<!-- parameterType参数类型 其中的类型 程序会根据参数自动更新自动判断所以可以省略不写
mybatis中通过获取参数
-->
<select id="findOne" parameterType="int" resultType="com.jt.pojo.DemoUser" >
select * from demo_user where id= #{id}
</select>
<select id="findTwo" parameterType="String" resultType="com.jt.pojo.DemoUser" >
select * from demo_user where name = #{name}
</select>
<select id="findByName" parameterType="String" resultType="com.jt.pojo.DemoUser" >
select * from demo_user where name = #{name}
</select>
<!--如果传递的参数是对象,则通过#{属性}可以直接获取数据-->
<select id="findBySA" resultType="com.jt.pojo.DemoUser" >
select * from demo_user where sex = #{sex} and age>#{age}
</select>
<select id="findBySA2" resultType="com.jt.pojo.DemoUser" >
select * from demo_user where sex = #{sex} and age>#{age}
</select>
<!--map的集合有两个数据sex age
如果传递参数是一个map集合通过#{key}获取数据
-->
<select id="findBySA3" resultType="com.jt.pojo.DemoUser" >
select * from demo_user where sex = #{sex} and age>#{age}
</select>
</mapper>
DemoUserMapper接口
package com.jt.mapper;
import com.jt.pojo.DemoUser;
import org.apache.ibatis.annotations.Param;
import org.apache.tomcat.jni.User;
import java.util.List;
import java.util.Map;
/*
*
*
* */
public interface DemoUserMapper {
//查询所有的表数据
public List<DemoUser> findAll();
DemoUser findOne(int id);
DemoUser findTwo(String name);
List<DemoUser> findByName(String name);
List<DemoUser> findBySA(DemoUser user);
//利用@Param注解 将里面的封装为map
List<DemoUser> findBySA2(@Param("sex") String sex,@Param("age") int age);
List<DemoUser> findBySA3(Map<String, Object> map);
}
1.2 、参数知识总结
1.如果参数采用对象封装,则可以使用#{属性}取值;
2.如果参数有多个,可以封装map实现参数的传递,可以利用#{key}来获取数据;
3.也可以使用@Param将多个参数封装为map,利用#{key}的方式来获取数据。
1.3 、业务说明
1.使用# { }获取数据时,默认有预编译的效果,防止sql注入攻击;
2.mybatis使用#{}获取数据时,默认添加一对引号;
3.当以字段名称为参数时,一般使用${},但是这样的sql慎用,可能会出现sql注入攻击问题,一般条件下能使用#{}不使用${}。
@Test
public void testFindOrder(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
String column="age";
List<DemoUser> list = demoUserMapper.findOrder(column);
System.out.println(list);
sqlSession.close();
}
<select id="findOrder" resultType="com.jt.pojo.DemoUser">
select * from demo_user Order by ${column}
</select>
1.4 、mybatis的常规CURD操作
新增操作:
//mybatis中的更新操作,默认都是开启的,如果进行更新操作,需要提交事务
@Test
public void testSaveUser(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
//数据库主键自增,所以对象的ID可以为null
DemoUser demoUser=new DemoUser(null,"佛媛",99,"女");
int rows = demoUserMapper.saveUser(demoUser);
if(rows>0){
System.out.println("影响的行数:"+rows);
sqlSession.commit();//事务提交
}
sqlSession.close();
}
<!-- mybatis执行更新操作时,自动的返回影响的行数-->
<insert id="saveUser" >
insert into demo_user value (null , #{name} , #{age} , #{sex})
</insert>
返回结果后刷新数据库
mybatis原生条件下做更新操作时 需要手动提交事务
自动提交事务:
SQLSessionFactory.openSession(true);
删除操作:
/*
* 删除id=???????
* sql: delete from demo_user where id in (232,233,234)
* 规则:如果遇到相同的多个数据,则一般采用集合的方式来封装数据
* 封装方式:
* array
* List
* map<List>
*
* */
@Test
public void testDeleteIds(){
SqlSession sqlSession=sqlSessionFactory.openSession(true);
DemoUserMapper demoUserMapper=sqlSession.getMapper(DemoUserMapper.class);
int [] ids={232,233,234};
demoUserMapper.deleteIds(ids);
System.out.println("删除成功!");
// sqlSession.close();
}
<delete id="deleteIds">
delete from demo_user where id in (
<foreach collection="array" item="id" separator=",">
#{id}
</foreach>)
</delete>
1.5 、xml文件中常用的转义字符
<!-- xml文件中的转义字符
> > 大于
< < 小于
& & 和
如果sql中有大量的转义字符 建议使用转义标签体
语法: <![CDATA[xxx内容]]>
select * from demo_user where age > #{minAge} and age < #{maxAge}
-->
<select id="findByAge" resultType="com.jt.pojo.DemoUser">
<![CDATA[select * from demo_user where age > #{minAge} and age < #{maxAge}]]>
</select>
1.6 、mybatis集合list
@Test
public void testDeleteList(){
SqlSession sqlSession=sqlSessionFactory.openSession(true);
DemoUserMapper demoUserMapper=sqlSession.getMapper(DemoUserMapper.class);
List list=new ArrayList();
list.add(232);
list.add(233);
list.add(234);
demoUserMapper.deleteList(list);
System.out.println("删除成功!");
}
<!--List集合删除操作-->
<delete id="deleteList">
delete from demo_user where id in (
<foreach collection="list" item="id" separator=",">
#{id}
</foreach>)
</delete>
1.7 、mybatis集合map
@Test
public void testDeleteMap(){
SqlSession sqlSession=sqlSessionFactory.openSession(true);
DemoUserMapper demoUserMapper=sqlSession.getMapper(DemoUserMapper.class);
List list=new ArrayList();
list.add(232);
list.add(233);
list.add(234);
HashMap map=new HashMap();
map.put("ids", list);
demoUserMapper.deleteMap(map);
System.out.println("删除成功!");
}
<delete id="deleteMap">
delete from demo_user where id in (
<foreach collection="ids" item="id" separator=",">
#{id}
</foreach>)
</delete>
1.8 、小结
mybatis操作:
指定mybatis-config.xml的路径
读取指定的核心配置文件.
通过SelSessionFactoryBuilder.buid方法创建SqlSessionFactory.
获取SqlSession
获取Mapper的接口
从mapper接口文件中获取业务数据.
调用xml文件的Sql语句实现数据获取.
mybatis自动封装为对象返回 交给用户处理.
/*
*小结:
* 学习了个注解@beforeEach做了简化
* 抽取了生成SQLSessionFactory方法
* 利用mybatis查询数据时 如果返回结果确定唯一则使用pojo对象接受,如果不能确定就使用list集合接受
* mybatis默认支持单值传参,如果遇到多值需要将多值转化为单值
*
* 1.利用pojo对象封装
* 2.利用万能map集合
* 3.如果参数一定使用多值操作,那么就用使用@Param(“sex”)String sex进行封装
*
* #预编译效果 防止sql注入 为数据添加引号
* $没有预编译效果 可能会被sql注入 一般以字段名称为参数时使用
*
* 常规的curd操作
* mybatis原生条件下做更新操作时 需要手动提交事务
* 自动提交事务:SQLSessionFactory.openSession(true);
*
* xml中常用的转义字符
* $gt; > $lt; < %amp; $
* <![CDATA[xxx内容]]>
* */
<!-- 批量删除多个数据
如果使用#{集合}获取的是集合对象的整体 删除无效
将数组拆分为单个数据 可以通过遍历的方式操作
mybatis中为了参数取值方便 特意封装了遍历的标签foreach
参数说明:
<foreach collection=""></foreach>
如果传递的参数是数组,则collection="array"
如果传递的参数是list集合则collection="List"
如果传递的参数是map集合则collection="map中的key"
标签属性说明:
1.collection 集合的名称
2.item 每次遍历的数据的形参变量
3.open 循环的开始标签
4.close 循环的结束标签
5.index 循环遍历的下标 一般不用
6.separator 循环遍历的分割符
-->
2 、mybatis作业
测试类:
//1.查询age<100的女的
@Test
public void testZuoye1(){
SqlSession sqlSession=sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper=sqlSession.getMapper(DemoUserMapper.class);
Map<String,Object> map=new HashMap<>();
map.put("maxAge",100);
map.put("sex", "女");
List<DemoUser> userList=demoUserMapper.findZuoye1(map);
System.out.println(userList);
sqlSession.close();
}
//2.查询name中含有“精”的数据,并且按照年龄降序排列
@Test
public void testZuoye2() {
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
String name = "精";
List<DemoUser> list = demoUserMapper.findZuoye2(name);
System.out.println(list);
sqlSession.close();
}
//3.查询age在100-300中间的数据
@Test
public void testZuoye3(){
SqlSession sqlSession=sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper=sqlSession.getMapper(DemoUserMapper.class);
Map<String,Object> map=new HashMap<>();
map.put("minAge",100);
map.put("maxAge",300);
List<DemoUser> userList=demoUserMapper.findZuoye3(map);
System.out.println(userList);
sqlSession.close();
}
//4.将小乔 大桥 王昭君年龄改为18
@Test
public void testZuoye4(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
Map<String,Object> map = new HashMap<>();
String[] array = {"小乔","大乔","王昭君"};
map.put("names",array);
map.put("age",18);
map.put("sex","女");
demoUserMapper.findZuoye4(map);
sqlSession.close();
}
查询语句:
<select id="findZuoye1" resultType="com.jt.pojo.DemoUser">
<![CDATA[select * from demo_user where age < #{maxAge} and sex=#{sex}]]>
</select>
<select id="findZuoye2" resultType="com.jt.pojo.DemoUser">
<![CDATA[select * from demo_user where name like concat('%',#{name},'%') order by age DESC ]]>
</select>
<select id="findZuoye3" resultType="com.jt.pojo.DemoUser">
<![CDATA[select * from demo_user where age > #{minAge} and age < #{maxAge}]]>
</select>
<!-- 更改数据-->
<update id="findZuoye4">
update demo_user set age = #{age},sex = #{sex}
where name in (
<foreach collection="names" item="name" separator=",">
#{name}
</foreach>
)
</update>