preparedstatement in 多个参数 parametertype有多个怎么写_SQL


1. <typeAliases>标签(配置别名)

功能:用于给 java 类型定义别名, 方便在配置文件中使用.

使用方式一


<!-- typeAliases给类型起别名 -->
<typeAliases>
    <!-- 给User类起别名为u -->
   <typeAlias type="com.bjsxt.pojo.User" alias="u" />
</typeAliases>


使用方式二

<typeAlias>中, 可以省略 alias 属性, 表示类别名为类名, 大小写不敏感


<typeAliases>
    <!-- 给User类起别名, 别名为user -->
    <typeAlias type="com.bjsxt.pojo.User" />
</typeAliases>


使用方式三

可以通过<package>给整个包下的所有类定义别名为类名


<typeAliases>
	<!-- 给包下的所有类定义别名为类名 -->
	<package name="com.bjsxt.pojo" />
</typeAliases>


常见的MyBatis 的内建别名


preparedstatement in 多个参数 parametertype有多个怎么写_SQL_02


2 配置parameterType属性进行参数的传递

2.1 parameterType的使用环境

如果执行的是条件查询, 需要在调用方法时传参数进来, 此时, 可以在 select 标签中通过 parameterType 属性指定参数的类型. 而在 SQL 语句中, 可以通过#{}的方式获取参数.

2.2一个参数的查询

注意点:当只有一个参数时, #{}中可以任意填写

#{}用于获取参数

index, 索引, 从0开始

param+数字, param1, param2

实例

根据 id 查询用户信息.


<?xml version="1.0" encoding="UTF-8"?>
<!-- parameterType, 参数类型, 用于参数的传递 -->
<select id="selById" resultType="user" parameterType="int">
	select * from t_user where id=#{param1}
</select>


2.3多个参数的查询

多个参数的查询多个参数传递时, 由于 sqlSession 中提供的查询方法只允许传入一个参数, 因此可以对多个参数进行封装. 可以使对象Map 集合

2.3.1 封装为对象


select id="sel" resultType="user" parameterType="user">
	<!-- 如果参数是对象, 可以通过#{属性名}来获取 -->
	select * from t_user where username=#{username} and
	password=#{password}
</select>


2.3.2封装为Map集合


<select id="sel" resultType="user" parameterType="map">
	<!-- 如果参数是map, 可以通过#{key}来获取 -->
	select * from t_user where username=#{uname} and password=#{upwd}
</sele
public void sel() {
	SqlSession session = null;	
	try {
		session = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-cfg.xml"))
				.openSession();
		User u = new User();
		u.setUsername("zhangsan");
		u.setPassword("123");
		User user =
				session.selectOne("com.bjsxt.mapper.UserMapper.sel", u);
		System.out.println(user);
	} catch (IOException e) {	
		e.printStackTrace();
	} finally {
		session.close();
	}
}


3 MyBatis事务管理

3.1 事务(Transaction)

a) 事务是数据库操作的最小单元, 有 ACID 的特性. 应该保证一个事务的的 SQL 语句要么同时成功, 要么都不成功.

b) MyBatis 中配置了事务管理器, type 属性设置为 JDBC.表示 MyBatis 采用和原生 JDBC 相同的事务管理机制.

c) 在 MyBatis 执行的开始时,将自动提交功能关闭了.所以,在执行 DML 操作时, 需要手动提交事务.

3.2 新增(insert)

mapper 文件中, 通过<insert>定义新增语句.

注意, 由于DML 操作的返回值都是 int 类型, 所以, 不需要定义resultType 属性.


<!-- 新增 -->
	<insert id="insUser" parameterType="user">
	insert into t_user values (default, #{username}, #{password})
</insert>


测试


@Test
public void testIns() {
	SqlSession session = MyBatisUtil.getSession();
	User user = new User();
	user.setUsername("小明");
	user.setPassword("123");
	int num = session.insert("com.bjsxt.mapper.UserMapper.insUser",
			user);
	if(num > 0) {
		// 提交事务
		session.commit();
		System.out.println("SUCCESS!");
	} else {
		// 回滚事务


4 MyBatis接口绑定方案

MyBatis 中, 提供了一套接口绑定方案. 程序员可以提供一个 接 口 , 然 后 提 供 对 应 接 口 的 一 个 mapper.xml 文 件 .

MyBatis 会自动将接口和 xml 文件进行绑定. 实际上就是MyBatis 会根据接口和对应的 xml 文件创建接口的实现类.换言之, 就是可以得到接口类型的对象, 方便方法的调用.

4.1使用方法

1) 定义接口

2)编写对应接口的映射文件

3) 在核心配置文件中扫描接口

