初入MyBatis框架<二>
演示使用Mybatis单表查询,以及核心配置文件的编写:
首先先创建一个数据库mybatis和表users:
SQL语句:
create database if not exists mybatis default character set 'utf8';
use mybatis;
create table users(
id varchar(32) primary key,
name varchar(32),
pwd varchar(32)
);
insert into users value('U001','Jack','1234');
insert into users value('U010','张三','4321');
然后写对应的值对象(SET,GET):
写一个他的核心配置文件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="users"><!-- 数据库的表名字 -->
<!-- 这里的标签就是操作名,例如select-->
</mapper>
演示1:
@Test
public void query1(){
SqlSession session = SqlSessionUtils.getSqlSession();
//MyBatis是默认开启事务的,可以从log4j中看出
List<User> users= session.selectList("all");//用id来选择SQL
for(User user : users){
System.out.println(users);
}
session.close();
}
配置文件中:
(别名在mybatis.xml中配置)
<select id="all" resultType="cn.hncu.domain.User">
select * from Users
</select>
演示2:采用接口
//采用接口的方式访问---更安全
@Test
public void query1_2(){
SqlSession session = SqlSessionUtils.getSqlSession();
UserMapper um=session.getMapper(UserMapper.class);
List<User> users= um.all();//all是配置文件中的ID
for(User user : users){
System.out.println(users);
}
session.close();
}
这里需要写一个接口:
配置文件:重新写一个User2.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="cn.hncu.domain.UserMapper"><!-- 域名为接口类型 -->
<select id="all" resultType="cn.hncu.domain.User">
select * from users
</select>
</mapper>
演示传参:—传单个参数
第一个普通,第二个是用接口:
@Test //演示传单个参数(直接使用脚本id的方式)
public void query2_1(){
SqlSession session = SqlSessionUtils.getSqlSession();
//前一个参数为别名+ID,后一个参数为传递给“#{value}”
List<User> users=session.selectList("users.user2", "U001");
for(User user: users){
System.out.println(user);
}
session.close();
}
//演示传单个参数(使用接口)---访问的是User2.xml
@Test //因为它的命名空间用的是UserMapper接口--下面session.getMapper()时的参数
public void query2_2(){
SqlSession session = SqlSessionUtils.getSqlSession();
UserMapper um= session.getMapper(UserMapper.class);
List<User> users=um.user2("U001");
for(User user: users){
System.out.println(user);
}
session.close();
}
配置文件:
<!-- 演示传单个参数 -->
<select id="user2" resultType="User" parameterType="string">
<!--返回类型为User,参数类型为string,参考帮助文档 -->
select * from users where id=#{value}
</select>
传多个参数
@Test //演示传多个参数(直接使用脚本id的方式)
public void query3_1(){
SqlSession session = SqlSessionUtils.getSqlSession();
//让users自己封装成javabean
User user = new User();
user.setId("U010");
user.setName("张三");
List<User> users = session.selectList("user3",user);
System.out.println(users);
session.close();
}
配置文件:
<!-- 演示传多个参数,,参数类型用值对象,sql中的形参名必须是User中的某个属性 -->
<select id="user3" resultType="User" parameterType="User">
select * from users where id=#{id} and name=#{name}
</select>
也可以做成动态SQL,由用户决定查询条件:在配置文件中
<!-- 把上个版本做成动态SQL -->
<select id="user3_2" resultType="User" parameterType="User">
select * from users where id=#{id}
<if test="name!=null">
and name=#{name}
</if>
</select>
更改配置文件中的返回类型,他会自动封装:
<!-- 返回类型是List<Map> -->
<select id="user4_1" resultType="hashmap">
select * from users
</select>
<!-- 查询条件不存在结果,返回的是空值 . 入参类型也为HashMap -->
<select id="user4_2" resultType="hashmap" parameterType="hashmap">
select * from users where id=#{id}
<if test="name!=null">
and name=#{name}
</if>
</select>
增删改查技术都是一样的:
<!-- 增 ,换个标签insert -->
<insert id="insertUser" parameterType="User">
insert into users(id,name,pwd)
values(#{id}, #{name}, #{pwd})
</insert>
<!-- 修改 -->
<update id="updateUser" parameterType="User">
update users set
name=#{name},pwd=#{pwd}
where id=#{id}
</update>
<!-- 删除 -->
<delete id="deleteUser" parameterType="hashmap">
delete from users where 1=-1
<if test="id != null">
or id=#{id}
</if>
<if test="name != null">
or name=#{name}
</if>
</delete>
因为是默认开启事务,所以演示增删改代码中要写commit();
还可自定义一个SQL标记块:
以后有很多个变量时,可统一定义,节省代码空间
<!-- sql标记块 -->
<sql id="sql1">
id,name,pwd
</sql>
<select id="all3" resultType="User">
select <include refid="sql1"/> from users
</select>
利用mybatis获得自动增长列字段的返回值
创建spu表
SQL语句:
CREATE TABLE cpu(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30)
);
两种方式:
1、纯java
2、mybatis配置
第一种:
@Test //纯java
public void getKey1() throws Exception{
SqlSession s= SqlSessionUtils.getSqlSession();
Connection con =s.getConnection();
String sql = "insert into cpu(name) values('AMD')";
Statement st=con.createStatement();
st.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);//拿返回值
ResultSet rs = st.getGeneratedKeys();
rs.next();
int k= rs.getInt(1);
System.out.println("key="+k);
s.commit();
s.close();
}
第二种:
@Test //mybatis方式
public void getKey2() throws Exception{
SqlSession s= SqlSessionUtils.getSqlSession();
Connection con =s.getConnection();
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "InAMD");
s.insert("autoKey",map);
System.out.println("key="+map.get("iid"));
s.commit();
s.close();
}
配置文件中:
<!-- 获取自动增长列字段值 -->
<insert id="autoKey" parameterType="hashmap"
keyProperty="iid" keyColumn="id"
useGeneratedKeys="true"
><!-- 参数含义1. 通过hashmap带回,2.前面调用的是哪个id拿到
3.哪一列是自动增长,4.然后要帮我们产生自动增长-->
insert into cpu(name) values(#{name})
</insert>
单表操作演示完。
专门演示下动态SQL:
除开用‘IF’能做到以外,还有几个标签也可以:
演示代码就不分开了
public class Demo3 {
@Test//演示动态SQL技术
public void dyncUser1(){
User user=new User();
user.setName("%o%");
user.setPwd("%2%");
SqlSession s= SqlSessionUtils.getSqlSession();
List<User> list = s.selectList("dyncUser1",user);
System.out.println(list);
s.commit();
s.close();
}
@Test//演示动态SQL技术2
public void dyncUser2(){
User user=new User();
//user.setId("U004");
user.setName("%o%");
user.setPwd("%2%");
SqlSession s= SqlSessionUtils.getSqlSession();
List<User> list = s.selectList("dyncUser2",user);
System.out.println(list);
s.commit();
s.close();
}
@Test//演示动态SQL技术3
public void dyncUser3(){
User user=new User();
//user.setId("U004");
user.setName("%o%");
user.setPwd("%2%");
SqlSession s= SqlSessionUtils.getSqlSession();
List<User> list = s.selectList("dyncUser3",user);
System.out.println(list);
s.commit();
s.close();
}
@Test//演示动态SQL技术4
public void dyncUpdate(){
User user=new User();
user.setId("U002");
user.setName("狒狒");
user.setPwd("8888");
SqlSession s= SqlSessionUtils.getSqlSession();
int n = s.update("dyncUpdate",user);
System.out.println("n="+n);
s.commit();
s.close();
}
@Test//演示动态SQL技术4
public void dyncUser4(){
List<Object> list = new ArrayList<Object>();
list.add("U001");
list.add("U002");
list.add("U010");
SqlSession s= SqlSessionUtils.getSqlSession();
List<User> user = s.selectList("dyncUser4", list);
System.out.println(user);
s.commit();
s.close();
}
}
配置文件中的:
IF:
<!-- 演示动态SQL技术 -->
<select id="dyncUser1" resultType="User" parameterType="string">
select * from users where 1=1
<if test="id !=null">
and id=#{id}
</if>
<!-- 不用&&,而是用'and' -->
<if test="name !=null and name !='' ">
and name like #{name}
</if>
<if test="pwd !=null">
and pwd like #{pwd}
</if>
</select>
WHERE
<!-- 演示动态SQL技术 2 -->
<select id="dyncUser2" resultType="User" parameterType="string">
select * from users
<where>
<if test="id !=null">
and id=#{id}
</if>
<if test="name !=null and name !='' ">
and name like #{name}
</if>
<if test="pwd !=null">
and pwd like #{pwd}
</if>
</where>
</select>
TRIM
<!-- 演示动态SQL技术 3 -->
<select id="dyncUser3" resultType="User" parameterType="string">
select * from users
<trim prefix="where" prefixOverrides="and"> <!-- 前缀 如果出现and前缀,就用where代替 -->
<if test="id !=null">
and id=#{id}
</if>
<if test="name !=null and name !='' ">
and name like #{name}
</if>
<if test="pwd !=null">
and pwd like #{pwd}
</if>
</trim>
</select>
SET
<update id="dyncUpdate" parameterType="string">
update users
<!-- ','可以多,他会帮我们删掉 -->
<set>
<if test="name != null and name !='' ">
name=#{name},
</if>
<if test="pwd !=null">
pwd=#{pwd},
</if>
</set>
where id = #{id}
</update>
FOREACH
<select id="dyncUser4" resultType="User" parameterType="list">
select * from users where id in
<!-- 构造子句:where id in('U001','U002','U010') -->
<foreach collection="list" item="val"
open="(" close=")" separator=","
><!-- open以什么开头, close以什么结尾 ,separator用,分隔-->
#{val}
</foreach>
</select>