1. 计划
1. 输入映射
2. 输出映射
3. 动态SQL
4. 关联关系
5. Spring集成MyBatis
2. 输入映射
2.1.1. 输入映射-包装pojo
我们假设创建一个身份证信息实体类IdCard,IdCard里包含一个属性User引用,模拟这么一个场景,加入我们知道一个Idcard,也知道IdCard的user.id属性值,想传入一个IdCard到后台方法查询出用户详细信息。
2.1.1.1. 创建IdCard
public class IdCard {
private String cartId;
private String city;
private String province;
private User user; //get..set… } |
2.1.1.2. 创建Mapper.xml对应的查询方法
<!-- getByCardUser --> <select id="getByCardUser" parameterType="IdCard" resultType="User"> SELECT * FROM user WHERE id=#{user.id} </select> |
2.1.2. 输入映射-Map
2.1.2.1. 创建测试方法
@Test public void getByMap(){ User user = new User(); user.setId("28"); Map<String, Object> dataMap = new HashMap<String,Object>(); dataMap.put("mp", user);
User userinfo = sqlSession.getMapper(UserMapper.class).getByMap(dataMap); System.out.println(userinfo); } |
2.1.2.2. 创建Mapper.xml方法
这里和Pojo类似,都是key.property
<!-- getByMap --> <select id="getByMap" parameterType="map" resultType="User"> SELECT * FROM user WHERE id=#{mp.id} </select> |
3. 输出映射
3.1. 简单数据类型
3.1.1. 创建测试方法
创建一个方法,查询总用户记录数
/*** * 输出映射-简单数据类型 */ @Test public void getCount(){ int count = sqlSession.getMapper(UserMapper.class).getAllCount(); System.out.println(count); } |
3.1.2. 创建Mapper.xml实现方法
<!-- getAllCount --> <select id="getAllCount" resultType="int"> SELECT COUNT(*) FROM user </select> |
3.1.3. 简单数据类型别名参考表
参考类:org.apache.ibatis.type.TypeAliasRegistry
public TypeAliasRegistry() { this.registerAlias("string", String.class); this.registerAlias("byte", Byte.class); this.registerAlias("long", Long.class); this.registerAlias("short", Short.class); this.registerAlias("int", Integer.class); this.registerAlias("integer", Integer.class); this.registerAlias("double", Double.class); this.registerAlias("float", Float.class); this.registerAlias("boolean", Boolean.class); this.registerAlias("byte[]", Byte[].class); this.registerAlias("long[]", Long[].class); this.registerAlias("short[]", Short[].class); this.registerAlias("int[]", Integer[].class); this.registerAlias("integer[]", Integer[].class); this.registerAlias("double[]", Double[].class); this.registerAlias("float[]", Float[].class); this.registerAlias("boolean[]", Boolean[].class); this.registerAlias("_byte", Byte.TYPE); this.registerAlias("_long", Long.TYPE); this.registerAlias("_short", Short.TYPE); this.registerAlias("_int", Integer.TYPE); this.registerAlias("_integer", Integer.TYPE); this.registerAlias("_double", Double.TYPE); this.registerAlias("_float", Float.TYPE); this.registerAlias("_boolean", Boolean.TYPE); this.registerAlias("_byte[]", byte[].class); this.registerAlias("_long[]", long[].class); this.registerAlias("_short[]", short[].class); this.registerAlias("_int[]", int[].class); this.registerAlias("_integer[]", int[].class); this.registerAlias("_double[]", double[].class); this.registerAlias("_float[]", float[].class); this.registerAlias("_boolean[]", boolean[].class); this.registerAlias("date", Date.class); this.registerAlias("decimal", BigDecimal.class); this.registerAlias("bigdecimal", BigDecimal.class); this.registerAlias("biginteger", BigInteger.class); this.registerAlias("object", Object.class); this.registerAlias("date[]", Date[].class); this.registerAlias("decimal[]", BigDecimal[].class); this.registerAlias("bigdecimal[]", BigDecimal[].class); this.registerAlias("biginteger[]", BigInteger[].class); this.registerAlias("object[]", Object[].class); this.registerAlias("map", Map.class); this.registerAlias("hashmap", HashMap.class); this.registerAlias("list", List.class); this.registerAlias("arraylist", ArrayList.class); this.registerAlias("collection", Collection.class); this.registerAlias("iterator", Iterator.class); this.registerAlias("ResultSet", ResultSet.class); }
|
3.2. ResultType
假如现在有这么一个需求,数据库name字段变成了user_name,我们按照原来的查询条件进行查询
3.2.1. 测试类方法
/*** * 输入Map */ @Test public void getByMap(){ User user = new User(); user.setId("28"); Map<String, Object> dataMap = new HashMap<String,Object>(); dataMap.put("mp", user);
User userinfo = sqlSession.getMapper(UserMapper.class).getByMap(dataMap); System.out.println(userinfo); } |
结果
问题来了,我们采用ResultType,得到的数据部分属性能进行转换,但数据库和实体bean之间属性名不一样的,无法进行转换,如何解决?
这里提供一种解决方案:可以在查询的时候取别名
例如 select id,user_name name,agefrom user where id=28
3.2.2. 修改Mapper.xml查询方法
<!-- getByMap --> <select id="getByMap" parameterType="map" resultType="User"> SELECT id,user_name name,age FROM user WHERE id=#{mp.id} </select> |
测试结果:
3.3. ResultMap
这里还提供另外一种解决方案,ResultMap,ResultMap更想Hibernate里面的hbm.xml文件的映射功能,提供了数据库表字段和实体Bean之间属性的一种映射关系,然后根据映射关系进行转换。
3.3.1. 修改Mapper.xml
3.3.1.1. 增加<resultMap>节点
这里的id节点是个特殊节点,指和数据库之间主键映射的属性,这里它类似Set集合,不允许id节点在对应的集合里出现重复。
result则是普通映射关系。
<resultMap type="User" id="baseResultMap"> <id column="id" property="id" javaType="java.lang.String"/> <result column="user_name" property="name" javaType="java.lang.String"/> <result column="age" property="age" javaType="int" /> </resultMap> |
3.3.1.2. 运行测试
问题来了,大家思考一下那么ResultMap是什么原理呢?
4. 动态SQL
4.1. If
在动态 SQL 中所做的最通用的事情是包含部分 where 字句的条件。比如:
<!-- getByMap --> <select id="getByMap" parameterType="map" resultMap="baseResultMap"> SELECT id,user_name,age FROM user WHERE 1=1 <if test="mp.id!=null"> AND id=#{mp.id} </if> </select> |
这条语句会提供一个可选的文本查找功能。如果你没有传递 id,那么所有数据将会被查出。
假若我们想可选搜索id 和 name 呢?首先,要改变语句的名称让它有意义。然后 简单加入另外的一个条件。
<!-- getByMap --> <select id="getByMap" parameterType="map" resultMap="baseResultMap"> SELECT id,user_name,age FROM user WHERE 1=1 <if test="mp.id!=null"> AND id=#{mp.id} </if> <if test="mp.name!=null"> AND user_name=#{mp.name} </if> </select> |
4.2. choose, when, otherwise
有时我们不想应用所有的条件, 相反我们想选择很多情况下的一种。 Java 中的 switch 和 语句相似,MyBatis 提供 choose 元素。
@Test public void getByDySQL(){ User user = new User("%小红%",15); List<User> users = sqlSession.getMapper(UserMapper.class).getByDySQL(user);
for (User u : users) { System.out.println(u); } } |
<!-- getByDySQL --> <select id="getByDySQL" parameterType="User" resultType="User"> SELECT * FROM user WHERE 1=1 <choose> <when test="age>15"> <![CDATA[ AND age>#{age} ]]> </when> <when test="name!=null"> <![CDATA[ AND age<=#{age} AND user_name like #{name} ]]> </when> <otherwise> AND age=#{age} </otherwise> </choose> </select> |
4.3. trim, where, set
前面的例子已经方便地处理了一个臭名昭著的动态 SQL 问题。要考虑我们回到“if”示 例后会发生什么,如果用if,一个条件都不成立这时候就会有问题。如:id=null,name=null的情况下,SQL语句就是个病句。
<!-- getByMap --> <select id="getByMap" parameterType="map" resultMap="baseResultMap"> SELECT id,user_name,age FROM user WHERE <if test="mp.id!=null"> AND id=#{mp.id} </if> <if test="mp.name!=null"> AND user_name=#{mp.name} </if> </select> |
where 元素知道如果由被包含的标记返回任意内容,就仅仅插入“WHERE” 。而且,如 果以“AND”或“OR”开头的内容,那么就会跳过 WHERE 不插入。
<!-- getByDySQL --> <select id="getByDySQL" parameterType="User" resultType="User"> SELECT * FROM user <where> <if test="age>15"> age>#{age} </if> <if test="name!=null"> user_name like #{name} </if> </where> </select> |
如果 where 元素没有做出你想要的,你可以使用 trim 元素来自定义。比如,和 where 元素相等的 trim 元素是:
<!-- getByDySQL --> <select id="getByDySQL" parameterType="User" resultType="User"> SELECT * FROM user <trim prefix="WHERE" prefixOverrides="AND|OR"> <if test="age>15"> OR age>#{age} </if> <if test="name!=null"> AND user_name like #{name} </if> </trim> </select> |
结果
针对修改而言,我们还有另一种操作方式,set标签
<!-- update --> <update id="update" parameterType="User"> UPDATE user <set> <if test="age>0"> age=#{age}, </if> <if test="name!=null"> user_name=#{name}, </if> </set> WHERE id=#{id} </update> |
4.4. foreach*
另外一个动态 SQL 通用的必要操作是迭代一个集合, 通常是构建在 IN 条件中的。 比如:
@Test public void testForeachList(){ List<User> users = new ArrayList<User>(); users.add(new User("18")); users.add(new User("21")); users.add(new User("25")); List<User> alluser = sqlSession.getMapper(UserMapper.class).getByIdList(users); for (User user : alluser) { System.out.println(user); }
} |
<!-- getByIdList --> <select id="getByIdList" parameterType="User" resultMap="baseResultMap"> SELECT * FROM user WHERE id IN <foreach collection="list" item="item" open="(" close=")" separator=","> #{item.id} </foreach> </select> |
foreach 元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可 以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素 是很智能的,它不会偶然地附加多余的分隔符。
注意 你可以传递一个 List 实例或者数组作为参数对象传给 MyBatis。当你这么做的时 候,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list” 作为键,而数组实例将会以“array”作为键。
这个部分是对关于 XML 配置文件和 XML 映射文件的而讨论的。下一部分将详细讨论 Java API,所以你可以得到你已经创建的最有效的映射。
4.5. Sql片段
比如一张表字段比较多,但又不是所有的都常用,可以写一个sql节点,里面写一些常常要用到的sql语句,提供在其他地方调用,如下:
<!-- SQL片段 --> <sql id="Base_Cloumn_List"> id,user_name,age </sql> |
通过<include refid=”x”/>来引用
<!-- getByIdList --> <select id="getByIdList" parameterType="User" resultMap="baseResultMap"> SELECT <include refid="Base_Cloumn_List" /> FROM user WHERE id IN <foreach collection="list" item="item" open="(" close=")" separator=","> #{item.id} </foreach> </select> |
5. 关联关系
5.1. 一对一关联
5.1.1. 分析
一对一关联关系,我们举个例子,比如有2张表,一张User表,一张IdCard表,一张身份证信息对应一个人,或者叫一个人只有一张身份证信息都行。那程序中如何去实现一对一关联关系?
我们分析大概有2种,一种是一条SQL通过关联关系全部查出来,另一种是先查询出一条来,再根据这一条查询关联对象。
1、 select u.*,card.* from user u inner join IdCard card on u.id=card.userid 2、 select * from user where id=12 select * from IdCard where userid=12 |
5.1.2. association关联查询
association一个复杂的类型关联;许多结果将包成这种类型,嵌入结果映射 – 结果映射自身的关联,或者参考一个
<resultMap type="IdCard" id="IdCardResultMap"> <id column="cartId" property="cartId"/> <result column="province" property="province" /> <result column="city" property="city" />
<!-- 一对一映射关系 --> <association property="user" javaType="User"> <id column="id" property="id"/> <result column="name" property="name" /> <result column="age" property="age" /> </association> </resultMap> |
5.1.2.1. 多次查询实现一对一
Mapper.xml代码实现
这里代码可以理解成< association select=”getUserById”>当前节点的数据通过调用getUserById的节点得到,和我们前面所想的先查询出身份证信息,再查出用户信息分两个步骤。
<resultMap type="IdCard" id="IdCardResultMap"> <id column="cartId" property="cartId"/> <result column="province" property="province" /> <result column="city" property="city" />
<!-- 一对一映射关系 --> <association property="user" javaType="User" select="getUserById" column="userid"> <id column="id" property="id"/> <result column="user_name" property="name" /> <result column="age" property="age" /> </association> </resultMap>
<!-- getCard --> <select id="getCard" parameterType="java.lang.String" resultMap="IdCardResultMap"> SELECT * FROM IdCard WHERE cartId=#{cartId} </select>
<!-- getUserById --> <select id="getUserById" parameterType="java.lang.String" resultType="User"> SELECT id,user_name name,age FROM user WHERE id=#{id} </select> |
输出结果有2条SQL语句,说明做了2次查询。
5.1.2.2. 一对一一次关联查询
上面的步骤分为了2次实现了一对一查询,那红做法和我们通常写java代码实现思路一致,但有没有什么方法能够实现一次查询就能得到结果呢?也可以,例如写个关联查询,再封装一个和关联查询对应的结果集的实体Bean。当然这种做法不科学,可以利用MyBatis提供的association节点来完成。
步骤如下:
先写一个关联查询SQL
创建实体Bean之间的关联关系
创建resultMap之间的映射关系,通过association来建立映射
SQL关联查询
SELECT card.*, u.* FROM idcard card INNER JOIN user u ON card.userid=u.id WHERE Card.cartId=#{cartId} |
ResultMap映射
这里只需要指定对应的属性property和当前association需要转换的java类型即可。
<resultMap type="IdCard" id="IdCardResultMap"> <id column="cartId" property="cartId"/> <result column="province" property="province" /> <result column="city" property="city" />
<!-- 一对一映射关系 --> <association property="user" javaType="User"> <id column="id" property="id"/> <result column="user_name" property="name" /> <result column="age" property="age" /> </association> </resultMap> |
将对应的SQL语句写到对应的节点里
<!-- getCard --> <select id="getCard" parameterType="java.lang.String" resultMap="IdCardResultMap"> SELECT card.*, u.* FROM idcard card INNER JOIN user u ON card.userid=u.id WHERE cartId=#{id} </select> |
5.2. 一对多关联
5.2.1. 分析
刚才我们完成了一对一的关联关系管理,那么如果有一对多如何管理呢?MyBatis提供了ResultMap的子节点collection来管理一对多映射。它的流程和步骤与一对一关联映射处理一样,也有2种情况,分别为多次查询匹配结果和单次查询从结果集对象里组合一对多信息
假设有这么一种场景,在上述情况下,增加一个Mobile对象,一个人有多部手机,如何实现?
5.2.2. 创建Mobile表和实体Bean
CREATE TABLE `mobile` ( `mid` varchar(50) NOT NULL, `mname` varchar(50) NOT NULL, `userid` varchar(50) NOT NULL, PRIMARY KEY (`mid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
public class Mobile {
private String mid;
private String mname; //get set… } |
5.2.3. Collection一对多关联查询
Mapper.xml映射配置信息
在刚才的基础上加入collection节点,如下,调用getByUserId来查询手机信息
<resultMap type="IdCard" id="IdCardResultMap"> <id column="cartId" property="cartId"/> <result column="province" property="province" /> <result column="city" property="city" />
<!-- 一对一映射关系 --> <association property="user" javaType="User"> <id column="id" property="id"/> <result column="user_name" property="name" /> <result column="age" property="age" />
<!-- 一对多关联映射关系管理 --> <collection property="mobiles" select="getByUserId" column="id"> <id column="mid" property="mid" /> <result column="mname" property="mname" /> </collection>
</association> </resultMap> |
通过用户id查询手机信息
<!-- 根据用户ID查询手机信息 --> <select id="getByUserId" parameterType="java.lang.String" resultType="Mobile"> SELECT * FROM mobile WHERE userid=#{userid} </select> |
测试
ResultType 对应得是基本类型 和 模型类型
ResultMap 对应得是自定义的 resultMap
5.3. 整合步骤
1. 创建一个java工程。
2. 导入jar包。(课前资料中mybatis与spring整合所有包)
3. mybatis的配置文件mybatis.xml
4. 编写Spring的配置文件
1) 数据库连接及连接池
2) sqlsessionFactory对象,配置到spring容器中
3) 编写Spring的配置文件
5. 复制jdbc.properties配置文件到新工程
6. 复制log4j.properties配置文件到新工程
5.3.1. 一次关联查询
一次关联查询,这里最考验的是SQL语句查询。我们思考一下,这里其实最终就是要再建立关联关系,把手机信息查出来,而手机是跟用户建立关联关系的,所以可以在上面SQL语句的基础上增加下关联查询即可
关联查询
<!-- getCard --> <select id="getCard" parameterType="java.lang.String" resultMap="IdCardResultMap"> SELECT card.*, u.*, m.mid, m.mname FROM idcard card INNER JOIN user u ON card.userid=u.id LEFT JOIN mobile m ON m.userid=u.id WHERE cartId=#{id} </select> |
resultMap配置
<resultMap type="IdCard" id="IdCardResultMap"> <id column="cartId" property="cartId"/> <result column="province" property="province" /> <result column="city" property="city" />
<!-- 一对一映射关系 --> <association property="user" javaType="User"> <id column="id" property="id"/> <result column="user_name" property="name" /> <result column="age" property="age" />
<!-- 一对多关联映射关系管理 --> <collection property="mobiles" ofType="Mobile"> <id column="mid" property="mid" /> <result column="mname" property="mname" /> </collection>
</association> </resultMap> |
结果
6. Spring集成MyBatis
如图:这是我们整个请求流程中需要注意的配置
6.1. 整合思路
1、SqlSessionFactory对象应该放到spring容器中作为单例存在。
2、传统dao的开发方式中,应该从spring容器中获得sqlsession对象。
3、Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。
4、数据库的连接以及数据库连接池事务管理都交给spring容器来完成。
6.2. 整合
6.2.1. 创建项目
因为我们这里不涉及到web,所以可以直接创建一个普通java工程。工程如下:
6.2.2. 导入资源文件
log4j.properties日志文件包
Jdbc.properties数据库链接配置信息
6.2.3. 导入jar包
这些包可以全部导入到项目中去。
6.2.4. 创建spring.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- Service层扫描 --> <context:component-scan base-package="cn.andco.springmybatis.service.impl" />
<!-- 解析jdbc配置文件 --> <context:property-placeholder location="classpath:*.properties" />
<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) 事务传播特性配置 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <!-- the transactional semantics... --> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" /> <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" /> <tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" /> <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" /> <tx:method name="modify*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" /> <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" />
<!-- 查询方法 --> <tx:method name="query*" read-only="true" /> <tx:method name="select*" read-only="true" /> <tx:method name="find*" read-only="true" /> </tx:attributes> </tx:advice>
<!-- 配置事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
<!-- 配置数据源 --> <!-- don't forget the DataSource --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${dataSource.driverClass}"/> <property name="url" value="${dataSource.jdbcUrl}"/> <property name="username" value="${dataSource.username}"/> <property name="password" value="${dataSource.password}"/> </bean>
<!-- 声明式事务AOP配置 --> <aop:config> <aop:pointcut expression="execution(* cn.andco.springmybatis.service.impl.*.*(..))" id="tranpointcut" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="tranpointcut" /> </aop:config>
<!-- SqlSessionFactoryBean --> <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:mybatis.xml" /> <property name="typeAliasesPackage" value="cn.andco.springmybatis.model" /> <property name="mapperLocations"> <list> <value>classpath:cn/andco/springmybatis/mapper/*Mapper.xml</value> </list> </property> <property name="dataSource" ref="dataSource" /> </bean>
<!-- 配置接口扫描包 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="cn.andco.springmybatis.mapper" p:sqlSessionFactoryBeanName="sqlSessionFactoryBean" />
</beans>
|
6.2.5. 实例测试
6.2.5.1. 创建UserService
public interface UserService {
/** * @param user * @return */ int save(User user);
}
|
6.2.5.2. 创建UserServiceImpl
@Service public class UserServiceImpl implements UserService{
@Autowired private UserMapper userMapper;
@Override public int save(User user){ return userMapper.save(user); }
} |
6.2.5.3. 创建User
public class User implements Serializable {
/** * */ private static final long serialVersionUID = -4804399457395979656L;
private String id;
private String name;
private Integer age; //get set …. } |
6.2.5.4. 创建UserMapper
public interface UserMapper {
/** * @param user * @return */ int save(User user);
} |
6.2.5.5. 创建UserMapper.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.andco.springmybatis.mapper.UserMapper"> <!-- save --> <insert id="save" parameterType="User"> INSERT INTO user(id,user_name,age) VALUES(#{id},#{name},#{age}) </insert>
</mapper> |
6.2.5.6. 测试类
public class SpringMyBatisTest {
private ApplicationContext act;
@Before public void init(){ act = new ClassPathXmlApplicationContext("classpath:spring.xml"); }
/*** * 增加数据测试 */ @Test public void add(){ UserService userService = act.getBean(UserService.class); User user = new User("1998", "98!!", 98); userService.save(user); }
/*** * Spring容器测试 */ @Test public void testSpringContext(){ String[] names = act.getBeanDefinitionNames();
for (String string : names) { System.out.println(string); } }
} |
6.2.5.7. 事务测试
修改UserServiceImpl
@Override public int save(User user){ int count = userMapper.save(user);
//让数据线增加到数据库去,再在这里人为制造一个算术异常,看是否能否回滚 int q = 0; int s = 10/q;
return count; } |
执行增加操作
/*** * 增加数据测试 */ @Test public void add(){ UserService userService = act.getBean(UserService.class); User user = new User("19981", "98A!!", 98); userService.save(user); } |
异常信息
数据库也没有对应信息