4)应用

1 定义接口


public interface UserMapper {
   List<User> selAll();
}


2 编写对应接口的映射文件

注意:

a)xml 文件名要和接口名一致

b)namespace 属性必须为接口的全限定路径

c)id 属性必须和接口对应的方法名一致


<mapper namespace="com.bjsxt.mapper.UserMapper">
	<select id="selAll" resultType="User">
		select * from t_user
	</select>
</mapper>


3 在核心配置文件中扫描接口

扫描单个接口, 可以使用 mapper 标签的 class 属性


<mappers>
	<mapper class="com.bjsxt.mapper.UserMapper" />
</mappers>


当扫描多个接口时,为简化配置,可以使用 package 标签,表示扫描对应包下的所有接口


<mappers>
       <package name="com.bjsxt.mapper" />
</mappers>


4 应用

在使用时, 可以通过 SqlSession 对象的 getMapper 方法,得到接口的代理对象, 从而可以调用定义好的方法


@Test
public void testBind() {
	SqlSession session = MyBatisUtil.getSession();
	UserMapper mapper = session.getMapper(UserMapper.class);
	List<User> list = mapper.selAll();
	for (User user : list) {
		System.out.println(user);
	}
	session.close();
}


4.2 接口绑定解决多参数的传递

方式一

接口中定义方法


User selByUP(String username, String password


映射文件中提供对应的标签. 此时, SQL语句中获取方式有两种, 通过#{index}或#{param+数字}的方式


<select id="selByUP" resultType="user">
        select * from t_user where username=#{0} and password=#{1}
</select>


方式二

接口中定义方法, 参数中使用@Param 注解设定参数名用于在 SQL 语句中使用


User selByUP(@Param("username") String username, @Param("password")
String password);


映射文件中提供对应的标签. 此时, SQL语句中获取方式有两种, 通过#{参数名称}或#{param+数字}的方式


<select id="selByUP" resultType="user">
	select * from t_user where username=#{username} andpassword=#{password}
</select>


5 动态 SQL

根据条件的不同, SQL 语句也会随之动态的改变,比如用户名,密码两个条件,就有四种情况解决SQL 字符串在一起时的错误,如忘了空格或在列表的最后省略逗号之类的

5.1动态SQL常用的标签

<if/><where/>

<choose/><when/><otherwise/>

<trim/><bind/>

<foreach/><sql/><include/>

5.2 动态SQL <if> where>

<if>

用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件.

<where>

用于管理 where 子句. 有如下功能:

a)如果没有条件, 不会生成 where 关键字

b)如果有条件, 会自动添加 where 关键字

c)如果第一个语句是and开头,会自动去除and

示例


<select id="sel" resultType="Student">
		select * from test
		<where>
			<if test="id>0">
				and id=#{id}
			</if>
			<if test="name!=null and name!=''">
				and name=#{name}
			</if>
		</where>
</select>


5.3 动态SQL <choose><when><otherwise> <set>

多个条件的判断的时候使用,功能类似于 switch...case...

5.3. 1<choose><when><otherwise>

示例


<select id="sel" resultType="user">
	select * from t_user
	<where>
		<choose>
			<when test="username != null and username != ''">
			and username = #{username}
			</when>
			<when test="password != null and password != ''">
			and password = #{password}
			</when>
			<otherwise>
			and 1=1
			</otherwise>
		</choose>
	</where>
</select>


5.3.2 <set>

用于维护 update 语句中的 set 子句. 功能如下:

a)满足条件时, 会自动添加 set 关键字

b)会去除 set 子句中多余的逗号

c)不满足条件时, 不会生成 set 关键字


int updUser(User user)
<update id="updUser" parameterType="user">
	update t_user
		<set>
			id=#{id}, <!-- 防止所有条件不成立时的语法错误 -->
			<if test="username != null and username != ''">
			username=#{username},
			</if>
			<if test="password != null and password != ''">
			password=#{password},
			</if>
		</set>
	where id=#{id}
</update>


5.4 动态SQL<trim> <bind>

<trim>

用于在前后添加或删除一些内容

prefix: 前缀, 表示向前面添加内容

prefixOverrides: 从前面删除内容

suffix: 后缀, 表示向后面添加内容

suffixOverrides: 从后面删除内容

示例


<update id="updUser" parameterType="user">
update t_user
	<trim prefix="set" prefixOverrides="user" suffix="hahaha"
	suffixOverrides=",">
	username=#{username},
	</trim>
	where id=#{id}
