文章目录
Mybatis基本使用
- 通过简单的xml或注解来配置映射java对象到数据库中的记录
- 它支持自定义sql,存储过程以及高级映射
使用的一般流程
- 添加依赖包
- 创建mybatis-config.xml 全局的配置⽂文件
- 创建XXXMapper.xml配置⽂文件
- 创建SqlSessionFactory
- 用SqlSessionFactory创建SqlSession对象
- 用SqlSession执行增删改查CRUD
-
添加依赖包
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.19</version> </dependency>
-
配置xml文件
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/xdclass? useUnicode=true&characterEncoding=utf-8&useSSL=false"/> <property name="username" value="root"/> <property name="password" value="liyan"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mapper/VideoMapper.xml"/> </mappers> </configuration>
其中的<mappers> </mapper>可以包含多个mapper
配置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"> <!-- namespace: 名称空间, 一般需要保持全局唯一,和dao层的java接口一致 可以映射sql语句 到对应的方法名称和参数,返回类型 mybatis 是使用接口动态代理 --> <mapper namespace="net.xdclass.xd_class.dao.VideoMapper" > <!-- statement sql 语句 id 当前mappper下需要唯一 resultType sql查询结果集的封装 --> <select id="selectById" resultType="net.xdclass.xd_class.domain.Video"> select * from video where id = #{video_id} </select> </mapper>
namespace的作用有两个: 一个是利用更长的全限定名来将不同的语句隔离开来,同时也实现了你上面见到的接口绑定。
其中的<select> <select> 所包裹的 id要和我们的方法名一致 resultType要和我们这个接口所处的java包下的地址一致
#{video_id} 就是取参数的值 @Param() 是给参数取别名 我们然后取值的时候用别名就好了,若是没有使用别名,我们就是直接使用videoId就好了
public interface VideoMapper { /** * 根据视频id查找视频对象 * */ Video selectById(@Param("video_id") int videoId); /** * 查找所用的video对象 * */ @Select("select * from video") Video selectAllVideo(); }
-
构建SqlSessionFactory 来获取最终的执行结果
public class SqlSessionDemo { public static void main(String[] args) throws IOException { String resouces = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resouces); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 用 try 包裹 try中的语句执行完毕之后 ,sqlSession就会自动关闭 // 类似于 SqlSession sqlSession = sqlSessionFactory.openSession(); // sqlSession.close(); try ( SqlSession sqlSession = sqlSessionFactory.openSession() ){ VideoMapper videoMapper = sqlSession.getMapper(VideoMapper.class); Video video = videoMapper.selectById(1); } System.out.println(video); } }
-
我们在执行sql语句的时最好使用别名。多个参数的时候一定要使用别名。
驼峰映射成下划线
-
Mybatis连接数据库,数据库中的表和我们所创建的类是自动映射的
-
我们在数据库中所配置的表中的字段一般是有下划线名称的
-
而在我们类中的属性一般都是驼峰名称
-
为了可以在我们查询的时候 可以 自动映射我们 可以给Mybatis配置类(mybatis-config.xml)加上一个配置
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
-
这个 配置一定要按Mybatis定义的顺序加到里面,不然会报错
-
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>
-
JDBCTYPE
-
当我们出现 无效的列类型报错的时候,就是我们缺少了jdbcType,我们java中的类型参数无法映射到数据库中的类型参数
-
只需要在sql语句中加入他的jdbcType
select * from video where id = #{video_id, jdbcType="INTEGER"}
-
对应的匹配
JDBC Type Java Type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIMAL java.math.BigDecimal BIT boolean BOOLEAN boolean TINYINT byte SMALLINT short INTEGER INTEGER INTEGER int BIGINT long REAL float FLOAT double DOUBLE double BINARY byte[] VARBINARY byte[] LONGVARBINARY byte[] DATE java.sql.Date TIME java.sql.Time TIMESTAMP java.sql.Timestamp CLOB Clob BLOB Blob ARRAY Array DISTINCT mapping of underlying type STRUCT Struct REF Ref DATALINK java.net.URL
模糊查询
-
我们在web端开发的时候使用模糊查询的方法
-
- Sting sql = "select * from video where title like ?"; - ······ - ps.setString(1, "%教%")
而在Mybatis中使用的模糊查询一般就是 concat 关键字尤为重要
-
<select id="selectByPointAndTitleLike" resultType="net.xdclass.xd_class.domain.Video"> select * from video where point=#{point,jdbcType=INTEGER} and title like concat('%', #{title,jdbcType=VARCHAR}, '%') </select>
-
/** * 模糊查询 * */ ArrayList<Video> selectByPointAndTitleLike (@Param("point") double point,@Param("title") String title);
-
插入数据,以及获取当前插入数据的主键
-
我们sql语句中的查询(select)语句 ,获取的是最终输出结果集,所以配置的一般都是 resultType。
-
而插入语句要获取对象集,才可以将数据插入到数据库中,所以要使用 parameterType。
-
当我们插入一行数据的时候,Mybaits具有自动映射的功能,其中values后面括号中的字段名一点是Java类中的字段名。而insert into 后跟的则是数据库中的字段名。
-
我们添加三个参数可以让插入语句执行完之后,然后让我们创建的对象自获得自增主键
-
useGeneratedKeys="true" keyProperty="id" keyColumn="id"
执行流程如下
-
先在接口中创建方法
/** * 插入 * */ void add(Video video);
-
配置xml文件
- 这里的id 和 我们的方法名一致
<insert id="add" parameterType="net.xdclass.xd_class.domain.Video" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> INSERT INTO `video` ( `title`, `summary`, `cover_img`, `price`, `create_time`, `point`) VALUES (#{title,jdbcType=VARCHAR},#{summary,jdbcType=VARCHAR}, #{coverImg,jdbcType=VARCHAR},#{price,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP},#{point,jdbcType=DOUBLE}); </insert>
-
然后构建sqlSessionFactory来执行方法
public static void main(String[] args) throws IOException { String resouces = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resouces); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 用 try 包裹 try中的语句执行完毕之后 ,就会自动关闭 SqlSession sqlSession = sqlSessionFactory.openSession(); VideoMapper videoMapper = sqlSession.getMapper(VideoMapper.class); /* ArrayList<Video> list = videoMapper.selectByPointAndTitleLike(8.9, "教"); Video video = videoMapper.selectById(40);*/ Video video = new Video(); video.setTitle("xxxxxxxxxxx"); video.setCoverImg("yyyyyyyyyyy"); video.setPoint(9.4); video.setCreateTime(new Date()); video.setPrice(9900); video.setSummary("1234"); int rows = videoMapper.add(video); System.out.println(video); sqlSession.close(); }
而打印出来的结果也符合我们的预期,自动获取了主键
Video{id=48, title='xxxxxxxxxxx', summary='1234', coverImg='yyyyyyyyyyy', price=9900, createTime=Sat Jan 02 20:54:49 CST 2021, point=9.4}
-
批量插入数据 利用foreach
-
foreach : 用于我们循环拼接的内置标签 里面包含了多种属性
- collection : 值为迭代循环的集合类型
- item:每一个元素迭代时候的别名
- index: 索引的属性名,在集合数组情况下的值为当前索引值,当迭代对象为map的时候这个值是map的key
- open:循环开头的字符串
- close:整个循环的结束字符串
- separtor:每次循环的分割符
-
<!-- 其中java类中字段的引用 需要加上item所配置的的名字 --> <!-- 而 separator 其实就是每一次循环执行完的分隔符--> <!-- collecttion 就是我们批量插入的时候 所引入的数据结构,一般为map和list--> <insert id="addBatch" parameterType="net.xdclass.xd_class.domain.Video" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> INSERT INTO video (title, summary) values <foreach collection="list" item="video" separator=","> (#{video.title, jdbcType=VARCHAR}, #{video.summary, jdbcType=VARCHAR}) </foreach> </insert>
配置完成之后
我们添加接口和使用方法去执行
/** * 批量插入 * */ int addBatch(List<Video> list); Video video = new Video(); video.setTitle("xxxxxxxxxxx"); video.setCoverImg("yyyyyyyyyyy"); Video video1 = new Video(); video.setTitle("1233123"); video.setSummary("99999"); List<Video> list = new ArrayList<Video>(); list.add(video); list.add(video1); int rows = videoMapper.addBatch(list); System.out.println(list);
类似于
insert into video(title, summary) values ("xxxxxxxxxxx","yyyyyyyyyyy"),("1233123","99999");
update语句 以及如何进行动态更新
-
基本更新语法其实其实和我们web中学的JDBC的语法相差不大。
-
但是在我们引入的时候,我们可以去这个字段是否需要去更新
-
就相当于加入一个判断语句 若是<if test=“语句”> </test>中的语句成立就不去更新
<update id="updateVideo" parameterType="net.xdclass.xd_class.domain.Video"> update video set <if test="title != null"> title = #{title, jdbcType=VARCHAR},</if> <if test="summary != null"> summary = #{summary, jdbcType=VARCHAR},</if> <if test="coverImg != null"> cover_img = #{coverImg, jdbcType=VARCHAR},</if> <if test="price != 0"> price = #{price, jdbcType=INTEGER},</if> <if test="createTime != null"> create_time = #{createTime, jdbcType=VARCHAR},</if> <if test="point != 0"> point = #{point, jdbcType=DOUBLE}</if> where id = #{id, jdbcType=INTEGER} </update>
<if test></test> 中的字段一定是和java类中的字段是相同的。
若是基本数据类型不可以用 != null 去判断的,基本数据类型本身就是不为null的。而这个时候我们可以去选择使用包装类 或者根据我们所需的业务去判空。
-
也可以引入<trim> </trim> 语句
- prefix 的意义就是在前面加一个set字段
- suffixOverrides 的意思就是去除这一段语句最后面的 “,”
下面的代码和上面的本质上是一致的
<update id="updateVideo" parameterType="net.xdclass.xd_class.domain.Video"> update video <trim prefix="set" suffixOverrides=","> <if test="title != null"> title = #{title, jdbcType=VARCHAR},</if> <if test="summary != null"> summary = #{summary, jdbcType=VARCHAR},</if> <if test="coverImg != null"> cover_img = #{coverImg, jdbcType=VARCHAR},</if> <if test="price != 0"> price = #{price, jdbcType=INTEGER},</if> <if test="createTime != null"> create_time = #{createTime, jdbcType=VARCHAR},</if> <if test="point != 0"> point = #{point, jdbcType=DOUBLE},</if> </trim> where id = #{id, jdbcType=INTEGER} </update>
-
我们然后可以构建sqlSessionFactory和接口去执行sql语句了
delete 语句 以及 大于符号">" 和小于符号”<“ 如何转义
-
其实delete 语句和我们上面介绍的也是一样的。
-
但是在MyBatis中使用xml配置文件来进行sql语句的书写,其中的大于小于符号和xml中的<> 冲突了
-
我们将大于符号或者小于符号这样包裹一下然后进行使用
大于等于 <![CDATA[ >= ]]> 小于等于 <![CDATA[ <= ]]>
-
删除价格小于等于30的video
<delete id="deleteVideo" parameterType="net.xdclass.xd_class.domain.Video"> delete from video where price <![CDATA[ <= ]] 30 </delete>
-
其他步骤和上面一致 (配置id一致接口方法,配置sqlSessionFactory模式然后去调用这个接口方法)