mybatis注解基础使用
一、创建Maven项目
代码:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>wyf</groupId>
<artifactId>xqweb</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf8</encoding>
</configuration>
</plugin>
</plugins>
</build> </project>
创建好pom.xml,开始编码。
二、配置Mybatis
代码片段:mybatis.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>
<properties resource="config.properties">
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="haha.UserDao"/>
<mapper resource="user.xml"/>
</mappers>
</configuration>
代码:config.properties
username=root
password=haha
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai
把配置信息跟mybatis.xml分开的好处是:更清晰。mybatis属于代码区,config.properties改起来比较简单。
三、创建实体类User
User有三个属性:name,age和id,重写toString()方法便于调试。
package haha;
public class User {
String name;
Integer age;
Integer id;
public User(){}
public User(String name,int age){
this.name=name;
this.age=age;
}
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} @Override
public String toString() {
return String.format("(id:%d,name:%s,age:%d)", id, name, age);
}
}
四、实现UserDao接口
UserDao接口有两个功能:插入、查询全部。
package haha;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey; import java.util.List; public interface UserDao {
@Insert("insert into user(name,age) value(#{name},#{age})")
int insert_withoutPrimaryKey(@Param("name") String name, @Param("age") int age); int insert_useGeneratedKey(@Param("user") User user); int insert_selectKey(@Param("user") User user); @Insert("insert into user(name,age) value(#{user.name},#{user.age})")
@SelectKey(statement = "select last_insert_id()", keyProperty = "user.id", before = false, resultType = int.class)
int insert_selectKeyAnotation(@Param("user") User user); @Select("select*from user")
List<User> getAll();
}
Mybatis写SQL语句有两种方式:1、使用注解;2、使用xml
对于比较长的SQL语句放在xml中,对于比较短的SQL语句放在注解中
在上面定义的UserDao中,insert_userGeneratedKey()和insert_selectKey()两个函数没有给出对应的SQL语句,需要在xml文件中进行定义。
代码片段:user.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">
<mapper namespace="haha.UserDao">
<insert id="insert_useGeneratedKey" parameterType="haha.User"
useGeneratedKeys="true" keyProperty="user.id">
insert into user set id=#{user.id},name=#{user.name},age=#{user.age}
</insert>
<insert id="insert_selectKey" parameterType="haha.User">
<selectKey keyProperty="user.id" keyColumn="id" order="AFTER" resultType="int">
SELECT last_insert_id()
</selectKey>
insert into user(name,age) VALUE (#{user.name},#{user.age})
</insert>
</mapper>
五、测试
编写一个UserService类测试一下
package haha;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List; public class UserService { public static void main(String[] args) throws IOException {
String resource = "mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
SqlSession session = factory.openSession();
UserDao dao = session.getMapper(UserDao.class);
//使用默认主键
int affectedRows = dao.insert_withoutPrimaryKey("张三", 25);
System.out.println(affectedRows);
//使用useGeneratedKey,将主键注入到user.id中
User u = new User("张三", 17);
affectedRows = dao.insert_useGeneratedKey(u);
System.out.println(affectedRows + " " + u.getId());
//使用selectKey执行在插入之前或之后执行查询语句
affectedRows = dao.insert_selectKey(u);
System.out.println(affectedRows + " " + u.getId());
//使用selectKey注解的方式
affectedRows = dao.insert_selectKeyAnotation(u);
System.out.println(affectedRows + " " + u.getId());
session.commit();
List<User> a = dao.getAll();
a.forEach(System.out::println);
}
}
六、insert()函数返回值
如下代码,insert()函数的返回值为int类型,表示affectedRows,即受影响的行数,如果成功插入返回1,如果不成功插入,返回0。对于一切写操作(insert,update,delete),返回值都是affectedRows。
@Insert("insert into user(name,age) value(#{name},#{age})")
int insert(@Param("name") String name, @Param("age") int age);
七、关于@SelectKey
关于insert()有一种需求很常见:如何确定插入数据的主键。对于MySQL中的自增类型主键,无需提供主键可以直接插入。还是以insert()函数为例,这个SQL语句没有提供主键,主键是自增类型可以自动生成。
@Insert("insert into user(name,age) value(#{name},#{age})")
int insert(@Param("name") String name, @Param("age") int age);
下面介绍一个重要注解@SelctKey(statement="SQL语句",keyProperty="将SQL语句查询结果存放到keyProperty中去",before="true表示先查询再插入,false反之",resultType=int.class)
其中:
statement是要运行的SQL语句,它的返回值通过resultType来指定
before表示查询语句statement运行的时机
keyProperty表示查询结果赋值给代码中的哪个对象,keyColumn表示将查询结果赋值给数据库表中哪一列
keyProperty和keyColumn都不是必需的,有没有都可以
before=true,插入之前进行查询,可以将查询结果赋给keyProperty和keyColumn,赋给keyColumn相当于更改数据库
befaore=false,先插入,再查询,这时只能将结果赋给keyProperty
赋值给keyProperty用来“读”数据库,赋值给keyColumn用来写数据库
selectKey的两大作用:1、生成主键;2、获取刚刚插入数据的主键。
使用selectKey,并且使用MySQL的last_insert_id()函数时,before必为false,也就是说必须先插入然后执行last_insert_id()才能获得刚刚插入数据的ID。
注意:
该注解相当于XML配置中的<selectKey>
的标签
与注解@Insert
, @InsertProvider
, @Update
or @UpdateProvider
搭配使用。在其他方法上将被忽略。
如果你指定了一个@SelectKey
注解,然后Mybatis将忽略任何生成的key属性通过设置@Options
,或者配置属性。
属性: statement是要执行的sql语句的字符串数组, keyProperty是需要更新为新值的参数对象属性, before可以是true或者false分别代表sql语句应该在执行insert之前或者之后, resultType是keyProperty的Java类型, statementType是语句的类型,取Statement, PreparedStatement和CallableStatement对应的STATEMENT, PREPARED或者CALLABLE其中一个,默认是PREPARED。
1、举一个before=true的例子,新插入数据的id是当前表中行的个数
当before=true,可以通过SQL语句来填充insert语句中的某个参数,这个参数的名称可以通过keyProperty来指明。
@Insert("insert into user value(#{id},#{name},#{age})")
@SelectKey(statement="select count(1)from user", keyProperty="id", before=true, resultType=int.class)
int insert(@Param("name") String name, @Param("age") int age);
这个函数返回值是affectedRows,也就是插入成功返回1,插入失败返回0。
以上这段代码有一个大大的隐患,万万不能用在生产环境中。这个隐患就是:不能通过count()来确定id,多线程情况下有可能产生冲突。解决方案:可以使用UUID作为主键。
2、before=false的情况
注意keyProperty不能使基本类型,因为那样赋值之后就找不到了(相当于传值)
注解的方式
@Insert("insert into user(name,age) value(#{user.name},#{user.age})")
@SelectKey(statement = "select last_insert_id()", keyProperty = "user.id", before = false, resultType = int.class)
int insert_selectKeyAnotation(@Param("user") User user);
XML的方式
<insert id="insert_selectKey" parameterType="haha.User">
<selectKey keyProperty="user.id" keyColumn="id" order="AFTER" resultType="int">
SELECT last_insert_id()
</selectKey>
insert into user(name,age) VALUE (#{user.name},#{user.age})
</insert>
3、在Oracle中使用SelectKey生成主键,通常是“先查询得到主键,再进行插入”
DUAL表是Oracle中的神奇的表
使用序列作为主键
<insert id="insertSelective" parameterType="com.zehin.vpaas.base.domain.SfyHazardAnalysis">
<selectKey resultType="java.lang.Integer" order="BEFORE" keyProperty="hazardId">
SELECT SEQUENCE_1.NEXTVAL FROM DUAL
</selectKey>
insert into SFY_HAZARD_ANALYSIS
<trim prefix="(" suffix=")" suffixOverrides=",">
HAZARD_ID,
<if test="hazardTime != null"> HAZARD_TIME,</if>
<if test="hazardTitle != null"> HAZARD_TITLE, </if>
<if test="hazardMeasure != null"> HAZARD_MEASURE, </if>
<if test="buildId != null"> BUILD_ID, </if>
</trim>
<trim prefix=" values(" suffix=")" suffixOverrides=",">
#{hazardId,jdbcType=INTEGER},
<if test="hazardTime != null">#{hazardTime,jdbcType=VARCHAR},</if>
<if test="hazardTitle != null"> #{hazardTitle,jdbcType=VARCHAR}, </if>
<if test="hazardMeasure != null"> #{hazardMeasure,jdbcType=VARCHAR}, </if>
<if test="buildId != null"> #{buildId,jdbcType= INTEGER}, </if>
</trim>
lt;/insert>
使用GUID作为主键
<insert id="insertUser" parameterType="com.danny.mybatis.po.User">
<selectKey keyProperty="userId" order="BEFORE" resultType="java.lang.Integer">
select SYS_GUID() as userId from DUAL
</selectKey>
insert into T_USER(userId,userName,birthday,sex,address) values (#{userId},#{userName},#{birthday},#{sex},#{address}) </insert>
4、使用useGeneratedKeys
<insert id="insert" parameterType="Spares"
useGeneratedKeys="true" keyProperty="id">
insert into spares(spares_id,spares_name,
spares_type_id,spares_spec)
values(#{id},#{name},#{typeId},#{spec})
</insert>
<insert id="insertUser" useGeneratedKeys="true" keyColumn="id">
insert into user(name,age) VALUE (#{name},#{age})
</insert>
八、获取刚刚插入数据的主键
除了使用selectKey的方式获取刚刚插入数据的主键,还有以下方案:
1、如果是MySQL,可以用select last_insert_id()
语句获取新插入数据的主键。
2、如果主键类型是UUID,可以直接在代码中生成主键进行插入,这样就不需要从数据库中读取主键了,主动权掌握在代码手中。
mybatis注解基础使用的更多相关文章
- mybatis 注解快速上手
一.mybatis 简单注解 关键注解词 : @Insert : 插入sql , 和xml insert sql语法完全一样 @Select : 查询sql, 和xml select sql语法完全一 ...
- Mybatis注解的使用
一.mybatis 简单注解 关键注解词 : @Insert : 插入sql , 和xml insert sql语法完全一样 @Select : 查询sql, 和xml select sql语法完全一 ...
- Spring Boot 项目学习 (二) MySql + MyBatis 注解 + 分页控件 配置
0 引言 本文主要在Spring Boot 基础项目的基础上,添加 Mysql .MyBatis(注解方式)与 分页控件 的配置,用于协助完成数据库操作. 1 创建数据表 这个过程就暂时省略了. 2 ...
- 13.MyBatis注解式开发
mybatis 的注解,主要是用于替换映射文件.而映射文件中无非存放着增.删.改.查 的 SQL 映射标签.所以,mybatis 注解,就是要替换映射文件中的 SQL 标签. mybatis 官方文档 ...
- MyBatis从入门到精通(第3章):MyBatis注解方式的基本使用
MyBatis 注解方式就是将 SQL 语句直接写在DAO层的接口上. 在黑马录制的2018年双元视频课:\08 SSM整合案例[企业权限管理系统]\07.订单操作 有使用MyBatis注解进行多表 ...
- Mybatis高级:Mybatis注解开发单表操作,Mybatis注解开发多表操作,构建sql语句,综合案例学生管理系统使用接口注解方式优化
知识点梳理 课堂讲义 一.Mybatis注解开发单表操作 *** 1.1 MyBatis的常用注解 之前我们在Mapper映射文件中编写的sql语句已经各种配置,其实是比较麻烦的 而这几年来注解开发越 ...
- 【java框架】MyBatis(7)--MyBatis注解开发
1.MyBatis注解开发 1.1.Lombok的基本使用 Lombok是SpringBoot2.1.X版本与IDEA官方支持的一个插件,它是为简化POJO类中繁杂重复代码:geter/setter/ ...
- Mybatis注解开发(一对一)
其他代码访问:Mybatis注解开发基础操作 1.添加OrderMapper接口 public interface OrderMapper { // @Select("select *,o. ...
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...
随机推荐
- SQL表名,应该用表对应资源对象的复数形式还是单数形式
原文:http://blog.csdn.net/lizeyang 问题 SQL表名,应该用表对应资源对象的复数形式还是单数形式.例如一个用户表,表名是用user还是users更合适呢? 精华回答 ...
- 基于SILVACO ATLAS的a-IGZO薄膜晶体管二维器件仿真(06)
在知网看到了江南大学的硕士论文: 双有源层a-IGZO薄膜晶体管的特性仿真 IGZO/IZO双有源层薄膜晶体管特性的模拟研究 发现,我昨天的文章中参数的设置存在重大失误,如下材料定义语句中: mate ...
- 【Android】网络通信
https://www.bilibili.com/video/av78497129?p=4 本文为此视频笔记 1.一些标准设定 (读头部和内容) --->运行,出现权限警告: --->运行 ...
- 基于科大讯飞AIUI平台自定义语义库的开发
说明:我写这篇文章的主要目的是因为我在做这块的时候遇到过一些坑,也是希望后来者能少走一些弯路. 科大讯飞AIUI开放平台地址 科大讯飞AIUI开放平台后处理地址 AIUI后处理开放平台协议 1. 科大 ...
- iOS开发之通过Framework建立项目依赖
https://www.jianshu.com/p/d146db167bf3 项目开发时经常会遇到个别模块想打包成framework的情况,传统的打包方式太繁琐,反复测试时很麻烦,不如一个项目管理来得 ...
- 《Web安全攻防 渗透测试实战指南》 学习笔记 (四)
Web安全攻防 渗透测试实战指南 学习笔记 (四) Nmap Network Mapper 是一款开放源代码的网 ...
- easy flash &easy log
EASY FLASH: ENV 快速保存产品参数(k-v型no-sql数据库存储),支持 写平衡(磨损平衡) 及 掉电保护 功能 EasyFlash不仅能够实现对产品的 设定参数 或 运行日志 等信息 ...
- Linux中制作静态库
静态库生成: 1.第一步:生成.o文件 2.第二步:将所有.o文件打包 ar src libMyTest.a *.o 生成出libMyTest.a 3.使用: 第一种:gcc main.c ...
- [IDEA] Idea复制文件到项目一直updating indices的问题
通常我们在开发JavaWeb项目的时候,都需要先将网页写好,在进行复制到web目录下,如果里面包含了很多的资源文件,就会造成一直updating indices. 方法一: 这是因为项目需要对web目 ...
- 「JSOI2014」强连通图
「JSOI2014」强连通图 传送门 第一问很显然就是最大的强连通分量的大小. 对于第二问,我们先把原图进行缩点,得到 \(\text{DAG}\) 后,统计出入度为零的点的个数和出度为零的点的个数, ...