</update>


<bind>

用于对数据进行再加工, 用于模糊查询


<select id="sel" resultType="user">
	select * from t_user
	<where>
		<if test="username!=null and username!=''">
		<bind name="username" value="'%' + username + '%'"/>
		and username like #{username}
		</if>
	</where>
</select>


5.5 动态SQL <foreach> <sql><include>

<foreach>

用于在 SQL 语句中遍历集合参数, 在 in 查询中使用

a)collection: 待遍历的集合

b)open: 设置开始符号

c)item: 迭代变量

d)separator: 项目分隔符

e)close: 设置结束符号


<select id="selIn" parameterType="list" resultType="user">
	select * from t_user where id in
	<foreach collection="list" open="(" separator="," close=")"
	item="item">
	#{item}
	</foreach>
</select>


接口中的方法(可以设置别名来方便使用List)


List<User> selIn(@Param("list") List<Integer> list);


<sql><include>

<sql>用于提取 SQL 语句, <include>用于引用 SQL 语句


<sql id="mySql">
	id, username, password
</sql>
<select id="selIn" parameterType="list" resultType="user">
		select
	<include refid="mySql"/>
		from t_user where id in
	<foreach collection="list" open="(" separator="," close=")"item="item">
		#{item}
	</foreach>
</select>


6 MyBatis 的缓存机制

a)缓存用于提高查询的效率

b)MyBatis的缓存是使用SQL标签的ID作为缓存的唯一标识的. 执行相同的标签可以使用缓存. 不同的标签不能使用缓存

c) MyBatis 中有两种缓存机制

1 一级缓存

a)默认开启. 线程级别的缓存, SqlSession 的缓存

b)在一个 SqlSession 生命周期中有效. SqlSession 关闭,缓存清空.

1 二级缓存

a)进程级别的缓存, SqlSessionFactory 的缓存

b)在一个 SqlSessionFactory 生命周期中有效.可以在多个SqlSession 生命中期中共享.

c)默认关闭, 需要使用的时候, 要为某个命名空间开启二级缓存(在 mapper.xml 中配置<cache>)

7 解决列名和属性名不一致问题

方式一

列别名

查询时, 可以通过列别名的方式将列名和属性名保持一致,继续使用自动映射, 从而解决该问题. 但是较为麻烦


<select id="selAll" resultType="user">
	select id id1, username username1, password password2 from t_user
</select>


方式二

使用<resultMap>

<resultMap>用于自定义映射关系, 可以由程序员自主制定列名和属性名的映射关系. 一旦使用 resultMap, 表示不再采用自动映射机制

id用于映射主键

result用于非主键映射


<resultMap type="user" id="umap">
	<id column="id" property="id1" />
	<result column="username" property="username1" />
	<result column="password" property="password1" />
</resultMap>
<select id="selAll" resultMap="umap">
	select * from t_user
</select>


8 多表关联查询_设计表结构

1 MyBatis实现多表关联查询的方式

业务装配方式

n+1方式

关联方式

1.1业务装配实现多表查询(多对一)

mapper 层只做单表查询操作, 在 service 层进行手动装配,实现关联查询的结果

注意在创建实体类的时候添加另一个表格的对象作为属性

1.1.2示例

mapper 层

学生:


<mapper namespace="com.bjsxt.mapper.StudentMapper">
	<select id="selAll" resultType="student">
		select * from t_student
	</select>
</mapper>


班级:


<mapper namespace="com.bjsxt.mapper.ClazzMapper">
	<select id="selById" resultType="clazz" parameterType="int">
		select * from t_class where id=#{0}
	</select>
</mapper>


service 层

调用 mapper 层, 先查询所有学生, 再根据每个学生的班级编号查询班级信息, 手动进行组装, 称之为业务装配


public class StudentServiceImpl implements StudentService {
	@Override
	public List<Student> selAll() {
		SqlSession session = MyBatisUtil.getSession();
// 学生mapper
		StudentMapper stuMapper = session.getMapper(StudentMapper.class);
// 班级mapper
		ClazzMapper clsMapper = session.getMapper(ClazzMapper.class);
// 查询所有学生信息
		List<Student> list = stuMapper.selAll();
// 为每一个student组装班级信息
		for (Student student : list) {
			student.setClazz(clsMapper.selById(student.getCid()));
		}
		session.close();
		return list;
	}
}


2 resultMap的N+1方式实现多表查询(多对一)

2.1 mapper 层

<association>用于关联一个对象

