mybatis学习一:基于xml与注解配置入门实例与问题
注:本case参考自:http://www.cnblogs.com/ysocean/p/7277545.html
一:Mybatis的介绍:
- MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
- iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。
- MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
二:基于xml配置的入门实例与介绍(idea的maven项目):
1:case项目结构如图:(pom文件)
几点注意:
- 有可能idea下Maven项目会很卡,那么调整:Other Setting->default Setting->搜索maven->Runner中:VM Options设置为:-DarchetypeCatalog=internal;
- main目录下的java使我们自己建的,要将java->右键->Mark Directory as设置为root(否则底下不能建立包文件);
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:pom文件的模型版本
关于group id和artifact id,为了便于多人多模块协同开发管理(以后会讲),建议使用以下命名规范
group id:com.公司名.项目名
artifact id:功能模块名
packaging:项目打包的后缀,war是web项目发布用的,默认为jar
version: artifact模块的版本
name和url:相当于项目描述,可删除
group id + artifact id +version :项目在仓库中的坐标
-->
<modelVersion>4.0.0</modelVersion>
<groupId>com.company.project</groupId>
<artifactId>module</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>test Maven Webapp</name>
<url>http://maven.apache.org</url>
<!--上面这部分必须有--> <dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<!--<dependency>这里的jdbc的数据库连接jar总是报错,可以注释掉后从外部导入jar
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.7-bin</version>
</dependency>-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
2、创建数据库表:
1 create database spring_mybatis_test1;
2 use spring_mybatis_test1;
3 create table user(
4 id int(20) not null auto_increment,
5 username varchar(50) ,
6 sex varchar(10),
7 birthday date,
8 address varchar(100),
9 primary key(id)
10 );
向其中插入一条数据: insert into user(id,username,sex,birthday,address,) values(1,‘tom’,‘男’,'1993-05-25','earth');
补充:下面将要用到的配置参数:
①、parameterType:指定输入参数的类型
②、resultType:指定输出结果的类型,在select中如果查询结果是集合,那么也表示集合中每个元素的类型
③、#{}:表示占位符,用来接收输入参数,类型可以是简单类型,pojo,HashMap等等
如果接收简单类型,#{}可以写成 value 或者其他名称
如果接收 pojo 对象值,通过 OGNL 读取对象中的属性值,即属性.属性.属性...的方式获取属性值
④、${}:表示一个拼接符,会引起 sql 注入,不建议使用
用来接收输入参数,类型可以是简单类型,pojo,HashMap等等
如果接收简单类型,${}里面只能是 value
如果接收 pojo 对象值,通过 OGNL 读取对象中的属性值,即属性.属性.属性...的方式获取属性值
3:Mybatis的配置文件mybatis-configuration.xml:(事务,dataSource,userMapper.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标签,当mybatis和spring整合之后,这个标签是不用配置的 --> <!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境
一、development:开发模式
二、work:工作模式-->
<environments default="development">
<!--id属性必须和上面的default一样 -->
<environment id="development">
<!--事务管理器
一、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围
二、MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期
比如 spring 或 JEE 应用服务器的上下文,默认情况下,它会关闭连接。然而一些容器并不希望这样,
因此如果你需要从连接中停止它,就可以将 closeConnection 属性设置为 false,比如:
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
-->
<transactionManager type="JDBC"/>
<!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_mybatis_test1"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments> <mappers>
<!-- 注册userMapper.xml文件,
userMapper.xml位于com.ys.mapper这个包下,所以resource写成com/ys/mapper/userMapper.xml-->
<mapper resource="mapping/userMapping.xml"/>
</mappers>
</configuration>
4:实体类和映射文件userMapper.xml
- 实体类User:
1 package com.spring.model;
2
3 import java.util.Date;
4 public class User {
5 private int id;
6 private String username;
7 private String sex;
8 private Date birthday;
9 private String address;
10 public int getId() {
11 return id;
12 }
13 public void setId(int id) {
14 this.id = id;
15 }
16 public String getUsername() {
17 return username;
18 }
19 public void setUsername(String username) {
20 this.username = username;
21 }
22 public String getSex() {
23 return sex;
24 }
25 public void setSex(String sex) {
26 this.sex = sex;
27 }
28 public Date getBirthday() {
29 return birthday;
30 }
31 public void setBirthday(Date birthday) {
32 this.birthday = birthday;
33 }
34 public String getAddress() {
35 return address;
36 }
37 public void setAddress(String address) {
38 this.address = address;
39 }
40 @Override
41 public String toString() {
42 return "User [id=" + id + ", username=" + username + ", sex=" + sex
43 + ", birthday=" + birthday + ", address=" + address + "]";
44 }
45 } - 映射文件:注意36-49行的自增主键获取
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper namespace="user"><!--注意namespace的名称,测试文件中直接引用namespace-->
6
7 <!-- 根据 id 查询 user 表中的数据
8 id:唯一标识符,此文件中的id值不能重复
9 resultType:返回值类型,一条数据库记录也就对应实体类的一个对象
10 parameterType:参数类型,也就是查询条件的类型
11 -->
12 <select id="selectUserById"
13 resultType="com.spring.model.User" parameterType="int">
14 <!-- 这里和普通的sql 查询语句差不多,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着 -->
15 select * from user where id = #{id}
16 </select>
17
18 <!-- 查询 user 表的所有数据
19 注意:因为是查询所有数据,所以返回的应该是一个集合,这个集合里面每个元素都是User类型
20 -->
21 <select id="selectUserAll" resultType="com.spring.model.User">
22 select * from user
23 </select>
24
25 <!-- 模糊查询:根据 user 表的username字段
26 下面两种写法都可以,但是要注意
27 1、${value}里面必须要写value,不然会报错
28 2、${}表示拼接 sql 字符串,将接收到的参数不加任何修饰拼接在sql语句中
29 3、使用${}会造成 sql 注入
30 -->
31 <select id="selectLikeUserName" resultType="com.spring.model.User" parameterType="String">
32 select * from user where username like '%${value}%'
33 <!-- select * from user where username like #{username} -->
34 </select>
35
36 <!-- 向 user 表插入一条数据 -->
37 <insert id="insertUser" parameterType="com.spring.model.User">
38 <!-- 将插入的数据主键返回到 user 对象中
39 keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性
40 select LAST_INSERT_ID():查询上一次执行insert 操作返回的主键id值,只适用于自增主键
41 resultType:指定 select LAST_INSERT_ID() 的结果类型
42 order:AFTER,相对于 select LAST_INSERT_ID()操作的顺序
43 -->
44 <selectKey keyProperty="id" resultType="int" order="AFTER">
45 select LAST_INSERT_ID()
46 </selectKey>
47 insert into user(username,sex,birthday,address)
48 value(#{username},#{sex},#{birthday},#{address})
49 </insert>
50
51 <!-- 根据 id 更新 user 表的数据 -->
52 <update id="updateUserById" parameterType="com.spring.model.User">
53 update user set username=#{username} where id=#{id}
54 </update>
55
56 <!-- 根据 id 删除 user 表的数据 -->
57 <delete id="deleteUserById" parameterType="int">
58 delete from user where id=#{id}
59 </delete>
60 </mapper>
5:测试类:;
1 package com.ys.test;
2
3 import java.io.InputStream;
4 import java.util.List;
5
6 import org.apache.ibatis.session.SqlSession;
7 import org.apache.ibatis.session.SqlSessionFactory;
8 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
9 import org.junit.Before;
10 import org.junit.Test;
11
14 public class CRUDTest {
15 //定义 SqlSession
16 SqlSession session =null;
17
18 @Before
19 public void init(){
20 //定义mybatis全局配置文件
21 String resource = "mybatis-configuration.xml";
22 //加载 mybatis 全局配置文件
23 InputStream inputStream = CRUDTest.class.getClassLoader().getResourceAsStream(resource);
25 //构建sqlSession的工厂
26 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
27 //根据 sqlSessionFactory 产生 session
28 session = sessionFactory.openSession();
29 }
30
31 //根据id查询user表数据
32 @Test
33 public void testSelectUserById(){
34 /*这个字符串由 userMapper.xml 文件中 两个部分构成
35 <mapper namespace="user"> 的 namespace 的值
36 <select id="selectUserById" > id 值*/
37 String statement = "user.selectUserById";
38 User user = session.selectOne(statement, 1);
39 System.out.println(user);
40 session.close();
41 }
42
43 //查询所有user表所有数据
44 @Test
45 public void testSelectUserAll(){
46 String statement = "user.selectUserAll";
47 List<User> listUser = session.selectList(statement);
48 for(User user : listUser){
49 System.out.println(user);
50 }
51 session.close();
52 }
53
54 //模糊查询:根据 user 表的username字段
55 @Test
56 public void testSelectLikeUserName(){
57 String statement = "user.selectLikeUserName";
58 List<User> listUser = session.selectList(statement, "%t%");
59 for(User user : listUser){
60 System.out.println(user);
61 }
62 session.close();
63
64 }
65 //向 user 表中插入一条数据
66 @Test
67 public void testInsertUser(){
68 String statement = "user.insertUser";
69 User user = new User();
70 user.setUsername("Bob");
71 user.setSex("女");
72 session.insert(statement, user);
73 //提交插入的数据
74 session.commit();
75 session.close();
76 }
77
78 //根据 id 更新 user 表的数据
79 @Test
80 public void testUpdateUserById(){
81 String statement = "user.updateUserById";
82 //如果设置的 id不存在,那么数据库没有数据更改
83 User user = new User();
84 user.setId(4);
85 user.setUsername("jim");
86 session.update(statement, user);
87 session.commit();
88 session.close();
89 }
91
92 //根据 id 删除 user 表的数据
93 @Test
94 public void testDeleteUserById(){
95 String statement = "user.deleteUserById";
96 session.delete(statement,4);
97 session.commit();
98 session.close();
99 }
100 }
结果:以下我只测试了testSelectUserById和testSelectLikeUserName,两个是一样的: User [id=1, username=tom, sex=男, birthday=Tue May 25 00:00:00 CST 1993, address=earth] 。
6:获取主键值:
- 数据库有自增主键:映射配置中的36-49行
1 <!-- 向 user 表插入一条数据 -->
2 <insert id="insertUser" parameterType="com.ys.po.User">
3 <!-- 将插入的数据主键返回到 user 对象中
4 keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性
5 select LAST_INSERT_ID():查询上一次执行insert 操作返回的主键id值,只适用于自增主键
6 resultType:指定 select LAST_INSERT_ID() 的结果类型
7 order:AFTER,相对于 select LAST_INSERT_ID()操作的顺序
8 -->
9 <selectKey keyProperty="id" resultType="int" order="AFTER">
10 select LAST_INSERT_ID()
11 </selectKey>
12 insert into user(username,sex,birthday,address)
13 value(#{username},#{sex},#{birthday},#{address})
14 </insert> - 非自增主键:
1 <!-- 向 user 表插入一条数据 -->
2 <insert id="insertUser" parameterType="com.ys.po.User">
3 <!-- 将插入的数据主键返回到 user 对象中
4 流程是:首先通过 select UUID()得到主键值,然后设置到 user 对象的id中,在进行 insert 操作
5 keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性
6 select UUID():得到主键的id值,注意这里是字符串
7 resultType:指定 select UUID() 的结果类型
8 order:BEFORE,相对于 select UUID()操作的顺序
9 -->
10 <selectKey keyProperty="id" resultType="String" order="BEFORE">
11 select UUID()
12 </selectKey>
13 insert into user(id,username,sex,birthday,address)
14 value(#{id},#{username},#{sex},#{birthday},#{address})
15 </insert>
三:基于注解配置的入门实例与介绍(idea的maven项目):
1:我们直接在上面的case中配置注解方式,整个目录结构如下:
需要改动的地方包括以上三个部分:
2:不需要动的部分
- pom.xml不需要改动;
- User实体bean不需要改动;
- userMapping.xml弃用
3、定义操作user表的注解接口UserMapper.java(接口)
1 package com.spring.model;
2
3 import org.apache.ibatis.annotations.Delete;
4 import org.apache.ibatis.annotations.Insert;
5 import org.apache.ibatis.annotations.Select;
6 import org.apache.ibatis.annotations.Update;
7
8 public interface UserMapper {
9
10 //根据 id 查询 user 表数据
11 @Select("select * from user where id=#{id}")
12 public User selectUserById(int id) throws Exception;
13
14 //箱user插入一条数据
15 @Insert("insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})")
16 public void insertUser(User user) throws Exception;
17
18 //根据 id 修改 user 表数据
19 @Update("update user set username=#{username},sex=#{sex} where id=#{id}")
20 public void updateUserById(User user) throws Exception;
21
22 //根据 id 删除 user 表数据
23 @Delete("delete from user where id=#{id}")
24 public void deleteUserById(int id) throws Exception;
25 }
4、mybatis-configuration.xml中注册映射接口UserMapper.java
1 ......
2 <mappers>
3 <!-- xml方式,注册userMapper.xml文件,
4 userMapper.xml位于com.ys.mapper这个包下,所以resource写成com/ys/mapper/userMapper.xml
5 <mapper resource="mapping/userMapping.xml"/>-->
6 <mapper class="com.spring.model.UserMapper"></mapper>
7 </mappers>
5、创建测试类
1 package com.spring;
2
3 import com.spring.CRUDTest;
4 import com.spring.model.User;
5 import com.spring.model.UserMapper;
6 import org.apache.ibatis.session.SqlSession;
7 import org.apache.ibatis.session.SqlSessionFactory;
8 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
9 import org.junit.Before;
10 import org.junit.Test;
11
12 import java.io.InputStream;
13
14 public class TestAnnotationCRUD {
15 SqlSession session=null;
16
17 @Before
18 public void init(){
19 //定义mybatis全局配置文件
20 String resource = "mybatis-configuration.xml";
21 //加载 mybatis 全局配置文件
22 InputStream inputStream = CRUDTest.class.getClassLoader().getResourceAsStream(resource);
23 //构建sqlSession的工厂
24 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
25 //根据 sqlSessionFactory 产生 session
26 session = sessionFactory.openSession();
27 }
28
29 //注解的增删改查方法测试
30 @Test
31 public void testAnncationCRUD() throws Exception {
32 //根据session获取 UserMapper接口
33 UserMapper userMapper = session.getMapper(UserMapper.class);
34 //调用selectUserById()方法
35 User user = userMapper.selectUserById(1);
36 System.out.println(user);
37
38 //调用 insertUser() 方法
39 User user1 = new User();
40 user1.setUsername("aliks");
41 user1.setSex("不详");
42 userMapper.insertUser(user1);
43
44 //调用 updateUserById() 方法
45 User user2 = new User();
46 user2.setId(6);
47 user2.setUsername("lbj");
48 userMapper.updateUserById(user2);
49
50 //调用 () 方法
51 userMapper.deleteUserById(6);
52
53 session.commit();
54 session.close();
55 }
56
57 }
idea输出: User [id=1, username=tom, sex=男, birthday=Tue May 25 00:00:00 CST 1993, address=earth]
数据库结果:
注解配置使我们放弃了映射文件mapping.xml,需要接口实现数据库操作与到方法间的映射
mybatis学习一:基于xml与注解配置入门实例与问题的更多相关文章
- 01Spring基于xml的IOC配置--入门
01Spring基于xml的IOC配置 1.创建一个普通的maven工程 1.1 选择maven,不用骨架,点击下一步. 1.2 填写GroupId.ArtifactId.Version.填完点击下一 ...
- MyBatis 使用简单的 XML或注解用于配置和原始映射
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .My ...
- spring 基于XML和注解的两种事务配置方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- MyBatis 项目开发中是基于 XML 还是注解?
只要你对 MyBatis 有所认识和了解,想必知道 MyBatis 有两种 SQL 语句映射模式,一种是基于注解,一种是基于XML. 基于 XML <mapper namespace=" ...
- Spring 框架的概述以及Spring中基于XML的IOC配置
Spring 框架的概述以及Spring中基于XML的IOC配置 一.简介 Spring的两大核心:IOC(DI)与AOP,IOC是反转控制,DI依赖注入 特点:轻量级.依赖注入.面向切面编程.容器. ...
- spring的AspectJ基于XML和注解(前置、后置、环绕、抛出异常、最终通知)
1.概念 (1)AspectJ是一个基于Java语言的AOP框架 (2)Spring2.0以后新增了对AspectJ切入点表达式的支持 (3)AspectJ是AspectJ1.5的新增功能,通过JDK ...
- 基于XML的AOP配置
创建spring的配置文件并导入约束 此处要导入aop的约束 <?xml version="1.0" encoding="UTF-8"?> < ...
- Spring中AOP的基于xml开发和配置
pom文件: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http ...
- mybatis学习笔记(二)-- 使用mybatisUtil工具类体验基于xml和注解实现
项目结构 基础入门可参考:mybatis学习笔记(一)-- 简单入门(附测试Demo详细过程) 开始体验 1.新建项目,新建类MybatisUtil.java,路径:src/util/Mybatis ...
随机推荐
- GAN实战笔记——第三章第一个GAN模型:生成手写数字
第一个GAN模型-生成手写数字 一.GAN的基础:对抗训练 形式上,生成器和判别器由可微函数表示如神经网络,他们都有自己的代价函数.这两个网络是利用判别器的损失记性反向传播训练.判别器努力使真实样本输 ...
- The POM for com.alibaba:druid:jar:1.2.6 is invalid, transitive dependencies (if any) will not be available
开发环境 IDEA2020.3, jdk1.8.0_231 问题描述 开发中引入了druid-spring-boot-starter最新版本1.2.6,项目install时的时候一直出现警告 The ...
- 零基础自学Python十天的时候,写的一款猜数字小游戏,附源码和软件下载链接!
自学一门语言最重要的是要及时给自己反馈,那么经常写一些小程序培养语感很重要,写完可以总结一下程序中运用到了哪些零散的知识点. 本程序中运用到的知识点有: 1.输入输出函数 (input.print) ...
- Springboot整合kaptcha验证码
01.通过配置类来配置kaptcha 01-01.添加kaptcha的依赖: <!-- kaptcha验证码 --> <dependency> <groupId>c ...
- 【Java8新特性】Optional类在处理空值判断场景的应用 回避空指针异常 编写健壮的应用程序
一.序言 空值异常是应用运行时常见的异常,传统方式为了编写健壮的应用,常常使用多层嵌套逻辑判断回避空指针异常.Java8新特性之Optional为此类问题提供了优雅的解决方式. 广大程序员朋友对空值异 ...
- jmeter变量嵌套:__V
问题复现 ${name_${n}} 下面没有获取到结果 解决方案 __V是用于执行变量名表达式 ${__V(name_${n})} 获取到结果
- 带你玩转CompletableFuture异步编程
前言 最近在忙生活的第一个OKR,这个等等后面具体聊聊,今天开始恢复每周一篇原创,感谢小伙伴的不离不弃.这篇文章也是最近在Code Review的时候,看到的大家代码,想整体推下大家异步编程的思想,由 ...
- 思迈特软件Smartbi:专注BI,把产品打造到极致
在企业服务领域,现在的BI(商业智能)无疑是妥妥的风口.不过在20多年前,BI却完全是一幅门庭冷清宾客稀的光景--小型企业高攀不起,大型企业爱答不理. 一些管理者们理所当然地认为,商业是人脑的高阶竞争 ...
- HMS Core挑战赛故事:鞋、街景、手办、玩具,原来这些都可以3D建模
HMS Core线上Codelabs挑战赛第3期中,开发者通过学习和运用HMS Core开发的3D建模服务,生成3D建模应用demo,再使用demo为自己身边的一个实物完成建模.在提交的作品中,小编发 ...
- 查询性能提升3倍!Apache Hudi 查询优化了解下?
从 Hudi 0.10.0版本开始,我们很高兴推出在数据库领域中称为 Z-Order 和 Hilbert 空间填充曲线的高级数据布局优化技术的支持. 1. 背景 Amazon EMR 团队最近发表了一 ...