mybatis入门(二):增删改查
mybatis的原理:
1.mybatis是一个持久层框架,是apache下的顶级项目
mybatis托管到googlecode下,目前托管到了github下面
2.mybatis可以将向prepareStatement中输入的参数自动进行输入映射,将查询结果集灵活的映射成java对象。(输出映射)
mybatis的一般使用到的maven包:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.42</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.4</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency>
其中
流程:
1.新建log4j.properties
2.新建sqlMapConfig.xml(名称可以替换,用来配置事务,数据库连接等等)(约束文件是config.dtd)
3.新建映射文件
映射文件命名:
User.xml(原始ibatis命名),mapper代理开发映射文件名称为xxxMapper.xml,比如:UserMapper.xml、ItemsMapper.xml
新建原始的User.xml(约束文件是mapper.dtd结尾)
4.创建一个pojo类
User.java:创建的理由是要和数据库里面的数据要保持一致,这样就可以把mybatis里面返回的结果直接映射为一个java对象
5.在sqlMapConfig.xml加载映射文件
6.建立mybatis的查询语句
1.新添加一个log4j.properties
1 ### set log levels ### 2 #在开发环境下日志的级别设置为DEBUG,生产环境设置成为info或error 3 log4j.rootLogger = INFO , console , debug , error 4 5 ### console ### 6 log4j.appender.console = org.apache.log4j.ConsoleAppender 7 log4j.appender.console.Target = System.out 8 log4j.appender.console.layout = org.apache.log4j.PatternLayout 9 log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] %m%n
2.新建sqlMapConfig.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <!-- 环境:配置mybatis的环境 --> 7 <environments default="development"> 8 <!-- 环境变量:可以配置多个环境变量,比如使用多数据源时,就需要配置多个环境变量 --> 9 <environment id="development"> 10 <!-- 事务管理器 --> 11 <transactionManager type="JDBC"/> 12 <!-- 数据源 --> 13 <dataSource type="POOLED"> 14 <property name="driver" value="com.mysql.jdbc.Driver"/> 15 <property name="url" value="jdbc:mysql://localhost:3306/mybatisData?characterEncoding=utf-8"/> 16 <property name="username" value="root"/> 17 <property name="password" value="root"/> 18 </dataSource> 19 </environment> 20 </environments> 21 <!-- 加载映射文件--> 22 <mappers> 23 <mapper resource="sqlMap/User.xml"/> 24 </mappers> 25 </configuration>
3.新建映射文件
User.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.apache.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离--> 6 <!--注意:使用mapper代理方法开发,namespace有特殊重要的作用--> 7 <mapper namespace="test"> 8 <!-- 在映射文件中配置很多sql语句--> 9 <!--通过select执行数据库查询 10 id:标识映射文件中的sql 11 将sql语句封装到mappedStatement对象中,所以id称为statement的id 12 parameterType:指定参数类型,这里指定int型 13 #{id}标识一个占位符,其中i表示接收输入的参数,如果输入的参数是简单类型,#{}D的参数可以任意,可以是value或其他名称 14 resultType:指定sql输出结果的所映射的java的对象类型,select指定resultType表示将单条记录所映射单条记录 15 --> 16 <select id="findUserById" parameterType="int" resultType="cn.wj.test.mybatis.pojo.User"> 17 select * from user where id = #{id} 18 </select> 19 20 <!-- 21 根据用户名称模糊查询用户信息,可能返回多条 22 resultType:指定的是单条记录所映射的java对象类型 23 ${}:标识拼接字符串,将接收到参数的内容不加任何修饰拼接在sql中(不是占位符) 24 使用${}拼接sql,可能会引起sql注入 25 ${value}:接收输入参数的内容,如果传入的参数是简单类型,${}中只能使用value 26 --> 27 <select id="findUserByName" parameterType="String" resultType="cn.wj.test.mybatis.pojo.User"> 28 select * from user where username like '%${value}%' 29 </select> 30 31 <!--添加用户 32 parameterType:指定输入参数类型是pojo(包括用户信息) 33 #{}中指定的pojo的属性名,接收到pojo对象的属性值,mybatis通过ognl获取对象的属性值 34 --> 35 <insert id="insertUser" parameterType="cn.wj.test.mybatis.pojo.User"> 36 <!-- 37 将插入的数据的主键返回,返回到user对象中 38 SELECT LAST_INSERT_TD():得到刚insert进去记录的主键值,只适用于自增主键 39 40 keyProperty:将查询到主键值设置到parameterType指定的对象的那个属性 41 order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句他的执行顺序 42 resultType:指定SELECT LAST_INSERT_ID()的结果类型 43 --> 44 <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> 45 SELECT LAST_INSERT_ID() 46 </selectKey> 47 insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address}) 48 </insert> 49 50 <insert id="insertUserUUID" parameterType="cn.wj.test.mybatis.pojo.UserUUID"> 51 <!-- 52 使用mysql的uuid生成主键 53 执行过程: 54 首先通过uuid()的到主键,将主键设置到user对象的id属性中 55 其次在insert执行过程时,从user对象取出id属性 56 --> 57 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> 58 SELECT uuid() 59 </selectKey> 60 insert into useruuid(id,name) value(#{id},#{name}) 61 </insert> 62 63 <!-- 64 删除用户 65 根据id删除用户,需要输入id值 66 --> 67 <delete id="deleteUserById" parameterType="java.lang.Integer"> 68 delete from user where id = #{id} 69 </delete> 70 71 <!-- 72 根据用户id更新用户 73 分析: 74 需要传入用户的id 75 需要传入用户的更新信息 76 parameterType指定的user对象,包括id和跟更新xinxi,注意id必须存在 77 #{id}:从输入user对象中获取id的属性值 78 --> 79 <update id="updateUser" parameterType="cn.wj.test.mybatis.pojo.User"> 80 update user set id = #{id} , username =#{username} , birthday = #{birthday},sex = #{sex},address = #{address} where id = #{id} 81 </update> 82 83 </mapper>
4.创建一个pojo类
User.java
1 package cn.wj.test.mybatis.pojo; 2 3 import java.util.Date; 4 5 /** 6 * Created by WJ on 2017/8/10 7 */ 8 public class User { 9 //属性名称和数据库表的字段对应 10 private int id; 11 private String username; 12 private String sex; 13 private Date birthday; 14 private String address; 15 16 public User(String username, String sex, Date birthday, String address) { 17 this.username = username; 18 this.sex = sex; 19 this.birthday = birthday; 20 this.address = address; 21 } 22 23 public int getId() { 24 return id; 25 } 26 27 public void setId(int id) { 28 this.id = id; 29 } 30 31 public String getUsername() { 32 return username; 33 } 34 35 public void setUsername(String username) { 36 this.username = username; 37 } 38 39 public String getSex() { 40 return sex; 41 } 42 43 public void setSex(String sex) { 44 this.sex = sex; 45 } 46 47 public Date getBirthday() { 48 return birthday; 49 } 50 51 public void setBirthday(Date birthday) { 52 this.birthday = birthday; 53 } 54 55 public String getAddress() { 56 return address; 57 } 58 59 public void setAddress(String address) { 60 this.address = address; 61 } 62 63 @Override 64 public String toString() { 65 return "User{" + 66 "id=" + id + 67 ", username='" + username + '\'' + 68 ", sex='" + sex + '\'' + 69 ", birthday=" + birthday + 70 ", address='" + address + '\'' + 71 '}'; 72 } 73 }
UserUUID.java
1 package cn.wj.test.mybatis.pojo; 2 3 /** 4 * Created by WJ on 2017/8/11 5 */ 6 public class UserUUID { 7 private String id; 8 private String name; 9 10 public String getId() { 11 return id; 12 } 13 14 public void setId(String id) { 15 this.id = id; 16 } 17 18 public String getName() { 19 return name; 20 } 21 22 public void setName(String name) { 23 this.name = name; 24 } 25 }
6.建立mybatis的查询语句
1 package cn.wj.test.mybatis.first; 2 3 import cn.wj.test.mybatis.pojo.User; 4 import cn.wj.test.mybatis.pojo.UserUUID; 5 import org.apache.ibatis.io.Resources; 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.Test; 10 11 import java.io.IOException; 12 import java.io.InputStream; 13 import java.util.Date; 14 import java.util.List; 15 16 /** 17 * Created by WJ on 2017/8/10 18 */ 19 public class mybatisFirst { 20 21 //根据id查询用户信息,得到一条记录结果 22 @Test 23 public void findUserByIdTests() throws IOException { 24 //mybatis配置文件 25 String resouce = "sqlMapConfig.xml"; 26 //得到配置文件流 27 InputStream inputStream = Resources.getResourceAsStream(resouce); 28 //创建会话工厂,传入mybatis的配置文件信息 29 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 30 //通过工厂得到sqlSession 31 SqlSession sqlSession = sqlSessionFactory.openSession(); 32 //通过sqlSession来操作数据库 33 //第一个参数,映射文件中statement的id,等于namespace.statementid(User.xml) 34 //第二个参数:指定和映射文件中所匹配的parameterType的类型的参数 35 //sqlSession.selectOne的结果是与映射文件中所匹配resultType的对象 36 User user = sqlSession.selectOne("test.findUserById", 1); 37 System.out.println(user.toString()); 38 //释放资源 39 sqlSession.close(); 40 } 41 42 //根据用户名称模糊查询用户列表 43 @Test 44 public void findUserByNameTests() throws IOException { 45 //mybatis配置文件 46 String resouce = "sqlMapConfig.xml"; 47 //得到配置文件流 48 InputStream inputStream = Resources.getResourceAsStream(resouce); 49 //创建会话工厂,传入mybatis的配置文件信息 50 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 51 //通过工厂得到sqlSession 52 SqlSession sqlSession = sqlSessionFactory.openSession(); 53 //通过sqlSession来操作数据库 54 //第一个参数,映射文件中statement的id,等于namespace.statementid(User.xml) 55 //第二个参数:指定和映射文件中所匹配的parameterType的类型的参数 56 //sqlSession.selectOne的结果是与映射文件中所匹配resultType的对象 57 List<User> userList = sqlSession.selectList("test.findUserByName", "wangjing"); 58 for (User user:userList) { 59 System.out.println(user); 60 } 61 //释放资源 62 sqlSession.close(); 63 } 64 65 //添加用户信息主键自增 66 @Test 67 public void insertUser() throws IOException { 68 //mybatis配置文件 69 String resouce = "sqlMapConfig.xml"; 70 //得到配置文件流 71 InputStream inputStream = Resources.getResourceAsStream(resouce); 72 //创建会话工厂,传入mybatis的配置文件信息 73 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 74 //通过工厂得到sqlSession 75 SqlSession sqlSession = sqlSessionFactory.openSession(); 76 //通过sqlSession来操作数据库 77 //第一个参数,映射文件中statement的id,等于namespace.statementid(User.xml) 78 //第二个参数:指定和映射文件中所匹配的parameterType的类型的参数 79 User user = new User("myname", "m", new Date(), "BJ"); 80 sqlSession.insert("test.insertUser",user); 81 System.out.println(user.getId()); 82 //提交事务 83 sqlSession.commit(); 84 //释放资源 85 sqlSession.close(); 86 } 87 88 //添加用户信息通过UUID方式自增的添加 89 @Test 90 public void insertUserUUID() throws IOException { 91 //mybatis配置文件 92 String resouce = "sqlMapConfig.xml"; 93 //得到配置文件流 94 InputStream inputStream = Resources.getResourceAsStream(resouce); 95 //创建会话工厂,传入mybatis的配置文件信息 96 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 97 //通过工厂得到sqlSession 98 SqlSession sqlSession = sqlSessionFactory.openSession(); 99 //通过sqlSession来操作数据库 100 //第一个参数,映射文件中statement的id,等于namespace.statementid(User.xml) 101 //第二个参数:指定和映射文件中所匹配的parameterType的类型的参数 102 UserUUID userUUID = new UserUUID(); 103 userUUID.setName("xxx"); 104 sqlSession.insert("test.insertUserUUID",userUUID); 105 System.out.println(userUUID.getId()); 106 //提交事务 107 sqlSession.commit(); 108 //释放资源 109 sqlSession.close(); 110 } 111 112 //通过id删除用户 113 @Test 114 public void deleteUser() throws IOException { 115 //mybatis配置文件 116 String resouce = "sqlMapConfig.xml"; 117 //得到配置文件流 118 InputStream inputStream = Resources.getResourceAsStream(resouce); 119 //创建会话工厂,传入mybatis的配置文件信息 120 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 121 //通过工厂得到sqlSession 122 SqlSession sqlSession = sqlSessionFactory.openSession(); 123 //通过sqlSession来操作数据库 124 //第一个参数,映射文件中statement的id,等于namespace.statementid(User.xml) 125 //第二个参数:指定和映射文件中所匹配的parameterType的类型的参数 126 sqlSession.delete("test.deleteUserById",-1); 127 //提交事务 128 sqlSession.commit(); 129 //释放资源 130 sqlSession.close(); 131 } 132 133 134 //更新用户 135 @Test 136 public void updateUser() throws IOException { 137 //mybatis配置文件 138 String resouce = "sqlMapConfig.xml"; 139 //得到配置文件流 140 InputStream inputStream = Resources.getResourceAsStream(resouce); 141 //创建会话工厂,传入mybatis的配置文件信息 142 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 143 //通过工厂得到sqlSession 144 SqlSession sqlSession = sqlSessionFactory.openSession(); 145 //通过sqlSession来操作数据库 146 //第一个参数,映射文件中statement的id,等于namespace.statementid(User.xml) 147 //第二个参数:指定和映射文件中所匹配的parameterType的类型的参数 148 User user = new User("myname123", "m", new Date(), "BJ123"); 149 user.setId(1); 150 sqlSession.update("test.updateUser",user); 151 //提交事务 152 sqlSession.commit(); 153 //释放资源 154 sqlSession.close(); 155 } 156 157 }
有关于查询的小总结:
parameterType:在映射文件中通过parameterType指定输入参数的类型
resultType:在映射文件中通过resultType指定输出结果的类型
#{}:
表示一个占位符,#{}接收输入参数,类型可以是简单类型,pojo,hashmap
如果接收简单类型,#{}可以写成value或其他的名称
接收输入参数,类型可以是简单类型,pojo,hashmap
#{}接收pojo对象值,通过ognl读取对象中的属性值,通过属性.属性的方式获取对象属性值
${}:
表示一个拼接符号,会引入sql注入,所以不建议使用
接收输入参数,类型可以是简单类型,pojo,hashmap
如果接收简单类型,${}只能写成value
${}接收pojo对象值,通过ognl读取对象中的属性值,通过属性.属性的方式获取对象属性值
selectOne:表示查询出一条记录进行映射(selectList也可以使用,这个List的只用一条记录)
selectList:表示查询一个列表(多条记录)进行映射(selectOne不可以使用,就会查询多条记录,不支持)
我们在User.xml如果要添加一个查询用户,我们可以这样说,我们可以在User.xml中创建一个添加用户的statement
mybatis中映射文件中sql语句后面不要加;号
自增主键返回
mysql自增主键
执行insert提交之前自动生成一个自增主键。
通过mysql函数获取到刚插入记录的自增主键
LAST_INSERT_ID()
是insert之后调用函数,这我需要把insert的statement的改为:
--------------------------------------------------------------------------------
<insert id="insertUser" parameterType="cn.wj.test.mybatis.pojo.User">
<!--
将插入的数据的主键返回,返回到user对象中
SELECT LAST_INSERT_TD():得到刚insert进去记录的主键值,只适用于自增主键
keyProperty:将查询到主键值设置到parameterType指定的对象的那个属性
order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句他的执行顺序
resultType:指定SELECT LAST_INSERT_ID()的结果类型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
--------------------------------------------------------------------------------
非自增主键的返回(uuid)
uuid()生成主键的方法
使用mysql的uuid函数生成主键,需要修改表中的id字段类型为String,长度设置为50位(这个没有一定标准,大于35位即可)
执行思路:
先通过uuid()查询到主键,将主键输入到sql语句中.
执行uuid()语句顺序相当于insert语句之前执行
--------------------------------------------------------------------------------
<insert id="insertUserUUID" parameterType="cn.wj.test.mybatis.pojo.UserUUID">
<!--
使用mysql的uuid生成主键
执行过程:
首先通过uuid()的到主键,将主键设置到user对象的id属性中
其次在insert执行过程时,从user对象取出id属性
-->
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT uuid()
</selectKey>
insert into useruuid(id,name) value(#{id},#{name})
</insert>
--------------------------------------------------------------------------------