property: 指定要关联的属性名

select: 设定要继续引用的查询, namespace+id

column: 查询时需要传递的列

提供 StudentMapper 和 ClazzMapper, StudentMapper 查询所有学生信息, ClazzMapper 根据编号查询班级信息. 再StudentMapper 中使用<association>设置装配

学生:


<mapper namespace="com.bjsxt.mapper.StudentMapper">
	<resultMap type="student" id="smap">
	<!-- N+1查询时, 同名映射可以省略, 但是只能使用一次 -->
		<result property="cid" column="cid" />
		<!-- 用于关联一个对象 -->
		<association property="clazz" select="com.bjsxt.mapper.ClazzMapper.selById" column="cid">
		</association>
	</resultMap>
	<select id="selAll" resultMap="smap">
		select * from t_student
	</select>
</mapper>


班级:


<mapper namespace="com.bjsxt.mapper.ClazzMapper">
	<select id="selById" resultType="clazz" parameterType="int">
		select * from t_class where id=#{0}
	</select>
</mapper>


2.2 service 层

由于装配已经完成, service 层只需要调用 mapper 即可, 不需要再进行装配了


public class StudentServiceImpl implements StudentService {
	@Override
	public List<Student> selAll() {
		SqlSession session = MyBatisUtil.getSession();
// 学生mapper
		StudentMapper stuMapper = session.getMapper(StudentMapper.class);
		List<Student> list = stuMapper.selAll();
		session.close();
		return list;
	}
}


3 resultMap 的关联方式实现多表查询(多对一)

3.1 mapper 层

a)在 StudentMapper.xml 中定义多表连接查询 SQL 语句, 一次性查到需要的所有数据, 包括对应班级的信息.

b)通过<resultMap>定义映射关系, 并通过<association>指定对象属性的映射关系. 可以把<association>看成一个<resultMap>使用. javaType 属性表示当前对象, 可以写全限定路径或别名


<resultMap type="student" id="smap">
	<id property="id" column="sid" />
	<result property="name" column="sname" />
	<result property="age" column="age" />
	<result property="gender" column="gender" />
	<result property="cid" column="cid" />
	<association property="clazz" javaType="clazz">
	<id property="id" column="cid" />
	<result property="name" column="cname" />
	<result property="room" column="room" />
	</association>
</resultMap>
<select id="selAll" resultMap="smap">
	select s.id sid, s.name sname, s.age, s.gender, c.id cid,c.name cname, c.room from t_student s left join t_class c on s.cid=c.id
</select>


9 注解开发详解

1 注解简介

a)注解是用于描述代码的代码. 例如: @Test(用于描述方法进行 junit 测试), @Override(用于描述方法的重写),@Param(用于描述属性的名称)

b)注解的使用风格: @xxx(属性), 使用前必须先导包

c)使用注解一般用于简化配置文件. 但是, 注解有时候也不是很友好(有时候反而更麻烦), 例如动态 SQL.

d)关于注解的属性

属性的设定方式是: 属性名=属性值

e)关于属性值的类型

基本类型和 String, 可以直接使用双引号的形式数组类型, name={值 1, 值 2, ...}; 如果数组元素只有一个, 可以省略大括号

对象类型, name=@对象名(属性) 如果属性是该注解的默认属性, 而且该注解只配置这一个属性, 可以将属性名省略

f)注解和配置文件可以配合使用

2 注解的使用

直接在方法上一行声明SQL语句


public interface StudentMapper {
	@Select("select * from t_student")
	List<Student> selAll();@Insert("insert into t_student values (default, #{name}, #{age},#{gender},#{cid})")
	int insStu(Student student);
	@Update("update t_student set age=#{1} where id=#{0}")
	int updStu(int id, int age);
	@Delete("delete from t_student where id=#{0}")
	int delStu(int id);
}


3 @Results和@Result

@Results: 类似于<resultMap>

@Result: 类似于<resultMap>的子标签

3.1 通过注解实现多表关联查询

班级:


public interface ClazzMapper {
	@Select("select * from t_class where id=#{0}")
	Clazz selById(int id);
}


学生:


public interface StudentMapper {
	@Select("select * from t_student")
	@Results(value = {
		@Result(column="id", property="id", id=true),
		@Result(column="name", property="name"),
		@Result(column="age", property="age"),
		@Result(column="gender", property="gender"),
		@Result(column="cid", property="cid"),
		@Result(property="clazz", one=@One(select="com.bjsxt.mapper.ClazzMapper.selById"), column="cid")
	})
	List<Student> sel();
}