MyBatis初识
Mybaties-9.28
环境
- JDK 1.8
- Mysql 5.7
- maven 3.6.1
- IDEA
关键词
-
持久化就是数据在持久态和瞬时态转化的过程
-
POJO (Plain Ordinary Java Object)
-
iBatis
-
DAOS(Data Access Objects)
-
持久层
依赖配置
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
Start
下面步骤均以官网显示的推荐步骤进行,对于官网一些的一些部分加以说明
环境为mavaen环境
1.配置依赖
在Maven配置中配置
2.使用xml进行配置文件
mybatis-config.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="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<!--上面四项就是平时进行配置的driver,url,name,password,进行替换即可-->
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
<!--此项必须配置,路径为xml文件的位置,这里建议如果是maven项目,请将BlogMaaper.xml文件放在resources目录下-->
</mappers>
</configuration>
3.编写实体类
和数据库对应即可
public class User {
int id;
String name;
String pwd;
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
4.编写接口文件
接口文件的作用就是定义返回类型和具体方法名
public interface UserMapper {
/**
* 获取所有用户列表
* @return 用户列表
*/
List<User> getUserList();
}
5.创建MyBatis工具类
为了保证统一获取sqlSession
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory = null;
// 获取sqlSessionFactory对象
static {
InputStream inputStream = MyBatisUtils.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
// 这里因为放在了resources文件夹里面可以很方便的直接使用类加载器读取文件
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static SqlSession getSqlSession(){
// 从 SqlSessionFactory 中获取 SqlSession
// sqlSession 类似于 connection
return sqlSessionFactory.openSession();
}
}
6.编写Mapper文件指定sql语句及返回类型
<?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="day01.dao.UserMapper">
<!--namespace是接口-->
<select id="getUserList" resultType="day01.pojo.User">
<!--id指的是获取的方法,resultType指的是返回的结果是什么类-->
select * from rainful_mybatis.User
<!--这里编写sql语句-->
</select>
</mapper>
7.调用
这里使用junit调用
public class UserMapperTest {
public static void main(String[] args) {
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
// 使用try resource语法可以方便后期减少sqlSession.close()
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.getUserList();
System.out.println(list);
} catch (Exception e){
e.printStackTrace();
}
}
}
可能遇到的问题
- xml文件没有放在resources文件夹内放在了类的旁边导致maven进行打包的时候忽略了xml文件,此时需要在maven的pom文件里面增加下面这句话防止xml文件和properties文件被maven打包时忽略
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
- 因为没有修改2步骤里面的一些文件导致空指针异常等
CRUD
namespace
命名空间中的包名和 Dao/mapper 接口的包名一致
select
- id就是对应的namespace中的方法名
- returnType sql执行语句的返回值类型(如果是自定义类型就需要包名全称或者别名)
- parameterType 参数类型,同上
<select id="getUserById" parameterType="int" resultType="day01.pojo.User">
select *
from rainful_mybatis.User
where id = #{id}
# 直接使用 #{参数名} 可以获得参数
</select>
insert
<insert id="insertUser" parameterType="day01.pojo.User">
# 注意这个里 insert就是insert标签 select就是select标签
# 写错会导致报错,而且提交成功
insert into rainful_mybatis.User (id, name, pwd) value (#{id}, #{name}, #{pwd})
# 这里的参数可以直接取user里面的属性名
</insert>
update
<update id="updateUser" parameterType="day01.pojo.User">
update rainful_mybatis.User
set name = #{name},
pwd = #{pwd}
where id = #{id}
</update>
delete
<delete id="delUser" parameterType="int">
delete
from rainful_mybatis.User
where id = #{id}
</delete>
-
注意增删改需要提交事务
-
return null 是因为select和insert这种标签问题
-
mybatis配置文件里面的resource配置路径又应该是 / 分隔
使用Map替代实体类
好处在于当实体类参数过多的时候可以不用写不需要的参数
但是如果实体类有空参,set方法== ,是不是就不需要了
/**
* 插入一个新用户
* @param map 一个map里面只包含需要更改的字段
* @return 返回受影响的行数
*/
int insertUser2(Map<String, Object> map);
<insert id="insertUser2" parameterType="Map">
insert into rainful_mybatis.User (name, pwd) value (#{username}, #{password});
# 这里可以看到后面的参数类型可以是其他名称不需要和前面对象
# 但是需要和map里面的字段对应
</insert>
@Test
public void insertUser2(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<>();
map.put("username", "赵六");
map.put("password", "123456");
int row = mapper.insertUser2(map);
if (row > 0){
System.out.println("插入成功");
sqlSession.commit();
}
}
}
下面试一试空参构造使用set来
/**
* 插入一个新用户
* @param user 一个空参构造的User,只需要设置一些需要更改的字段
* @return 返回受影响的行数
*/
int insertUser3(User user);
<insert id="insertUser3" parameterType="day01.pojo.User">
insert into rainful_mybatis.User (name, pwd) value (#{name}, #{pwd})
</insert>
@Test
public void insertUser3(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setName("十全");
user.setPwd("123123123");
int row = mapper.insertUser3(user);
if (row > 0){
System.out.println("插入成功");
sqlSession.commit();
}
}
}
模糊查询
- 通过xml配置
<select id="getUserListByFuzzyQuery" parameterType="String" resultType="day01.pojo.User">
select *
from rainful_mybatis.User
where name like concat('%', #{value}, '%')
</select>
@Test
public void selectUser(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserListByFuzzyQuery("赵");
for (User user : userList) {
System.out.println("user = " + user);
}
}
}
-
或者直接在调用处"%赵%"
-
在sql里面使用 ’%${value}%‘ 的方式会触发sql注入问题
-
总结
- #{ }是预编译处理,MyBatis在处理#{ }时,它会将sql中的#{ }替换为?,然后调用PreparedStatement的set方法来赋值,传入字符串后,会在值两边加上单引号,使用占位符的方式提高效率,可以防止sql注入。
- ${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中,可能引发sql注入。
配置解析
核心配置文件
mybatis-config.xml
参数
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
环境配置
可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境
-
每个数据库对应一个 SqlSessionFactory 实例
-
如果需要指定非默认环境使用方法
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
-
如果忽略了环境参数将会加载默认环境
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
eg:
<environments default="development">
<!--这里配置默认的环境,还可以进行增加其他环境进行更换或者多个环境并存-->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://ip:port/数据库名s"/>
<property name="username" value="root"/>
<property name="password" value="xxxx"/>
<!--上面四项就是平时进行配置的driver,url,name,password,进行替换即可-->
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://ip:port/数据库名"/>
<property name="username" value="root"/>
<property name="password" value="xxxx"/>
</dataSource>
</environment>
</environments>
- 这里配置了一个test环境
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in, "test");
- sqlSession可以指定test环境进行
事务管理器
分为 JDBC | MANAGED
- JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
- MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。
如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器,因为 Spring 模块会使用自带的管理器来覆盖前面的配置。
数据源
有三种数据源类型 UNPOOLED | POOLED JNDI
UNPOOLED 每次请求后都会关闭,对于可用性要求不高的简单应用程序可以使用
- 仅需配置下面5项
driver
– 这是 JDBC 驱动的 Java 类全限定名(并不是 JDBC 驱动中可能包含的数据源类)。url
– 这是数据库的 JDBC URL 地址。username
– 登录数据库的用户名。password
– 登录数据库的密码。defaultTransactionIsolationLevel
– 默认的连接事务隔离级别。defaultNetworkTimeout
– 等待数据库操作完成的默认网络超时时间(单位:毫秒)。查看java.sql.Connection#setNetworkTimeout()
的 API 文档以获取更多信息。
POOLED 使用了连接池
- 增加配置
poolMaximumActiveConnections
– 在任意时间可存在的活动(正在使用)连接数量,默认值:10poolMaximumIdleConnections
– 任意时间可能存在的空闲连接数。poolMaximumCheckoutTime
– 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)poolTimeToWait
– 这是一个底层设置,如果获取连接花费了相当长的时间,连接池会打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直失败且不打印日志),默认值:20000 毫秒(即 20 秒)。poolMaximumLocalBadConnectionTolerance
– 这是一个关于坏连接容忍度的底层设置, 作用于每一个尝试从缓存池获取连接的线程。 如果这个线程获取到的是一个坏的连接,那么这个数据源允许这个线程尝试重新获取一个新的连接,但是这个重新尝试的次数不应该超过poolMaximumIdleConnections
与poolMaximumLocalBadConnectionTolerance
之和。 默认值:3(新增于 3.4.5)poolPingQuery
– 发送到数据库的侦测查询,用来检验连接是否正常工作并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动出错时返回恰当的错误消息。poolPingEnabled
– 是否启用侦测查询。若开启,需要设置poolPingQuery
属性为一个可执行的 SQL 语句(最好是一个速度非常快的 SQL 语句),默认值:false。poolPingConnectionsNotUsedFor
– 配置 poolPingQuery 的频率。可以被设置为和数据库连接超时时间一样,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。
JNDI 为了容器而实现的
属性
对于properties,可以在外面进行配置,并可以进行动态替换
在外部的db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://ip:port/数据库名
username=root
password=密码
<properties resource="db.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>
这里动态进行名称引用
甚至还可以在properties里面进行额外参数的设置
甚至还可以额外写最后在SqlSessionFactoryBuilder.build()方法里面进行传值
-
如果一个属性在多个地方进行了配置,那么mybatis将会按照下面的顺序进行加载
- 首先读取properties元素内部指定的值
- 然后根据properties元素中的resource属性读取属性文件的值,或根据 url 属性指定的路径读取属性文件,并覆盖前面的值
- 最后读取作为方法参数传递的属性,并覆盖之前的同名属性
-
可以配置默认值,但是需要额外配置
-
: 修改默认字符防止混乱
类型别名
为java类设置一个别名,防止完全限定类名的冗余
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
为一个包取别名
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
<!--里面所有的类默认以首字母小写为别名,如果有注解则为注解值-->
@Alias("author")
public class Author {
...
}
设置
设置名 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 |
true | false | false |
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |
其他
~
生命周期和作用域
SqlSessionFactoryBuilder
一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)
SqlSessionFactory
一旦被创建就应该在应用的运行期间一直存在,使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,最简单的就是使用单例模式或者静态单例模式。
SqlSession
SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。
解决属性名和字段名不一致的问题
1.起别名
没意思, pass
2.resultMap
简单级别
<resultMap id="UserMap" type="user">
<result column="pwd" property="password"/>
<!--column是数据库的列名, property是java类的属性-->
</resultMap>
<!--namespace是接口-->
<select id="getUserList" resultMap="UserMap">
<!--id指的是获取的方法,resultMap指的是使用那个id的resultMap-->
select * from rainful_mybatis.User
<!--这里编写sql语句-->
</select>
这里使用的是部分映射,将数据库的pwd字段映射给类的password字段
将所有的列映射到 HashMap
的键上,假如你的程序更可能会使用 JavaBean 或 POJO,MyBatis 会在幕后自动创建一个 ResultMap
,再根据属性名来映射列到 JavaBean 的属性上。如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名,也可以显示配置外部的resultMap,这也是解决列名不匹配的另外一种方式。
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
然后在引用它的语句中设置 resultMap
属性就行了(注意我们去掉了 resultType
属性)
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
高级级别
~
日志
日志工厂
- LOG4J(需要导包)
- STDOUT_LOGGING (掌握)
- 其他
- 如果报错classNotFound 一般是没导包,类名或者包名写错
Opening JDBC Connection
Created connection 1752203484.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@687080dc]
==> Preparing: select * from rainful_mybatis.User
==> Parameters:
<== Columns: id, name, pwd
<== Row: 1, 张三, 123456
<== Row: 2, 李四, 123457
<== Row: 3, 王五, 123458
<== Row: 4, 赵六, 123459
<== Row: 8, 王五, 1234356
<== Row: 9, 赵六, 123456
<== Row: 10, 十全, 123123123
<== Total: 7
User{id=1, name='张三', password='123456'}
User{id=2, name='李四', password='123457'}
User{id=3, name='王五', password='123458'}
User{id=4, name='赵六', password='123459'}
User{id=8, name='王五', password='1234356'}
User{id=9, name='赵六', password='123456'}
User{id=10, name='十全', password='123123123'}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@687080dc]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@687080dc]
Returned connection 1752203484 to pool.
Log4J
-
导入依赖
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
配置mybatis-config.xml
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
-
配置log4j.properties文件
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码 log4j.rootLogger=DEBUG,console,file #控制台输出的相关设置 log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.Threshold=DEBUG log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=[%c]-%m%n #文件输出的相关设置 log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.File=./log/kuang.log log4j.appender.file.MaxFileSize=10mb log4j.appender.file.Threshold=DEBUG log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n #日志输出级别 log4j.logger.org.mybatis=DEBUG log4j.logger.java.sql=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG
-
自己调用Log4J打印信息
public class UserMapperTest { private final Logger logger = Logger.getLogger(UserMapperTest.class); @Test public void testLog4j(){ logger.info("info:这是info级别信息"); logger.debug("debug:这是debug级别信息"); logger.error("error:这是error级别信息"); } }
分页
使用limit分页
接口
/**
* 用户列表分页
* @param map 参数列表
* @return 用户列表
*/
List<User> getUserByLimit(Map<String, Integer> map);
// 可以看到这里用的是map进行了参数的封装
// 如果不想使用map封装那么必须使用 (@Param("name") String name, @Param("pwd") String pwd) 这种方式显式声名参数
Mapper配置
<select id="getUserByLimit" resultMap="UserMap" parameterType="map">
select * from rainful_mybatis.User limit #{startIndex},#{pageSize}
</select>
测试
@Test
public void getUserByLimitTest(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Integer> map = new HashMap<String, Integer>(){{
put("startIndex", 0);
put("pageSize", 2);
}};
List<User> users = mapper.getUserByLimit(map);
for (User user : users) {
System.out.println("user = " + user);
}
}
}
RowBounds(了解)
这里不记录
分页插件
MyBatis 分页插件 PageHelper
使用注解开发
面向接口编程
根本原因:解耦,可拓展,提供复用,分层开发中,上层不用管下层的实现,大家遵守共同的标准,是的开发变得容易,提高规范性
理解
接口是从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离
接口本身反应了系统设计人员对系统的抽象理解
接口应有两类
对个体的抽象,对应一个抽象体(abstract class)
对某一方面的抽象,对应一个抽象面(interface)
三个面向区别
- 面向对象是指,考虑问题时,以对象为单位,考虑属性和方法
- 面向过程是指,考虑问题时,以一个具体流程问单位
- 接口设计与非接口设计是对于复用技术而言的,与面向对象(过程)不是一个问题,更多的体现对系统整体的架构
Start
对于简单的sql,可以直接在接口方法上面直接写
对于复杂的还是xml配置
接口方法配置
/**
* 使用注解获取数据库对象
* @return 用户列表
*/
@Select("select * from User")
List<User> getUserByAnnotation();
mybatis-config.xml配置
<mappers>
<mapper class="dao.UserMapper"/>
</mappers>
测试
@Test
public void getUserByAnnotation(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserByAnnotation();
for (User user : userList) {
System.out.println("user = " + user);
}
}
}
使用注解增删改查
查
接口配置
/**
* 根据用户名和密码查找用户
* @param name 用户名
* @param pwd 密码
* @return 返回一个User对象
*/
@Select("select * from User where name = #{name} and pwd = #{pwd}")
User getUserByAnnotation2(@Param("name") String name, @Param("pwd") String pwd);
xml配置
<mappers>
<mapper class="dao.UserMapper"/>
</mappers>
测试
@Test
public void getUserByAnnotation2(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserByAnnotation2("张三", "123456");
System.out.println("user = " + user);
}
}
在openSession(true)的话设置自动提交
但是建议不要用吧
增
接口配置
/**
* 插入一个新的User对象
* @param user 新的User对象
* @return 受影响的行数
*/
@Insert("insert into User (name, pwd) value (#{name}, #{pwd})")
int insertUser(User user);
// 注意此时注解的名字
xml配置同上
测试
@Test
public void insertUser(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int row = mapper.insertUser(new User(0, "十一", "123123435"));
if (row > 0){
System.out.println("插入成功");
sqlSession.commit();
}
}
}
改
接口配置
/**
* 更新用户
* @param user 新的用户对象
* @return 受影响的行数
*/
@Update("update User set pwd = #{pwd} where name = #{name}")
int updateUser(User user);
@Test
public void updateUser(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int row = mapper.updateUser(new User(0, "十一", "aaa"));
if (row > 0){
System.out.println("更新成功");
sqlSession.commit();
}
}
}
删
/**
* 根据id删除用户
* @param id id
* @return 受影响的行数
*/
@Delete("delete from User where id = #{id}")
int deleteUser(int id);
@Test
public void deleteUser(){
try(SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int row = mapper.deleteUser(11);
if (row > 0){
System.out.println("删除成功");
sqlSession.commit();
}
}
}
关于@Param()
- 基本类型的参数或者String类型需要加上这个
- 引用类型不需要加
- 如果只有一个基本类型也不需要,但是建议加上
- SQL中引用的就是 @Param() 中设定的属性名
#{} ${}
前面是预编译 后面是拼接sql